From c32c81f3dbdfd68f6ab20a29ad86f811aed36e4e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 11:35:05 +0200 Subject: ARM/mfd/gpio: Fixup TPS65010 regression on OMAP1 OSK1 Aaro reports problems on the OSK1 board after we altered the dynamic base for GPIO allocations. It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air. Let's bite the bullet and try to just move the gpio_chip in the tps65010 MFD driver over to using dynamic allocations. Alter everything in the OSK1 board file to use a GPIO descriptor table and lookups. Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work. The .setup() callback for tps65010 was used for some GPIO hogging, but since the OSK1 is the only user in the entire kernel we can alter the signatures to something that is helpful and make a clean transition. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Cc: Christophe Leroy Cc: andy.shevchenko@gmail.com Cc: Andreas Kemnade Acked-by: Lee Jones Reviewed-by: Lee Jones Reported-by: Aaro Koskinen Reviewed-by: Andy Shevchenko Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-osk.c | 139 +++++++++++++++++++++++++++------------- 1 file changed, 95 insertions(+), 44 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index df758c1f9237..a8ca8d427182 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -25,7 +25,8 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include +#include #include #include #include @@ -64,13 +65,12 @@ /* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with * alternate pin configurations for hardware-controlled blinking. */ -#define OSK_TPS_GPIO_BASE (OMAP_MAX_GPIO_LINES + 16 /* MPUIO */) -# define OSK_TPS_GPIO_USB_PWR_EN (OSK_TPS_GPIO_BASE + 0) -# define OSK_TPS_GPIO_LED_D3 (OSK_TPS_GPIO_BASE + 1) -# define OSK_TPS_GPIO_LAN_RESET (OSK_TPS_GPIO_BASE + 2) -# define OSK_TPS_GPIO_DSP_PWR_EN (OSK_TPS_GPIO_BASE + 3) -# define OSK_TPS_GPIO_LED_D9 (OSK_TPS_GPIO_BASE + 4) -# define OSK_TPS_GPIO_LED_D2 (OSK_TPS_GPIO_BASE + 5) +#define OSK_TPS_GPIO_USB_PWR_EN 0 +#define OSK_TPS_GPIO_LED_D3 1 +#define OSK_TPS_GPIO_LAN_RESET 2 +#define OSK_TPS_GPIO_DSP_PWR_EN 3 +#define OSK_TPS_GPIO_LED_D9 4 +#define OSK_TPS_GPIO_LED_D2 5 static struct mtd_partition osk_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ @@ -174,11 +174,20 @@ static const struct gpio_led tps_leds[] = { /* NOTE: D9 and D2 have hardware blink support. * Also, D9 requires non-battery power. */ - { .gpio = OSK_TPS_GPIO_LED_D9, .name = "d9", - .default_trigger = "disk-activity", }, - { .gpio = OSK_TPS_GPIO_LED_D2, .name = "d2", }, - { .gpio = OSK_TPS_GPIO_LED_D3, .name = "d3", .active_low = 1, - .default_trigger = "heartbeat", }, + { .name = "d9", .default_trigger = "disk-activity", }, + { .name = "d2", }, + { .name = "d3", .default_trigger = "heartbeat", }, +}; + +static struct gpiod_lookup_table tps_leds_gpio_table = { + .dev_id = "leds-gpio", + .table = { + /* Use local offsets on TPS65010 */ + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D9, NULL, 0, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D2, NULL, 1, GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D3, NULL, 2, GPIO_ACTIVE_LOW), + { } + }, }; static struct gpio_led_platform_data tps_leds_data = { @@ -192,29 +201,34 @@ static struct platform_device osk5912_tps_leds = { .dev.platform_data = &tps_leds_data, }; -static int osk_tps_setup(struct i2c_client *client, void *context) +/* The board just hold these GPIOs hogged from setup to teardown */ +static struct gpio_desc *eth_reset; +static struct gpio_desc *vdd_dsp; + +static int osk_tps_setup(struct i2c_client *client, struct gpio_chip *gc) { + struct gpio_desc *d; if (!IS_BUILTIN(CONFIG_TPS65010)) return -ENOSYS; /* Set GPIO 1 HIGH to disable VBUS power supply; * OHCI driver powers it up/down as needed. */ - gpio_request(OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en"); - gpio_direction_output(OSK_TPS_GPIO_USB_PWR_EN, 1); + d = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en", + GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); /* Free the GPIO again as the driver will request it */ - gpio_free(OSK_TPS_GPIO_USB_PWR_EN); + gpiochip_free_own_desc(d); /* Set GPIO 2 high so LED D3 is off by default */ tps65010_set_gpio_out_value(GPIO2, HIGH); /* Set GPIO 3 low to take ethernet out of reset */ - gpio_request(OSK_TPS_GPIO_LAN_RESET, "smc_reset"); - gpio_direction_output(OSK_TPS_GPIO_LAN_RESET, 0); + eth_reset = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_LAN_RESET, "smc_reset", + GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW); /* GPIO4 is VDD_DSP */ - gpio_request(OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power"); - gpio_direction_output(OSK_TPS_GPIO_DSP_PWR_EN, 1); + vdd_dsp = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power", + GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); /* REVISIT if DSP support isn't configured, power it off ... */ /* Let LED1 (D9) blink; leds-gpio may override it */ @@ -232,15 +246,22 @@ static int osk_tps_setup(struct i2c_client *client, void *context) /* register these three LEDs */ osk5912_tps_leds.dev.parent = &client->dev; + gpiod_add_lookup_table(&tps_leds_gpio_table); platform_device_register(&osk5912_tps_leds); return 0; } +static void osk_tps_teardown(struct i2c_client *client, struct gpio_chip *gc) +{ + gpiochip_free_own_desc(eth_reset); + gpiochip_free_own_desc(vdd_dsp); +} + static struct tps65010_board tps_board = { - .base = OSK_TPS_GPIO_BASE, .outmask = 0x0f, .setup = osk_tps_setup, + .teardown = osk_tps_teardown, }; static struct i2c_board_info __initdata osk_i2c_board_info[] = { @@ -263,11 +284,6 @@ static void __init osk_init_smc91x(void) { u32 l; - if ((gpio_request(0, "smc_irq")) < 0) { - printk("Error requesting gpio 0 for smc91x irq\n"); - return; - } - /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ l = omap_readl(EMIFS_CCS(1)); l |= 0x3; @@ -279,10 +295,6 @@ static void __init osk_init_cf(int seg) struct resource *res = &osk5912_cf_resources[1]; omap_cfg_reg(M7_1610_GPIO62); - if ((gpio_request(62, "cf_irq")) < 0) { - printk("Error requesting gpio 62 for CF irq\n"); - return; - } switch (seg) { /* NOTE: CS0 could be configured too ... */ @@ -308,18 +320,17 @@ static void __init osk_init_cf(int seg) seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg))); omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */ omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */ - - /* the CF I/O IRQ is really active-low */ - irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING); } static struct gpiod_lookup_table osk_usb_gpio_table = { .dev_id = "ohci", .table = { /* Power GPIO on the I2C-attached TPS65010 */ - GPIO_LOOKUP("tps65010", 0, "power", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("tps65010", OSK_TPS_GPIO_USB_PWR_EN, "power", + GPIO_ACTIVE_HIGH), GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent", GPIO_ACTIVE_HIGH), + { } }, }; @@ -341,8 +352,25 @@ static struct omap_usb_config osk_usb_config __initdata = { #define EMIFS_CS3_VAL (0x88013141) +static struct gpiod_lookup_table osk_irq_gpio_table = { + .dev_id = NULL, + .table = { + /* GPIO used for SMC91x IRQ */ + GPIO_LOOKUP(OMAP_GPIO_LABEL, 0, "smc_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for CF IRQ */ + GPIO_LOOKUP("gpio-48-63", 14, "cf_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used by the TPS65010 chip */ + GPIO_LOOKUP("mpuio", 1, "tps65010", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init osk_init(void) { + struct gpio_desc *d; u32 l; osk_init_smc91x(); @@ -359,10 +387,31 @@ static void __init osk_init(void) osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); osk_flash_resource.end += SZ_32M - 1; - osk5912_smc91x_resources[1].start = gpio_to_irq(0); - osk5912_smc91x_resources[1].end = gpio_to_irq(0); - osk5912_cf_resources[0].start = gpio_to_irq(62); - osk5912_cf_resources[0].end = gpio_to_irq(62); + + /* + * Add the GPIOs to be used as IRQs and immediately look them up + * to be passed as an IRQ resource. This is ugly but should work + * until the day we convert to device tree. + */ + gpiod_add_lookup_table(&osk_irq_gpio_table); + + d = gpiod_get(NULL, "smc_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get SMC IRQ GPIO descriptor\n"); + } else { + irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_RISING); + osk5912_smc91x_resources[1] = DEFINE_RES_IRQ(gpiod_to_irq(d)); + } + + d = gpiod_get(NULL, "cf_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get CF IRQ GPIO descriptor\n"); + } else { + /* the CF I/O IRQ is really active-low */ + irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_FALLING); + osk5912_cf_resources[0] = DEFINE_RES_IRQ(gpiod_to_irq(d)); + } + platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); l = omap_readl(USB_TRANSCEIVER_CTRL); @@ -372,13 +421,15 @@ static void __init osk_init(void) gpiod_add_lookup_table(&osk_usb_gpio_table); omap1_usb_init(&osk_usb_config); + omap_serial_init(); + /* irq for tps65010 chip */ /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ - if (gpio_request(OMAP_MPUIO(1), "tps65010") == 0) - gpio_direction_input(OMAP_MPUIO(1)); - - omap_serial_init(); - osk_i2c_board_info[0].irq = gpio_to_irq(OMAP_MPUIO(1)); + d = gpiod_get(NULL, "tps65010", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get TPS65010 IRQ GPIO descriptor\n"); + else + osk_i2c_board_info[0].irq = gpiod_to_irq(d); omap_register_i2c_bus(1, 400, osk_i2c_board_info, ARRAY_SIZE(osk_i2c_board_info)); } -- cgit From fa1ae0cd897b089b5cc05ab471518ad13db2d567 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 11:40:28 +0200 Subject: ARM: omap1: Drop header on AMS Delta The AMS Delta board uses GPIO descriptors exclusively and does not have any dependencies on the legacy header, so just drop it. Acked-by: Janusz Krzysztofik Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-ams-delta.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 9108c871d129..ac47ab9fe096 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include -- cgit From 4c40db6249ff1da335b276bdd6c3c3462efbc2ab Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 11:56:23 +0200 Subject: ARM: omap1: Remove reliance on GPIO numbers from PalmTE It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air. Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-palmte.c | 51 +++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 20 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index f79c497f04d5..49b7757cb2fd 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -13,7 +13,8 @@ * * Copyright (c) 2006 Andrzej Zaborowski */ -#include +#include +#include #include #include #include @@ -187,23 +188,6 @@ static struct spi_board_info palmte_spi_info[] __initdata = { }, }; -static void __init palmte_misc_gpio_setup(void) -{ - /* Set TSC2102 PINTDAV pin as input (used by TSC2102 driver) */ - if (gpio_request(PALMTE_PINTDAV_GPIO, "TSC2102 PINTDAV") < 0) { - printk(KERN_ERR "Could not reserve PINTDAV GPIO!\n"); - return; - } - gpio_direction_input(PALMTE_PINTDAV_GPIO); - - /* Set USB-or-DC-IN pin as input (unused) */ - if (gpio_request(PALMTE_USB_OR_DC_GPIO, "USB/DC-IN") < 0) { - printk(KERN_ERR "Could not reserve cable signal GPIO!\n"); - return; - } - gpio_direction_input(PALMTE_USB_OR_DC_GPIO); -} - #if IS_ENABLED(CONFIG_MMC_OMAP) static struct omap_mmc_platform_data _palmte_mmc_config = { @@ -231,8 +215,23 @@ static void palmte_mmc_init(void) #endif /* CONFIG_MMC_OMAP */ +static struct gpiod_lookup_table palmte_irq_gpio_table = { + .dev_id = NULL, + .table = { + /* GPIO used for TSC2102 PINTDAV IRQ */ + GPIO_LOOKUP("gpio-0-15", PALMTE_PINTDAV_GPIO, "tsc2102_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for USB or DC input detection */ + GPIO_LOOKUP("gpio-0-15", PALMTE_USB_OR_DC_GPIO, "usb_dc_irq", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init omap_palmte_init(void) { + struct gpio_desc *d; + /* mux pins for uarts */ omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); @@ -243,9 +242,21 @@ static void __init omap_palmte_init(void) platform_add_devices(palmte_devices, ARRAY_SIZE(palmte_devices)); - palmte_spi_info[0].irq = gpio_to_irq(PALMTE_PINTDAV_GPIO); + gpiod_add_lookup_table(&palmte_irq_gpio_table); + d = gpiod_get(NULL, "tsc2102_irq", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get TSC2102 IRQ GPIO descriptor\n"); + else + palmte_spi_info[0].irq = gpiod_to_irq(d); spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info)); - palmte_misc_gpio_setup(); + + /* We are getting this just to set it up as input */ + d = gpiod_get(NULL, "usb_dc_irq", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get USB/DC IRQ GPIO descriptor\n"); + else + gpiod_put(d); + omap_serial_init(); omap1_usb_init(&palmte_usb_config); omap_register_i2c_bus(1, 100, NULL, 0); -- cgit From 480c82daa3e41873421dc2c9e2918ad7e21d7a0b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 17:45:29 +0200 Subject: ARM: omap1: Remove reliance on GPIO numbers from SX1 It appears this happens because the OMAP driver now allocates GPIO numbers dynamically, so all that is references by number is a bit up in the air. Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-sx1.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c index 0c0cdd5e77c7..a13c630be7b7 100644 --- a/arch/arm/mach-omap1/board-sx1.c +++ b/arch/arm/mach-omap1/board-sx1.c @@ -11,7 +11,8 @@ * Maintainters : Vladimir Ananiev (aka Vovan888), Sergge * oslik.ru */ -#include +#include +#include #include #include #include @@ -304,8 +305,23 @@ static struct platform_device *sx1_devices[] __initdata = { /*-----------------------------------------*/ +static struct gpiod_lookup_table sx1_gpio_table = { + .dev_id = NULL, + .table = { + GPIO_LOOKUP("gpio-0-15", 1, "irda_off", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-15", 11, "switch", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-15", 15, "usb_on", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init omap_sx1_init(void) { + struct gpio_desc *d; + /* mux pins for uarts */ omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); @@ -320,15 +336,25 @@ static void __init omap_sx1_init(void) omap_register_i2c_bus(1, 100, NULL, 0); omap1_usb_init(&sx1_usb_config); sx1_mmc_init(); + gpiod_add_lookup_table(&sx1_gpio_table); /* turn on USB power */ /* sx1_setusbpower(1); can't do it here because i2c is not ready */ - gpio_request(1, "A_IRDA_OFF"); - gpio_request(11, "A_SWITCH"); - gpio_request(15, "A_USB_ON"); - gpio_direction_output(1, 1); /*A_IRDA_OFF = 1 */ - gpio_direction_output(11, 0); /*A_SWITCH = 0 */ - gpio_direction_output(15, 0); /*A_USB_ON = 0 */ + d = gpiod_get(NULL, "irda_off", GPIOD_OUT_HIGH); + if (IS_ERR(d)) + pr_err("Unable to get IRDA OFF GPIO descriptor\n"); + else + gpiod_put(d); + d = gpiod_get(NULL, "switch", GPIOD_OUT_LOW); + if (IS_ERR(d)) + pr_err("Unable to get SWITCH GPIO descriptor\n"); + else + gpiod_put(d); + d = gpiod_get(NULL, "usb_on", GPIOD_OUT_LOW); + if (IS_ERR(d)) + pr_err("Unable to get USB ON GPIO descriptor\n"); + else + gpiod_put(d); omapfb_set_lcd_config(&sx1_lcd_config); } -- cgit From 767d83361aaa6a1ecb4d5b89eeb38a267239917a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 8 May 2023 23:20:06 +0200 Subject: Input: ads7846 - Convert to use software nodes The Nokia 770 is using GPIOs from the global numberspace on the CBUS node to pass down to the LCD controller. This regresses when we let the OMAP GPIO driver use dynamic GPIO base. The Nokia 770 now has dynamic allocation of IRQ numbers, so this needs to be fixed for it to work. As this is the only user of LCD MIPID we can easily augment the driver to use a GPIO descriptor instead and resolve the issue. The platform data .shutdown() callback wasn't even used in the code, but we encode a shutdown asserting RESET in the remove() callback for completeness sake. The CBUS also has the ADS7846 touchscreen attached. Populate the devices on the Nokia 770 CBUS I2C using software nodes instead of platform data quirks. This includes the LCD and the ADS7846 touchscreen so the conversion just brings the LCD along with it as software nodes is an all-or-nothing design pattern. The ADS7846 has some limited support for using GPIO descriptors, let's convert it over completely to using device properties and then fix all remaining boardfile users to provide all platform data using software nodes. Dump the of includes and of_match_ptr() in the ADS7846 driver as part of the job. Since we have to move ADS7846 over to obtaining the GPIOs it is using exclusively from descriptors, we provide descriptor tables for the two remaining in-kernel boardfiles using ADS7846: - PXA Spitz - MIPS Alchemy DB1000 development board It was too hard for me to include software node conversion of these two remaining users at this time: the spitz is using a hscync callback in the platform data that would require further GPIO descriptor conversion of the Spitz, and moving the hsync callback down into the driver: it will just become too big of a job, but it can be done separately. The MIPS Alchemy DB1000 is simply something I cannot test, so take the easier approach of just providing some GPIO descriptors in this case as I don't want the patch to grow too intrusive. As we see that several device trees have incorrect polarity flags and just expect to bypass the gpiolib polarity handling, fix up all device trees too, in a separate patch. Suggested-by: Dmitry Torokhov Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Acked-by: Dmitry Torokhov Reviewed-by: Dmitry Torokhov Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-nokia770.c | 99 +++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 34 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index a501a473ffd6..dde74694cb4c 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -8,15 +8,16 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include -#include #include #include @@ -35,6 +36,25 @@ #include "clock.h" #include "mmc.h" +static const struct software_node nokia770_mpuio_gpiochip_node = { + .name = "mpuio", +}; + +static const struct software_node nokia770_gpiochip1_node = { + .name = "gpio-0-15", +}; + +static const struct software_node nokia770_gpiochip2_node = { + .name = "gpio-16-31", +}; + +static const struct software_node *nokia770_gpiochip_nodes[] = { + &nokia770_mpuio_gpiochip_node, + &nokia770_gpiochip1_node, + &nokia770_gpiochip2_node, + NULL +}; + #define ADS7846_PENDOWN_GPIO 15 static const unsigned int nokia770_keymap[] = { @@ -85,40 +105,47 @@ static struct platform_device *nokia770_devices[] __initdata = { &nokia770_kp_device, }; -static void mipid_shutdown(struct mipid_platform_data *pdata) -{ - if (pdata->nreset_gpio != -1) { - printk(KERN_INFO "shutdown LCD\n"); - gpio_set_value(pdata->nreset_gpio, 0); - msleep(120); - } -} - -static struct mipid_platform_data nokia770_mipid_platform_data = { - .shutdown = mipid_shutdown, -}; +static struct mipid_platform_data nokia770_mipid_platform_data = { }; static const struct omap_lcd_config nokia770_lcd_config __initconst = { .ctrl_name = "hwa742", }; +static const struct property_entry nokia770_mipid_props[] = { + PROPERTY_ENTRY_GPIO("reset-gpios", &nokia770_gpiochip1_node, + 13, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node nokia770_mipid_swnode = { + .name = "lcd_mipid", + .properties = nokia770_mipid_props, +}; + static void __init mipid_dev_init(void) { - nokia770_mipid_platform_data.nreset_gpio = 13; nokia770_mipid_platform_data.data_lines = 16; omapfb_set_lcd_config(&nokia770_lcd_config); } -static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = { - .x_max = 0x0fff, - .y_max = 0x0fff, - .x_plate_ohms = 180, - .pressure_max = 255, - .debounce_max = 10, - .debounce_tol = 3, - .debounce_rep = 1, - .gpio_pendown = ADS7846_PENDOWN_GPIO, +static const struct property_entry nokia770_ads7846_props[] = { + PROPERTY_ENTRY_STRING("compatible", "ti,ads7846"), + PROPERTY_ENTRY_U32("touchscreen-size-x", 4096), + PROPERTY_ENTRY_U32("touchscreen-size-y", 4096), + PROPERTY_ENTRY_U32("touchscreen-max-pressure", 256), + PROPERTY_ENTRY_U32("touchscreen-average-samples", 10), + PROPERTY_ENTRY_U16("ti,x-plate-ohms", 180), + PROPERTY_ENTRY_U16("ti,debounce-tol", 3), + PROPERTY_ENTRY_U16("ti,debounce-rep", 1), + PROPERTY_ENTRY_GPIO("pendown-gpios", &nokia770_gpiochip1_node, + ADS7846_PENDOWN_GPIO, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node nokia770_ads7846_swnode = { + .name = "ads7846", + .properties = nokia770_ads7846_props, }; static struct spi_board_info nokia770_spi_board_info[] __initdata = { @@ -128,13 +155,14 @@ static struct spi_board_info nokia770_spi_board_info[] __initdata = { .chip_select = 3, .max_speed_hz = 12000000, .platform_data = &nokia770_mipid_platform_data, + .swnode = &nokia770_mipid_swnode, }, [1] = { .modalias = "ads7846", .bus_num = 2, .chip_select = 0, .max_speed_hz = 2500000, - .platform_data = &nokia770_ads7846_platform_data, + .swnode = &nokia770_ads7846_swnode, }, }; @@ -212,14 +240,16 @@ static inline void nokia770_mmc_init(void) #endif #if IS_ENABLED(CONFIG_I2C_CBUS_GPIO) -static struct gpiod_lookup_table nokia770_cbus_gpio_table = { - .dev_id = "i2c-cbus-gpio.2", - .table = { - GPIO_LOOKUP_IDX("mpuio", 9, NULL, 0, 0), /* clk */ - GPIO_LOOKUP_IDX("mpuio", 10, NULL, 1, 0), /* dat */ - GPIO_LOOKUP_IDX("mpuio", 11, NULL, 2, 0), /* sel */ - { }, - }, + +static const struct software_node_ref_args nokia770_cbus_gpio_refs[] = { + SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 9, 0), + SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 10, 0), + SOFTWARE_NODE_REFERENCE(&nokia770_mpuio_gpiochip_node, 11, 0), +}; + +static const struct property_entry nokia770_cbus_props[] = { + PROPERTY_ENTRY_REF_ARRAY("gpios", nokia770_cbus_gpio_refs), + { } }; static struct platform_device nokia770_cbus_device = { @@ -253,7 +283,8 @@ static void __init nokia770_cbus_init(void) nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio); i2c_register_board_info(2, nokia770_i2c_board_info_2, ARRAY_SIZE(nokia770_i2c_board_info_2)); - gpiod_add_lookup_table(&nokia770_cbus_gpio_table); + device_create_managed_software_node(&nokia770_cbus_device.dev, + nokia770_cbus_props, NULL); platform_device_register(&nokia770_cbus_device); } #else /* CONFIG_I2C_CBUS_GPIO */ @@ -273,8 +304,8 @@ static void __init omap_nokia770_init(void) /* Unmask SleepX signal */ omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); + software_node_register_node_group(nokia770_gpiochip_nodes); platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); - nokia770_spi_board_info[1].irq = gpio_to_irq(15); spi_register_board_info(nokia770_spi_board_info, ARRAY_SIZE(nokia770_spi_board_info)); omap_serial_init(); -- cgit From e519f0bb64efc2c9c8b67bb2d114dda458bdc34d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 8 May 2023 23:20:07 +0200 Subject: ARM/mmc: Convert old mmci-omap to GPIO descriptors A recent change to the OMAP driver making it use a dynamic GPIO base created problems with some old OMAP1 board files, among them Nokia 770, SX1 and also the OMAP2 Nokia n8x0. Fix up all instances of GPIOs being used for the MMC driver by pushing the handling of power, slot selection and MMC "cover" into the driver as optional GPIOs. This is maybe not the most perfect solution as the MMC framework have some central handlers for some of the stuff, but it at least makes the situtation better and solves the immediate issue. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Acked-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-nokia770.c | 43 +++++++++++------------------------- arch/arm/mach-omap1/board-sx1-mmc.c | 1 - 2 files changed, 13 insertions(+), 31 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index dde74694cb4c..9583417f5bea 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -184,27 +184,23 @@ static struct omap_usb_config nokia770_usb_config __initdata = { #if IS_ENABLED(CONFIG_MMC_OMAP) -#define NOKIA770_GPIO_MMC_POWER 41 -#define NOKIA770_GPIO_MMC_SWITCH 23 - -static int nokia770_mmc_set_power(struct device *dev, int slot, int power_on, - int vdd) -{ - gpio_set_value(NOKIA770_GPIO_MMC_POWER, power_on); - return 0; -} - -static int nokia770_mmc_get_cover_state(struct device *dev, int slot) -{ - return gpio_get_value(NOKIA770_GPIO_MMC_SWITCH); -} +static struct gpiod_lookup_table nokia770_mmc_gpio_table = { + .dev_id = "mmci-omap.1", + .table = { + /* Slot index 0, VSD power, GPIO 41 */ + GPIO_LOOKUP_IDX("gpio-32-47", 9, + "vsd", 0, GPIO_ACTIVE_HIGH), + /* Slot index 0, switch, GPIO 23 */ + GPIO_LOOKUP_IDX("gpio-16-31", 7, + "cover", 0, GPIO_ACTIVE_HIGH), + { } + }, +}; static struct omap_mmc_platform_data nokia770_mmc2_data = { .nr_slots = 1, .max_freq = 12000000, .slots[0] = { - .set_power = nokia770_mmc_set_power, - .get_cover_state = nokia770_mmc_get_cover_state, .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, .name = "mmcblk", }, @@ -214,20 +210,7 @@ static struct omap_mmc_platform_data *nokia770_mmc_data[OMAP16XX_NR_MMC]; static void __init nokia770_mmc_init(void) { - int ret; - - ret = gpio_request(NOKIA770_GPIO_MMC_POWER, "MMC power"); - if (ret < 0) - return; - gpio_direction_output(NOKIA770_GPIO_MMC_POWER, 0); - - ret = gpio_request(NOKIA770_GPIO_MMC_SWITCH, "MMC cover"); - if (ret < 0) { - gpio_free(NOKIA770_GPIO_MMC_POWER); - return; - } - gpio_direction_input(NOKIA770_GPIO_MMC_SWITCH); - + gpiod_add_lookup_table(&nokia770_mmc_gpio_table); /* Only the second MMC controller is used */ nokia770_mmc_data[1] = &nokia770_mmc2_data; omap1_init_mmc(nokia770_mmc_data, OMAP16XX_NR_MMC); diff --git a/arch/arm/mach-omap1/board-sx1-mmc.c b/arch/arm/mach-omap1/board-sx1-mmc.c index f1c160924dfe..f183a8448a7b 100644 --- a/arch/arm/mach-omap1/board-sx1-mmc.c +++ b/arch/arm/mach-omap1/board-sx1-mmc.c @@ -9,7 +9,6 @@ * Copyright (C) 2007 Instituto Nokia de Tecnologia - INdT */ -#include #include #include "hardware.h" -- cgit From 084b6f216778b4109123b396b531f12ff6c354e9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 11:12:54 +0200 Subject: ARM: omap1: Fix up the Nokia 770 board device IRQs The platform devices on the Nokia 770 is using some board-specific IRQs that get statically assigned to platform devices in the boardfile. This does not work with dynamic IRQ chip bases. Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, convert to IRQ numbers and pass as resources to the devices. This is ugly but should work. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-nokia770.c | 58 ++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index 9583417f5bea..dd1a8f439fac 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -6,7 +6,7 @@ */ #include #include -#include +#include #include #include #include @@ -251,19 +251,25 @@ static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = { static void __init nokia770_cbus_init(void) { - const int retu_irq_gpio = 62; - const int tahvo_irq_gpio = 40; - - if (gpio_request_one(retu_irq_gpio, GPIOF_IN, "Retu IRQ")) - return; - if (gpio_request_one(tahvo_irq_gpio, GPIOF_IN, "Tahvo IRQ")) { - gpio_free(retu_irq_gpio); - return; + struct gpio_desc *d; + int irq; + + d = gpiod_get(NULL, "retu_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get CBUS Retu IRQ GPIO descriptor\n"); + } else { + irq = gpiod_to_irq(d); + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + nokia770_i2c_board_info_2[0].irq = irq; + } + d = gpiod_get(NULL, "tahvo_irq", GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get CBUS Tahvo IRQ GPIO descriptor\n"); + } else { + irq = gpiod_to_irq(d); + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + nokia770_i2c_board_info_2[1].irq = irq; } - irq_set_irq_type(gpio_to_irq(retu_irq_gpio), IRQ_TYPE_EDGE_RISING); - irq_set_irq_type(gpio_to_irq(tahvo_irq_gpio), IRQ_TYPE_EDGE_RISING); - nokia770_i2c_board_info_2[0].irq = gpio_to_irq(retu_irq_gpio); - nokia770_i2c_board_info_2[1].irq = gpio_to_irq(tahvo_irq_gpio); i2c_register_board_info(2, nokia770_i2c_board_info_2, ARRAY_SIZE(nokia770_i2c_board_info_2)); device_create_managed_software_node(&nokia770_cbus_device.dev, @@ -276,8 +282,26 @@ static void __init nokia770_cbus_init(void) } #endif /* CONFIG_I2C_CBUS_GPIO */ +static struct gpiod_lookup_table nokia770_irq_gpio_table = { + .dev_id = NULL, + .table = { + /* GPIO used by SPI device 1 */ + GPIO_LOOKUP("gpio-0-15", 15, "ads7846_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for retu IRQ */ + GPIO_LOOKUP("gpio-48-63", 15, "retu_irq", + GPIO_ACTIVE_HIGH), + /* GPIO used for tahvo IRQ */ + GPIO_LOOKUP("gpio-32-47", 8, "tahvo_irq", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init omap_nokia770_init(void) { + struct gpio_desc *d; + /* On Nokia 770, the SleepX signal is masked with an * MPUIO line by default. It has to be unmasked for it * to become functional */ @@ -289,6 +313,14 @@ static void __init omap_nokia770_init(void) software_node_register_node_group(nokia770_gpiochip_nodes); platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices)); + + gpiod_add_lookup_table(&nokia770_irq_gpio_table); + d = gpiod_get(NULL, "ads7846_irq", GPIOD_IN); + if (IS_ERR(d)) + pr_err("Unable to get ADS7846 IRQ GPIO descriptor\n"); + else + nokia770_spi_board_info[1].irq = gpiod_to_irq(d); + spi_register_board_info(nokia770_spi_board_info, ARRAY_SIZE(nokia770_spi_board_info)); omap_serial_init(); -- cgit From df89de979f0e09e1896d59312362ce1657b848eb Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 19:51:30 +0200 Subject: ARM: omap1: Make serial wakeup GPIOs use descriptors The code in serial.c looks up GPIOs corresponding to a line on the UART when muxed in as GPIO to use this as a wakeup on serial activity for OMAP1. Utilize the NULL device to define some board-specific GPIO lookups and use these to immediately look up the same GPIOs, set as input and convert to IRQ numbers, then set these to wakeup IRQs. This is ugly but should work. This is only needed on the OSK1 and Nokia 770 devices that use the OMAP16xx. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/board-nokia770.c | 7 +++++++ arch/arm/mach-omap1/board-osk.c | 7 +++++++ arch/arm/mach-omap1/serial.c | 30 +++++++++++++++--------------- 3 files changed, 29 insertions(+), 15 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index dd1a8f439fac..5ea27ca26abf 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -294,6 +294,13 @@ static struct gpiod_lookup_table nokia770_irq_gpio_table = { /* GPIO used for tahvo IRQ */ GPIO_LOOKUP("gpio-32-47", 8, "tahvo_irq", GPIO_ACTIVE_HIGH), + /* GPIOs used by serial wakeup IRQs */ + GPIO_LOOKUP_IDX("gpio-32-47", 5, "wakeup", 0, + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-16-31", 2, "wakeup", 1, + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-48-63", 1, "wakeup", 2, + GPIO_ACTIVE_HIGH), { } }, }; diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index a8ca8d427182..463687b9ca52 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c @@ -364,6 +364,13 @@ static struct gpiod_lookup_table osk_irq_gpio_table = { /* GPIO used by the TPS65010 chip */ GPIO_LOOKUP("mpuio", 1, "tps65010", GPIO_ACTIVE_HIGH), + /* GPIOs used for serial wakeup IRQs */ + GPIO_LOOKUP_IDX("gpio-32-47", 5, "wakeup", 0, + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-16-31", 2, "wakeup", 1, + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP_IDX("gpio-48-63", 1, "wakeup", 2, + GPIO_ACTIVE_HIGH), { } }, }; diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index c7f590645774..3adceb97138f 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -4,7 +4,8 @@ * * OMAP1 serial support. */ -#include +#include +#include #include #include #include @@ -196,39 +197,38 @@ void omap_serial_wake_trigger(int enable) } } -static void __init omap_serial_set_port_wakeup(int gpio_nr) +static void __init omap_serial_set_port_wakeup(int idx) { + struct gpio_desc *d; int ret; - ret = gpio_request(gpio_nr, "UART wake"); - if (ret < 0) { - printk(KERN_ERR "Could not request UART wake GPIO: %i\n", - gpio_nr); + d = gpiod_get_index(NULL, "wakeup", idx, GPIOD_IN); + if (IS_ERR(d)) { + pr_err("Unable to get UART wakeup GPIO descriptor\n"); return; } - gpio_direction_input(gpio_nr); - ret = request_irq(gpio_to_irq(gpio_nr), &omap_serial_wake_interrupt, + ret = request_irq(gpiod_to_irq(d), &omap_serial_wake_interrupt, IRQF_TRIGGER_RISING, "serial wakeup", NULL); if (ret) { - gpio_free(gpio_nr); - printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n", - gpio_nr); + gpiod_put(d); + pr_err("No interrupt for UART%d wake GPIO\n", idx + 1); return; } - enable_irq_wake(gpio_to_irq(gpio_nr)); + enable_irq_wake(gpiod_to_irq(d)); } + int __init omap_serial_wakeup_init(void) { if (!cpu_is_omap16xx()) return 0; if (uart1_ck != NULL) - omap_serial_set_port_wakeup(37); + omap_serial_set_port_wakeup(0); if (uart2_ck != NULL) - omap_serial_set_port_wakeup(18); + omap_serial_set_port_wakeup(1); if (uart3_ck != NULL) - omap_serial_set_port_wakeup(49); + omap_serial_set_port_wakeup(2); return 0; } -- cgit From c729baa8604226a8f878296bd145ab4046c80b12 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 30 Apr 2023 19:56:37 +0200 Subject: ARM: omap1: Exorcise the legacy GPIO header After fixing all the offending users referencing the global GPIO numberspace in OMAP1, a few sites still remain including the legacy header for no reason. Delete the last remaining users, and OMAP1 is free from legacy GPIO dependencies. Fixes: 92bf78b33b0b ("gpio: omap: use dynamic allocation of base") Signed-off-by: Linus Walleij --- arch/arm/mach-omap1/devices.c | 1 - arch/arm/mach-omap1/gpio15xx.c | 1 - arch/arm/mach-omap1/gpio16xx.c | 1 - arch/arm/mach-omap1/irq.c | 1 - 4 files changed, 4 deletions(-) (limited to 'arch/arm/mach-omap1') diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 5304699c7a97..8b2c5f911e97 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 61fa26efd865..6724af4925f2 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -8,7 +8,6 @@ * Charulatha V */ -#include #include #include #include diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index cf052714b3f8..55acec22fef4 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c @@ -8,7 +8,6 @@ * Charulatha V */ -#include #include #include diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index bfc7ab010ae2..af06a8753fdc 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -35,7 +35,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include -- cgit