diff options
32 files changed, 636 insertions, 511 deletions
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 <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/gpio/consumer.h> -#include <linux/gpio.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index a501a473ffd6..5ea27ca26abf 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -6,17 +6,18 @@ */ #include <linux/clkdev.h> #include <linux/irq.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/gpio/machine.h> +#include <linux/gpio/property.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/mutex.h> #include <linux/platform_device.h> +#include <linux/property.h> #include <linux/input.h> #include <linux/omapfb.h> #include <linux/spi/spi.h> -#include <linux/spi/ads7846.h> #include <linux/workqueue.h> #include <linux/delay.h> @@ -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, }, }; @@ -156,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", }, @@ -186,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); @@ -212,14 +223,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 = { @@ -238,22 +251,29 @@ 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)); - 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 */ @@ -262,8 +282,33 @@ 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), + /* 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), + { } + }, +}; + 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 */ @@ -273,8 +318,16 @@ 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); + + 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(); diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index df758c1f9237..463687b9ca52 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 <linux/gpio.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/driver.h> #include <linux/gpio/machine.h> #include <linux/kernel.h> #include <linux/init.h> @@ -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,32 @@ 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), + /* 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), + { } + }, +}; + static void __init osk_init(void) { + struct gpio_desc *d; u32 l; osk_init_smc91x(); @@ -359,10 +394,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 +428,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)); } 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 <balrog@zabor.org> */ -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> @@ -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); 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 <linux/gpio.h> #include <linux/platform_device.h> #include "hardware.h" 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 <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/input.h> @@ -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); } 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 <linux/dma-mapping.h> -#include <linux/gpio.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> 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 <charu@ti.com> */ -#include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> #include <linux/soc/ti/omap1-soc.h> #include <asm/irq.h> 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 <charu@ti.com> */ -#include <linux/gpio.h> #include <linux/platform_data/gpio-omap.h> #include <linux/soc/ti/omap1-io.h> 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 <linux/gpio.h> #include <linux/init.h> #include <linux/module.h> #include <linux/sched.h> diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index 19ea9842acc1..ffa4a9bece1e 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -4,7 +4,8 @@ * * OMAP1 serial support. */ -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -197,39 +198,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; } diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 3353b0a923d9..564bf80a2621 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -10,7 +10,8 @@ #include <linux/clk.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/io.h> #include <linux/irq.h> @@ -28,13 +29,12 @@ #include "common.h" #include "mmc.h" +#include "usb-tusb6010.h" #include "soc.h" #include "common-board-devices.h" #define TUSB6010_ASYNC_CS 1 #define TUSB6010_SYNC_CS 4 -#define TUSB6010_GPIO_INT 58 -#define TUSB6010_GPIO_ENABLE 0 #define TUSB6010_DMACHAN 0x3f #define NOKIA_N810_WIMAX (1 << 2) @@ -61,37 +61,6 @@ static void board_check_revision(void) } #if IS_ENABLED(CONFIG_USB_MUSB_TUSB6010) -/* - * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and - * 1.5 V voltage regulators of PM companion chip. Companion chip will then - * provide then PGOOD signal to TUSB6010 which will release it from reset. - */ -static int tusb_set_power(int state) -{ - int i, retval = 0; - - if (state) { - gpio_set_value(TUSB6010_GPIO_ENABLE, 1); - msleep(1); - - /* Wait until TUSB6010 pulls INT pin down */ - i = 100; - while (i && gpio_get_value(TUSB6010_GPIO_INT)) { - msleep(1); - i--; - } - - if (!i) { - printk(KERN_ERR "tusb: powerup failed\n"); - retval = -ENODEV; - } - } else { - gpio_set_value(TUSB6010_GPIO_ENABLE, 0); - msleep(10); - } - - return retval; -} static struct musb_hdrc_config musb_config = { .multipoint = 1, @@ -102,39 +71,36 @@ static struct musb_hdrc_config musb_config = { static struct musb_hdrc_platform_data tusb_data = { .mode = MUSB_OTG, - .set_power = tusb_set_power, .min_power = 25, /* x2 = 50 mA drawn from VBUS as peripheral */ .power = 100, /* Max 100 mA VBUS for host mode */ .config = &musb_config, }; +static struct gpiod_lookup_table tusb_gpio_table = { + .dev_id = "musb-tusb", + .table = { + GPIO_LOOKUP("gpio-0-15", 0, "enable", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-48-63", 10, "int", + GPIO_ACTIVE_HIGH), + { } + }, +}; + static void __init n8x0_usb_init(void) { int ret = 0; - static const char announce[] __initconst = KERN_INFO "TUSB 6010\n"; - - /* PM companion chip power control pin */ - ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW, - "TUSB6010 enable"); - if (ret != 0) { - printk(KERN_ERR "Could not get TUSB power GPIO%i\n", - TUSB6010_GPIO_ENABLE); - return; - } - tusb_set_power(0); + gpiod_add_lookup_table(&tusb_gpio_table); ret = tusb6010_setup_interface(&tusb_data, TUSB6010_REFCLK_19, 2, - TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, - TUSB6010_GPIO_INT, TUSB6010_DMACHAN); + TUSB6010_ASYNC_CS, TUSB6010_SYNC_CS, + TUSB6010_DMACHAN); if (ret != 0) - goto err; + return; - printk(announce); + pr_info("TUSB 6010\n"); return; - -err: - gpio_free(TUSB6010_GPIO_ENABLE); } #else @@ -170,22 +136,32 @@ static struct spi_board_info n800_spi_board_info[] __initdata = { * GPIO23 and GPIO9 slot 2 EMMC on N810 * */ -#define N8X0_SLOT_SWITCH_GPIO 96 -#define N810_EMMC_VSD_GPIO 23 -#define N810_EMMC_VIO_GPIO 9 - static int slot1_cover_open; static int slot2_cover_open; static struct device *mmc_device; -static int n8x0_mmc_switch_slot(struct device *dev, int slot) -{ -#ifdef CONFIG_MMC_DEBUG - dev_dbg(dev, "Choose slot %d\n", slot + 1); -#endif - gpio_set_value(N8X0_SLOT_SWITCH_GPIO, slot); - return 0; -} +static struct gpiod_lookup_table nokia8xx_mmc_gpio_table = { + .dev_id = "mmci-omap.0", + .table = { + /* Slot switch, GPIO 96 */ + GPIO_LOOKUP("gpio-80-111", 16, + "switch", GPIO_ACTIVE_HIGH), + { } + }, +}; + +static struct gpiod_lookup_table nokia810_mmc_gpio_table = { + .dev_id = "mmci-omap.0", + .table = { + /* Slot index 1, VSD power, GPIO 23 */ + GPIO_LOOKUP_IDX("gpio-16-31", 7, + "vsd", 1, GPIO_ACTIVE_HIGH), + /* Slot index 1, VIO power, GPIO 9 */ + GPIO_LOOKUP_IDX("gpio-0-15", 9, + "vsd", 1, GPIO_ACTIVE_HIGH), + { } + }, +}; static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot, int power_on, int vdd) @@ -256,31 +232,13 @@ static int n8x0_mmc_set_power_menelaus(struct device *dev, int slot, return 0; } -static void n810_set_power_emmc(struct device *dev, - int power_on) -{ - dev_dbg(dev, "Set EMMC power %s\n", power_on ? "on" : "off"); - - if (power_on) { - gpio_set_value(N810_EMMC_VSD_GPIO, 1); - msleep(1); - gpio_set_value(N810_EMMC_VIO_GPIO, 1); - msleep(1); - } else { - gpio_set_value(N810_EMMC_VIO_GPIO, 0); - msleep(50); - gpio_set_value(N810_EMMC_VSD_GPIO, 0); - msleep(50); - } -} - static int n8x0_mmc_set_power(struct device *dev, int slot, int power_on, int vdd) { if (board_is_n800() || slot == 0) return n8x0_mmc_set_power_menelaus(dev, slot, power_on, vdd); - n810_set_power_emmc(dev, power_on); + /* The n810 power will be handled by GPIO code in the driver */ return 0; } @@ -418,13 +376,6 @@ static void n8x0_mmc_shutdown(struct device *dev) static void n8x0_mmc_cleanup(struct device *dev) { menelaus_unregister_mmc_callback(); - - gpio_free(N8X0_SLOT_SWITCH_GPIO); - - if (board_is_n810()) { - gpio_free(N810_EMMC_VSD_GPIO); - gpio_free(N810_EMMC_VIO_GPIO); - } } /* @@ -433,7 +384,6 @@ static void n8x0_mmc_cleanup(struct device *dev) */ static struct omap_mmc_platform_data mmc1_data = { .nr_slots = 0, - .switch_slot = n8x0_mmc_switch_slot, .init = n8x0_mmc_late_init, .cleanup = n8x0_mmc_cleanup, .shutdown = n8x0_mmc_shutdown, @@ -463,14 +413,9 @@ static struct omap_mmc_platform_data mmc1_data = { static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC]; -static struct gpio n810_emmc_gpios[] __initdata = { - { N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vddf" }, - { N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW, "MMC slot 2 Vdd" }, -}; - static void __init n8x0_mmc_init(void) { - int err; + gpiod_add_lookup_table(&nokia8xx_mmc_gpio_table); if (board_is_n810()) { mmc1_data.slots[0].name = "external"; @@ -483,20 +428,7 @@ static void __init n8x0_mmc_init(void) */ mmc1_data.slots[1].name = "internal"; mmc1_data.slots[1].ban_openended = 1; - } - - err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW, - "MMC slot switch"); - if (err) - return; - - if (board_is_n810()) { - err = gpio_request_array(n810_emmc_gpios, - ARRAY_SIZE(n810_emmc_gpios)); - if (err) { - gpio_free(N8X0_SLOT_SWITCH_GPIO); - return; - } + gpiod_add_lookup_table(&nokia810_mmc_gpio_table); } mmc1_data.nr_slots = 2; diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 4afa2f08e668..fca7869c8075 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -244,7 +244,6 @@ static int _omap_device_notifier_call(struct notifier_block *nb, case BUS_NOTIFY_ADD_DEVICE: if (pdev->dev.of_node) omap_device_build_from_dt(pdev); - omap_auxdata_legacy_init(dev); fallthrough; default: od = to_omap_device(pdev); diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 04208cc52784..c1c0121f478d 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -6,8 +6,8 @@ */ #include <linux/clk.h> #include <linux/davinci_emac.h> +#include <linux/gpio/machine.h> #include <linux/gpio/consumer.h> -#include <linux/gpio.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/of_platform.h> @@ -41,7 +41,6 @@ struct pdata_init { }; static struct of_dev_auxdata omap_auxdata_lookup[]; -static struct twl4030_gpio_platform_data twl_gpio_auxdata; #ifdef CONFIG_MACH_NOKIA_N8X0 static void __init omap2420_n8x0_legacy_init(void) @@ -98,52 +97,43 @@ static struct iommu_platform_data omap3_iommu_isp_pdata = { }; #endif -static int omap3_sbc_t3730_twl_callback(struct device *dev, - unsigned gpio, - unsigned ngpio) +static void __init omap3_sbc_t3x_usb_hub_init(char *hub_name, int idx) { - int res; + struct gpio_desc *d; - res = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH, - "wlan pwr"); - if (res) - return res; - - gpiod_export(gpio_to_desc(gpio), 0); - - return 0; -} - -static void __init omap3_sbc_t3x_usb_hub_init(int gpio, char *hub_name) -{ - int err = gpio_request_one(gpio, GPIOF_OUT_INIT_LOW, hub_name); - - if (err) { - pr_err("SBC-T3x: %s reset gpio request failed: %d\n", - hub_name, err); + /* This asserts the RESET line (reverse polarity) */ + d = gpiod_get_index(NULL, "reset", idx, GPIOD_OUT_HIGH); + if (IS_ERR(d)) { + pr_err("Unable to get T3x USB reset GPIO descriptor\n"); return; } - - gpiod_export(gpio_to_desc(gpio), 0); - + gpiod_set_consumer_name(d, hub_name); + gpiod_export(d, 0); udelay(10); - gpio_set_value(gpio, 1); + /* De-assert RESET */ + gpiod_set_value(d, 0); msleep(1); } -static void __init omap3_sbc_t3730_twl_init(void) -{ - twl_gpio_auxdata.setup = omap3_sbc_t3730_twl_callback; -} +static struct gpiod_lookup_table omap3_sbc_t3x_usb_gpio_table = { + .dev_id = NULL, + .table = { + GPIO_LOOKUP_IDX("gpio-160-175", 7, "reset", 0, + GPIO_ACTIVE_LOW), + { } + }, +}; static void __init omap3_sbc_t3730_legacy_init(void) { - omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); + gpiod_add_lookup_table(&omap3_sbc_t3x_usb_gpio_table); + omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub", 0); } static void __init omap3_sbc_t3530_legacy_init(void) { - omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); + gpiod_add_lookup_table(&omap3_sbc_t3x_usb_gpio_table); + omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub", 0); } static void __init omap3_evm_legacy_init(void) @@ -187,31 +177,59 @@ static void __init am35xx_emac_reset(void) omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */ } -static struct gpio cm_t3517_wlan_gpios[] __initdata = { - { 56, GPIOF_OUT_INIT_HIGH, "wlan pwr" }, - { 4, GPIOF_OUT_INIT_HIGH, "xcvr noe" }, +static struct gpiod_lookup_table cm_t3517_wlan_gpio_table = { + .dev_id = NULL, + .table = { + GPIO_LOOKUP("gpio-48-53", 8, "power", + GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("gpio-0-15", 4, "noe", + GPIO_ACTIVE_HIGH), + { } + }, }; static void __init omap3_sbc_t3517_wifi_init(void) { - int err = gpio_request_array(cm_t3517_wlan_gpios, - ARRAY_SIZE(cm_t3517_wlan_gpios)); - if (err) { - pr_err("SBC-T3517: wl12xx gpios request failed: %d\n", err); - return; - } + struct gpio_desc *d; + + gpiod_add_lookup_table(&cm_t3517_wlan_gpio_table); - gpiod_export(gpio_to_desc(cm_t3517_wlan_gpios[0].gpio), 0); - gpiod_export(gpio_to_desc(cm_t3517_wlan_gpios[1].gpio), 0); + /* This asserts the RESET line (reverse polarity) */ + d = gpiod_get(NULL, "power", GPIOD_OUT_HIGH); + if (IS_ERR(d)) { + pr_err("Unable to get CM T3517 WLAN power GPIO descriptor\n"); + } else { + gpiod_set_consumer_name(d, "wlan pwr"); + gpiod_export(d, 0); + } + d = gpiod_get(NULL, "noe", GPIOD_OUT_HIGH); + if (IS_ERR(d)) { + pr_err("Unable to get CM T3517 WLAN XCVR NOE GPIO descriptor\n"); + } else { + gpiod_set_consumer_name(d, "xcvr noe"); + gpiod_export(d, 0); + } msleep(100); - gpio_set_value(cm_t3517_wlan_gpios[1].gpio, 0); -} + gpiod_set_value(d, 0); +} + +static struct gpiod_lookup_table omap3_sbc_t3517_usb_gpio_table = { + .dev_id = NULL, + .table = { + GPIO_LOOKUP_IDX("gpio-144-159", 8, "reset", 0, + GPIO_ACTIVE_LOW), + GPIO_LOOKUP_IDX("gpio-96-111", 2, "reset", 1, + GPIO_ACTIVE_LOW), + { } + }, +}; static void __init omap3_sbc_t3517_legacy_init(void) { - omap3_sbc_t3x_usb_hub_init(152, "cm-t3517 usb hub"); - omap3_sbc_t3x_usb_hub_init(98, "sb-t35 usb hub"); + gpiod_add_lookup_table(&omap3_sbc_t3517_usb_gpio_table); + omap3_sbc_t3x_usb_hub_init("cm-t3517 usb hub", 0); + omap3_sbc_t3x_usb_hub_init("sb-t35 usb hub", 1); am35xx_emac_reset(); hsmmc2_internal_input_clk(); omap3_sbc_t3517_wifi_init(); @@ -393,21 +411,6 @@ static struct ti_prm_platform_data ti_prm_pdata = { .clkdm_lookup = clkdm_lookup, }; -/* - * GPIOs for TWL are initialized by the I2C bus and need custom - * handing until DSS has device tree bindings. - */ -void omap_auxdata_legacy_init(struct device *dev) -{ - if (dev->platform_data) - return; - - if (strcmp("twl4030-gpio", dev_name(dev))) - return; - - dev->platform_data = &twl_gpio_auxdata; -} - #if defined(CONFIG_ARCH_OMAP3) && IS_ENABLED(CONFIG_SND_SOC_OMAP_MCBSP) static struct omap_mcbsp_platform_data mcbsp_pdata; static void __init omap3_mcbsp_init(void) @@ -428,9 +431,6 @@ static struct pdata_init auxdata_quirks[] __initdata = { { "nokia,n810", omap2420_n8x0_legacy_init, }, { "nokia,n810-wimax", omap2420_n8x0_legacy_init, }, #endif -#ifdef CONFIG_ARCH_OMAP3 - { "compulab,omap3-sbc-t3730", omap3_sbc_t3730_twl_init, }, -#endif { /* sentinel */ }, }; diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c index 18fa52f828dc..b46c254c2bc4 100644 --- a/arch/arm/mach-omap2/usb-tusb6010.c +++ b/arch/arm/mach-omap2/usb-tusb6010.c @@ -11,12 +11,12 @@ #include <linux/errno.h> #include <linux/delay.h> #include <linux/platform_device.h> -#include <linux/gpio.h> #include <linux/export.h> #include <linux/platform_data/usb-omap.h> #include <linux/usb/musb.h> +#include "usb-tusb6010.h" #include "gpmc.h" static u8 async_cs, sync_cs; @@ -132,10 +132,6 @@ static struct resource tusb_resources[] = { { /* Synchronous access */ .flags = IORESOURCE_MEM, }, - { /* IRQ */ - .name = "mc", - .flags = IORESOURCE_IRQ, - }, }; static u64 tusb_dmamask = ~(u32)0; @@ -154,9 +150,9 @@ static struct platform_device tusb_device = { /* this may be called only from board-*.c setup code */ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data, - unsigned ps_refclk, unsigned waitpin, - unsigned async, unsigned sync, - unsigned irq, unsigned dmachan) + unsigned int ps_refclk, unsigned int waitpin, + unsigned int async, unsigned int sync, + unsigned int dmachan) { int status; static char error[] __initdata = @@ -192,14 +188,6 @@ int __init tusb6010_setup_interface(struct musb_hdrc_platform_data *data, if (status < 0) return status; - /* IRQ */ - status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq"); - if (status < 0) { - printk(error, 3, status); - return status; - } - tusb_resources[2].start = gpio_to_irq(irq); - /* set up memory timings ... can speed them up later */ if (!ps_refclk) { printk(error, 4, status); diff --git a/arch/arm/mach-omap2/usb-tusb6010.h b/arch/arm/mach-omap2/usb-tusb6010.h new file mode 100644 index 000000000000..d210ff6238c2 --- /dev/null +++ b/arch/arm/mach-omap2/usb-tusb6010.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __USB_TUSB6010_H +#define __USB_TUSB6010_H + +extern int __init tusb6010_setup_interface( + struct musb_hdrc_platform_data *data, + unsigned int ps_refclk, unsigned int waitpin, + unsigned int async_cs, unsigned int sync_cs, + unsigned int dmachan); + +#endif /* __USB_TUSB6010_H */ diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 4325bdc2b9ff..28e376e06fdc 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -506,10 +506,18 @@ static struct ads7846_platform_data spitz_ads7846_info = { .x_plate_ohms = 419, .y_plate_ohms = 486, .pressure_max = 1024, - .gpio_pendown = SPITZ_GPIO_TP_INT, .wait_for_sync = spitz_ads7846_wait_for_hsync, }; +static struct gpiod_lookup_table spitz_ads7846_gpio_table = { + .dev_id = "spi2.0", + .table = { + GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_TP_INT, + "pendown", GPIO_ACTIVE_LOW), + { } + }, +}; + static void spitz_bl_kick_battery(void) { void (*kick_batt)(void); @@ -594,6 +602,7 @@ static void __init spitz_spi_init(void) else gpiod_add_lookup_table(&spitz_lcdcon_gpio_table); + gpiod_add_lookup_table(&spitz_ads7846_gpio_table); gpiod_add_lookup_table(&spitz_spi_gpio_table); pxa2xx_set_spi_info(2, &spitz_spi_info); spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices)); diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c index 2c52ee27b4f2..79d66faa8482 100644 --- a/arch/mips/alchemy/devboards/db1000.c +++ b/arch/mips/alchemy/devboards/db1000.c @@ -381,13 +381,21 @@ static struct platform_device db1100_mmc1_dev = { static struct ads7846_platform_data db1100_touch_pd = { .model = 7846, .vref_mv = 3300, - .gpio_pendown = 21, }; static struct spi_gpio_platform_data db1100_spictl_pd = { .num_chipselect = 1, }; +static struct gpiod_lookup_table db1100_touch_gpio_table = { + .dev_id = "spi0.0", + .table = { + GPIO_LOOKUP("alchemy-gpio2", 21, + "pendown", GPIO_ACTIVE_LOW), + { } + }, +}; + static struct spi_board_info db1100_spi_info[] __initdata = { [0] = { .modalias = "ads7846", @@ -474,6 +482,7 @@ int __init db1000_dev_setup(void) pfc |= (1 << 0); /* SSI0 pins as GPIOs */ alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); + gpiod_add_lookup_table(&db1100_touch_gpio_table); spi_register_board_info(db1100_spi_info, ARRAY_SIZE(db1100_spi_info)); diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index c1bb2c3ca6f2..446599ac234a 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c @@ -17,7 +17,9 @@ #include <linux/interrupt.h> #include <linux/kthread.h> #include <linux/irq.h> +#include <linux/gpio/machine.h> #include <linux/gpio/driver.h> +#include <linux/gpio/consumer.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/irqdomain.h> @@ -465,8 +467,7 @@ static int gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) REG_GPIO_DEBEN1, 3); } -static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev, - struct twl4030_gpio_platform_data *pdata) +static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) { struct twl4030_gpio_platform_data *omap_twl_info; @@ -474,9 +475,6 @@ static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev, if (!omap_twl_info) return NULL; - if (pdata) - *omap_twl_info = *pdata; - omap_twl_info->use_leds = of_property_read_bool(dev->of_node, "ti,use-leds"); @@ -504,9 +502,18 @@ static int gpio_twl4030_remove(struct platform_device *pdev) return 0; } +/* Called from the registered devm action */ +static void gpio_twl4030_power_off_action(void *data) +{ + struct gpio_desc *d = data; + + gpiod_unexport(d); + gpiochip_free_own_desc(d); +} + static int gpio_twl4030_probe(struct platform_device *pdev) { - struct twl4030_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct twl4030_gpio_platform_data *pdata; struct device_node *node = pdev->dev.of_node; struct gpio_twl4030_priv *priv; int ret, irq_base; @@ -546,9 +553,7 @@ no_irqs: mutex_init(&priv->mutex); - if (node) - pdata = of_gpio_twl4030(&pdev->dev, pdata); - + pdata = of_gpio_twl4030(&pdev->dev); if (pdata == NULL) { dev_err(&pdev->dev, "Platform data is missing\n"); return -ENXIO; @@ -585,17 +590,32 @@ no_irqs: goto out; } - platform_set_drvdata(pdev, priv); + /* + * Special quirk for the OMAP3 to hog and export a WLAN power + * GPIO. + */ + if (IS_ENABLED(CONFIG_ARCH_OMAP3) && + of_machine_is_compatible("compulab,omap3-sbc-t3730")) { + struct gpio_desc *d; - if (pdata->setup) { - int status; + d = gpiochip_request_own_desc(&priv->gpio_chip, + 2, "wlan pwr", + GPIO_ACTIVE_HIGH, + GPIOD_OUT_HIGH); + if (IS_ERR(d)) + return dev_err_probe(&pdev->dev, PTR_ERR(d), + "unable to hog wlan pwr GPIO\n"); + + gpiod_export(d, 0); + + ret = devm_add_action_or_reset(&pdev->dev, gpio_twl4030_power_off_action, d); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to install power off handler\n"); - status = pdata->setup(&pdev->dev, priv->gpio_chip.base, - TWL4030_GPIO_MAX); - if (status) - dev_dbg(&pdev->dev, "setup --> %d\n", status); } + platform_set_drvdata(pdev, priv); out: return ret; } diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index bb1058b1e7fd..40eb27f1b23f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -24,11 +24,8 @@ #include <linux/interrupt.h> #include <linux/slab.h> #include <linux/pm.h> -#include <linux/of.h> -#include <linux/of_gpio.h> -#include <linux/of_device.h> +#include <linux/property.h> #include <linux/gpio/consumer.h> -#include <linux/gpio.h> #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> #include <linux/regulator/consumer.h> @@ -140,7 +137,7 @@ struct ads7846 { int (*filter)(void *data, int data_idx, int *val); void *filter_data; int (*get_pendown_state)(void); - int gpio_pendown; + struct gpio_desc *gpio_pendown; void (*wait_for_sync)(void); }; @@ -223,7 +220,7 @@ static int get_pendown_state(struct ads7846 *ts) if (ts->get_pendown_state) return ts->get_pendown_state(); - return !gpio_get_value(ts->gpio_pendown); + return gpiod_get_value(ts->gpio_pendown); } static void ads7846_report_pen_up(struct ads7846 *ts) @@ -989,8 +986,6 @@ static int ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts, const struct ads7846_platform_data *pdata) { - int err; - /* * REVISIT when the irq can be triggered active-low, or if for some * reason the touchscreen isn't hooked up, we don't need to access @@ -999,25 +994,15 @@ static int ads7846_setup_pendown(struct spi_device *spi, if (pdata->get_pendown_state) { ts->get_pendown_state = pdata->get_pendown_state; - } else if (gpio_is_valid(pdata->gpio_pendown)) { - - err = devm_gpio_request_one(&spi->dev, pdata->gpio_pendown, - GPIOF_IN, "ads7846_pendown"); - if (err) { - dev_err(&spi->dev, - "failed to request/setup pendown GPIO%d: %d\n", - pdata->gpio_pendown, err); - return err; + } else { + ts->gpio_pendown = gpiod_get(&spi->dev, "pendown", GPIOD_IN); + if (IS_ERR(ts->gpio_pendown)) { + dev_err(&spi->dev, "failed to request pendown GPIO\n"); + return PTR_ERR(ts->gpio_pendown); } - - ts->gpio_pendown = pdata->gpio_pendown; - if (pdata->gpio_pendown_debounce) - gpiod_set_debounce(gpio_to_desc(ts->gpio_pendown), + gpiod_set_debounce(ts->gpio_pendown, pdata->gpio_pendown_debounce); - } else { - dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n"); - return -EINVAL; } return 0; @@ -1119,7 +1104,6 @@ static int ads7846_setup_spi_msg(struct ads7846 *ts, return 0; } -#ifdef CONFIG_OF static const struct of_device_id ads7846_dt_ids[] = { { .compatible = "ti,tsc2046", .data = (void *) 7846 }, { .compatible = "ti,ads7843", .data = (void *) 7843 }, @@ -1130,20 +1114,14 @@ static const struct of_device_id ads7846_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, ads7846_dt_ids); -static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) +static const struct ads7846_platform_data *ads7846_get_props(struct device *dev) { struct ads7846_platform_data *pdata; - struct device_node *node = dev->of_node; - const struct of_device_id *match; + const struct platform_device_id *pdev_id; u32 value; - if (!node) { - dev_err(dev, "Device does not have associated DT data\n"); - return ERR_PTR(-EINVAL); - } - - match = of_match_device(ads7846_dt_ids, dev); - if (!match) { + pdev_id = device_get_match_data(dev); + if (!pdev_id) { dev_err(dev, "Unknown device model\n"); return ERR_PTR(-EINVAL); } @@ -1152,60 +1130,51 @@ static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) if (!pdata) return ERR_PTR(-ENOMEM); - pdata->model = (unsigned long)match->data; + pdata->model = (unsigned long)pdev_id->driver_data; - of_property_read_u16(node, "ti,vref-delay-usecs", - &pdata->vref_delay_usecs); - of_property_read_u16(node, "ti,vref-mv", &pdata->vref_mv); - pdata->keep_vref_on = of_property_read_bool(node, "ti,keep-vref-on"); + device_property_read_u16(dev, "ti,vref-delay-usecs", + &pdata->vref_delay_usecs); + device_property_read_u16(dev, "ti,vref-mv", &pdata->vref_mv); + pdata->keep_vref_on = device_property_read_bool(dev, "ti,keep-vref-on"); - pdata->swap_xy = of_property_read_bool(node, "ti,swap-xy"); + pdata->swap_xy = device_property_read_bool(dev, "ti,swap-xy"); - of_property_read_u16(node, "ti,settle-delay-usec", - &pdata->settle_delay_usecs); - of_property_read_u16(node, "ti,penirq-recheck-delay-usecs", - &pdata->penirq_recheck_delay_usecs); + device_property_read_u16(dev, "ti,settle-delay-usec", + &pdata->settle_delay_usecs); + device_property_read_u16(dev, "ti,penirq-recheck-delay-usecs", + &pdata->penirq_recheck_delay_usecs); - of_property_read_u16(node, "ti,x-plate-ohms", &pdata->x_plate_ohms); - of_property_read_u16(node, "ti,y-plate-ohms", &pdata->y_plate_ohms); + device_property_read_u16(dev, "ti,x-plate-ohms", &pdata->x_plate_ohms); + device_property_read_u16(dev, "ti,y-plate-ohms", &pdata->y_plate_ohms); - of_property_read_u16(node, "ti,x-min", &pdata->x_min); - of_property_read_u16(node, "ti,y-min", &pdata->y_min); - of_property_read_u16(node, "ti,x-max", &pdata->x_max); - of_property_read_u16(node, "ti,y-max", &pdata->y_max); + device_property_read_u16(dev, "ti,x-min", &pdata->x_min); + device_property_read_u16(dev, "ti,y-min", &pdata->y_min); + device_property_read_u16(dev, "ti,x-max", &pdata->x_max); + device_property_read_u16(dev, "ti,y-max", &pdata->y_max); /* * touchscreen-max-pressure gets parsed during * touchscreen_parse_properties() */ - of_property_read_u16(node, "ti,pressure-min", &pdata->pressure_min); - if (!of_property_read_u32(node, "touchscreen-min-pressure", &value)) + device_property_read_u16(dev, "ti,pressure-min", &pdata->pressure_min); + if (!device_property_read_u32(dev, "touchscreen-min-pressure", &value)) pdata->pressure_min = (u16) value; - of_property_read_u16(node, "ti,pressure-max", &pdata->pressure_max); + device_property_read_u16(dev, "ti,pressure-max", &pdata->pressure_max); - of_property_read_u16(node, "ti,debounce-max", &pdata->debounce_max); - if (!of_property_read_u32(node, "touchscreen-average-samples", &value)) + device_property_read_u16(dev, "ti,debounce-max", &pdata->debounce_max); + if (!device_property_read_u32(dev, "touchscreen-average-samples", &value)) pdata->debounce_max = (u16) value; - of_property_read_u16(node, "ti,debounce-tol", &pdata->debounce_tol); - of_property_read_u16(node, "ti,debounce-rep", &pdata->debounce_rep); + device_property_read_u16(dev, "ti,debounce-tol", &pdata->debounce_tol); + device_property_read_u16(dev, "ti,debounce-rep", &pdata->debounce_rep); - of_property_read_u32(node, "ti,pendown-gpio-debounce", + device_property_read_u32(dev, "ti,pendown-gpio-debounce", &pdata->gpio_pendown_debounce); - pdata->wakeup = of_property_read_bool(node, "wakeup-source") || - of_property_read_bool(node, "linux,wakeup"); - - pdata->gpio_pendown = of_get_named_gpio(dev->of_node, "pendown-gpio", 0); + pdata->wakeup = device_property_read_bool(dev, "wakeup-source") || + device_property_read_bool(dev, "linux,wakeup"); return pdata; } -#else -static const struct ads7846_platform_data *ads7846_probe_dt(struct device *dev) -{ - dev_err(dev, "no platform data defined\n"); - return ERR_PTR(-EINVAL); -} -#endif static void ads7846_regulator_disable(void *regulator) { @@ -1269,7 +1238,7 @@ static int ads7846_probe(struct spi_device *spi) pdata = dev_get_platdata(dev); if (!pdata) { - pdata = ads7846_probe_dt(dev); + pdata = ads7846_get_props(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } @@ -1426,7 +1395,7 @@ static struct spi_driver ads7846_driver = { .driver = { .name = "ads7846", .pm = pm_sleep_ptr(&ads7846_pm), - .of_match_table = of_match_ptr(ads7846_dt_ids), + .of_match_table = ads7846_dt_ids, }, .probe = ads7846_probe, .remove = ads7846_remove, diff --git a/drivers/mfd/tps65010.c b/drivers/mfd/tps65010.c index fb733288cca3..faea4ff44c6f 100644 --- a/drivers/mfd/tps65010.c +++ b/drivers/mfd/tps65010.c @@ -506,12 +506,8 @@ static void tps65010_remove(struct i2c_client *client) struct tps65010 *tps = i2c_get_clientdata(client); struct tps65010_board *board = dev_get_platdata(&client->dev); - if (board && board->teardown) { - int status = board->teardown(client, board->context); - if (status < 0) - dev_dbg(&client->dev, "board %s %s err %d\n", - "teardown", client->name, status); - } + if (board && board->teardown) + board->teardown(client, &tps->chip); if (client->irq > 0) free_irq(client->irq, tps); cancel_delayed_work_sync(&tps->work); @@ -619,7 +615,7 @@ static int tps65010_probe(struct i2c_client *client) tps, DEBUG_FOPS); /* optionally register GPIOs */ - if (board && board->base != 0) { + if (board) { tps->outmask = board->outmask; tps->chip.label = client->name; @@ -632,7 +628,7 @@ static int tps65010_probe(struct i2c_client *client) /* NOTE: only partial support for inputs; nyet IRQs */ tps->chip.get = tps65010_gpio_get; - tps->chip.base = board->base; + tps->chip.base = -1; tps->chip.ngpio = 7; tps->chip.can_sleep = 1; @@ -641,7 +637,7 @@ static int tps65010_probe(struct i2c_client *client) dev_err(&client->dev, "can't add gpiochip, err %d\n", status); else if (board->setup) { - status = board->setup(client, board->context); + status = board->setup(client, &tps->chip); if (status < 0) { dev_dbg(&client->dev, "board %s %s err %d\n", diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index ce78edfb402b..a14af21f12da 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -26,6 +26,7 @@ #include <linux/clk.h> #include <linux/scatterlist.h> #include <linux/slab.h> +#include <linux/gpio/consumer.h> #include <linux/platform_data/mmc-omap.h> @@ -111,6 +112,9 @@ struct mmc_omap_slot { struct mmc_request *mrq; struct mmc_omap_host *host; struct mmc_host *mmc; + struct gpio_desc *vsd; + struct gpio_desc *vio; + struct gpio_desc *cover; struct omap_mmc_slot_data *pdata; }; @@ -133,6 +137,7 @@ struct mmc_omap_host { int irq; unsigned char bus_mode; unsigned int reg_shift; + struct gpio_desc *slot_switch; struct work_struct cmd_abort_work; unsigned abort:1; @@ -216,8 +221,13 @@ no_claim: if (host->current_slot != slot) { OMAP_MMC_WRITE(host, CON, slot->saved_con & 0xFC00); - if (host->pdata->switch_slot != NULL) - host->pdata->switch_slot(mmc_dev(slot->mmc), slot->id); + if (host->slot_switch) + /* + * With two slots and a simple GPIO switch, setting + * the GPIO to 0 selects slot ID 0, setting it to 1 + * selects slot ID 1. + */ + gpiod_set_value(host->slot_switch, slot->id); host->current_slot = slot; } @@ -297,6 +307,9 @@ static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled) static inline int mmc_omap_cover_is_open(struct mmc_omap_slot *slot) { + /* If we have a GPIO then use that */ + if (slot->cover) + return gpiod_get_value(slot->cover); if (slot->pdata->get_cover_state) return slot->pdata->get_cover_state(mmc_dev(slot->mmc), slot->id); @@ -1106,6 +1119,11 @@ static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on, host = slot->host; + if (slot->vsd) + gpiod_set_value(slot->vsd, power_on); + if (slot->vio) + gpiod_set_value(slot->vio, power_on); + if (slot->pdata->set_power != NULL) slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on, vdd); @@ -1240,6 +1258,23 @@ static int mmc_omap_new_slot(struct mmc_omap_host *host, int id) slot->power_mode = MMC_POWER_UNDEFINED; slot->pdata = &host->pdata->slots[id]; + /* Check for some optional GPIO controls */ + slot->vsd = gpiod_get_index_optional(host->dev, "vsd", + id, GPIOD_OUT_LOW); + if (IS_ERR(slot->vsd)) + return dev_err_probe(host->dev, PTR_ERR(slot->vsd), + "error looking up VSD GPIO\n"); + slot->vio = gpiod_get_index_optional(host->dev, "vio", + id, GPIOD_OUT_LOW); + if (IS_ERR(slot->vio)) + return dev_err_probe(host->dev, PTR_ERR(slot->vio), + "error looking up VIO GPIO\n"); + slot->cover = gpiod_get_index_optional(host->dev, "cover", + id, GPIOD_IN); + if (IS_ERR(slot->cover)) + return dev_err_probe(host->dev, PTR_ERR(slot->cover), + "error looking up cover switch GPIO\n"); + host->slots[id] = slot; mmc->caps = 0; @@ -1349,6 +1384,13 @@ static int mmc_omap_probe(struct platform_device *pdev) if (IS_ERR(host->virt_base)) return PTR_ERR(host->virt_base); + host->slot_switch = gpiod_get_optional(host->dev, "switch", + GPIOD_OUT_LOW); + if (IS_ERR(host->slot_switch)) + return dev_err_probe(host->dev, PTR_ERR(host->slot_switch), + "error looking up slot switch GPIO\n"); + + INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work); INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work); diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d162afbbe19f..ecbd3784bec3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2330,7 +2330,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) spin_lock_init(&musb->lock); spin_lock_init(&musb->list_lock); - musb->board_set_power = plat->set_power; musb->min_power = plat->min_power; musb->ops = plat->platform_ops; musb->port_mode = plat->mode; diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b7588d11cfc5..91b5b6b66f96 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -352,8 +352,6 @@ struct musb { u16 epmask; u8 nr_endpoints; - int (*board_set_power)(int state); - u8 min_power; /* vbus for periph, in mA/2 */ enum musb_mode port_mode; diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index a1f29dbc62e6..cbc707fe570f 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -11,6 +11,8 @@ * interface. */ +#include <linux/gpio/consumer.h> +#include <linux/delay.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -30,6 +32,8 @@ struct tusb6010_glue { struct device *dev; struct platform_device *musb; struct platform_device *phy; + struct gpio_desc *enable; + struct gpio_desc *intpin; }; static void tusb_musb_set_vbus(struct musb *musb, int is_on); @@ -1021,16 +1025,29 @@ static void tusb_setup_cpu_interface(struct musb *musb) static int tusb_musb_start(struct musb *musb) { + struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent); void __iomem *tbase = musb->ctrl_base; - int ret = 0; unsigned long flags; u32 reg; + int i; - if (musb->board_set_power) - ret = musb->board_set_power(1); - if (ret != 0) { - printk(KERN_ERR "tusb: Cannot enable TUSB6010\n"); - return ret; + /* + * Enable or disable power to TUSB6010. When enabling, turn on 3.3 V and + * 1.5 V voltage regulators of PM companion chip. Companion chip will then + * provide then PGOOD signal to TUSB6010 which will release it from reset. + */ + gpiod_set_value(glue->enable, 1); + msleep(1); + + /* Wait for 100ms until TUSB6010 pulls INT pin down */ + i = 100; + while (i && gpiod_get_value(glue->intpin)) { + msleep(1); + i--; + } + if (!i) { + pr_err("tusb: Powerup respones failed\n"); + return -ENODEV; } spin_lock_irqsave(&musb->lock, flags); @@ -1083,8 +1100,8 @@ static int tusb_musb_start(struct musb *musb) err: spin_unlock_irqrestore(&musb->lock, flags); - if (musb->board_set_power) - musb->board_set_power(0); + gpiod_set_value(glue->enable, 0); + msleep(10); return -ENODEV; } @@ -1158,11 +1175,13 @@ done: static int tusb_musb_exit(struct musb *musb) { + struct tusb6010_glue *glue = dev_get_drvdata(musb->controller->parent); + del_timer_sync(&musb->dev_timer); the_musb = NULL; - if (musb->board_set_power) - musb->board_set_power(0); + gpiod_set_value(glue->enable, 0); + msleep(10); iounmap(musb->sync_va); @@ -1218,6 +1237,15 @@ static int tusb_probe(struct platform_device *pdev) glue->dev = &pdev->dev; + glue->enable = devm_gpiod_get(glue->dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(glue->enable)) + return dev_err_probe(glue->dev, PTR_ERR(glue->enable), + "could not obtain power on/off GPIO\n"); + glue->intpin = devm_gpiod_get(glue->dev, "int", GPIOD_IN); + if (IS_ERR(glue->intpin)) + return dev_err_probe(glue->dev, PTR_ERR(glue->intpin), + "could not obtain INT GPIO\n"); + pdata->platform_ops = &tusb_ops; usb_phy_generic_register(); @@ -1236,10 +1264,7 @@ static int tusb_probe(struct platform_device *pdev) musb_resources[1].end = pdev->resource[1].end; musb_resources[1].flags = pdev->resource[1].flags; - musb_resources[2].name = pdev->resource[2].name; - musb_resources[2].start = pdev->resource[2].start; - musb_resources[2].end = pdev->resource[2].end; - musb_resources[2].flags = pdev->resource[2].flags; + musb_resources[2] = DEFINE_RES_IRQ_NAMED(gpiod_to_irq(glue->intpin), "mc"); pinfo = tusb_dev_info; pinfo.parent = &pdev->dev; diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index 03cff39d392d..e4a7f0b824ff 100644 --- a/drivers/video/fbdev/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c @@ -7,6 +7,7 @@ */ #include <linux/device.h> #include <linux/delay.h> +#include <linux/gpio/consumer.h> #include <linux/slab.h> #include <linux/workqueue.h> #include <linux/spi/spi.h> @@ -41,6 +42,7 @@ struct mipid_device { when we can issue the next sleep in/out command */ unsigned long hw_guard_wait; /* max guard time in jiffies */ + struct gpio_desc *reset; struct omapfb_device *fbdev; struct spi_device *spi; @@ -556,6 +558,12 @@ static int mipid_spi_probe(struct spi_device *spi) return -ENOMEM; } + /* This will de-assert RESET if active */ + md->reset = gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(md->reset)) + return dev_err_probe(&spi->dev, PTR_ERR(md->reset), + "no reset GPIO line\n"); + spi->mode = SPI_MODE_0; md->spi = spi; dev_set_drvdata(&spi->dev, md); @@ -574,6 +582,8 @@ static void mipid_spi_remove(struct spi_device *spi) { struct mipid_device *md = dev_get_drvdata(&spi->dev); + /* Asserts RESET */ + gpiod_set_value(md->reset, 1); mipid_disable(&md->panel); kfree(md); } diff --git a/include/linux/mfd/tps65010.h b/include/linux/mfd/tps65010.h index a1fb9bc5311d..5edf1aef1118 100644 --- a/include/linux/mfd/tps65010.h +++ b/include/linux/mfd/tps65010.h @@ -28,6 +28,8 @@ #ifndef __LINUX_I2C_TPS65010_H #define __LINUX_I2C_TPS65010_H +struct gpio_chip; + /* * ---------------------------------------------------------------------------- * Registers, all 8 bits @@ -176,12 +178,10 @@ struct i2c_client; /** * struct tps65010_board - packages GPIO and LED lines - * @base: the GPIO number to assign to GPIO-1 * @outmask: bit (N-1) is set to allow GPIO-N to be used as an * (open drain) output * @setup: optional callback issued once the GPIOs are valid * @teardown: optional callback issued before the GPIOs are invalidated - * @context: optional parameter passed to setup() and teardown() * * Board data may be used to package the GPIO (and LED) lines for use * in by the generic GPIO and LED frameworks. The first four GPIOs @@ -193,12 +193,9 @@ struct i2c_client; * devices in their initial states using these GPIOs. */ struct tps65010_board { - int base; unsigned outmask; - - int (*setup)(struct i2c_client *client, void *context); - int (*teardown)(struct i2c_client *client, void *context); - void *context; + int (*setup)(struct i2c_client *client, struct gpio_chip *gc); + void (*teardown)(struct i2c_client *client, struct gpio_chip *gc); }; #endif /* __LINUX_I2C_TPS65010_H */ diff --git a/include/linux/mfd/twl.h b/include/linux/mfd/twl.h index 6e3d99b7a0ee..c062d91a67d9 100644 --- a/include/linux/mfd/twl.h +++ b/include/linux/mfd/twl.h @@ -593,9 +593,6 @@ struct twl4030_gpio_platform_data { */ u32 pullups; u32 pulldowns; - - int (*setup)(struct device *dev, - unsigned gpio, unsigned ngpio); }; struct twl4030_madc_platform_data { diff --git a/include/linux/platform_data/lcd-mipid.h b/include/linux/platform_data/lcd-mipid.h index 63f05eb23827..4927cfc5158c 100644 --- a/include/linux/platform_data/lcd-mipid.h +++ b/include/linux/platform_data/lcd-mipid.h @@ -15,10 +15,8 @@ enum mipid_test_result { #ifdef __KERNEL__ struct mipid_platform_data { - int nreset_gpio; int data_lines; - void (*shutdown)(struct mipid_platform_data *pdata); void (*set_bklight_level)(struct mipid_platform_data *pdata, int level); int (*get_bklight_level)(struct mipid_platform_data *pdata); diff --git a/include/linux/platform_data/mmc-omap.h b/include/linux/platform_data/mmc-omap.h index 91051e9907f3..054d0c3c5ec5 100644 --- a/include/linux/platform_data/mmc-omap.h +++ b/include/linux/platform_data/mmc-omap.h @@ -20,8 +20,6 @@ struct omap_mmc_platform_data { * maximum frequency on the MMC bus */ unsigned int max_freq; - /* switch the bus to a new slot */ - int (*switch_slot)(struct device *dev, int slot); /* initialize board-specific MMC functionality, can be NULL if * not supported */ int (*init)(struct device *dev); diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index d424c1aadf38..a04c1c34c344 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -35,8 +35,6 @@ struct ads7846_platform_data { u16 debounce_tol; /* tolerance used for filtering */ u16 debounce_rep; /* additional consecutive good readings * required after the first two */ - int gpio_pendown; /* the GPIO used to decide the pendown - * state if get_pendown_state == NULL */ int gpio_pendown_debounce; /* platform specific debounce time for * the gpio_pendown */ int (*get_pendown_state)(void); diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h index e4a3ad3c800f..3963e55e88a3 100644 --- a/include/linux/usb/musb.h +++ b/include/linux/usb/musb.h @@ -99,9 +99,6 @@ struct musb_hdrc_platform_data { /* (HOST or OTG) program PHY for external Vbus */ unsigned extvbus:1; - /* Power the device on or off */ - int (*set_power)(int state); - /* MUSB configuration-specific details */ const struct musb_hdrc_config *config; @@ -135,14 +132,4 @@ static inline int musb_mailbox(enum musb_vbus_id_status status) #define TUSB6010_REFCLK_24 41667 /* psec/clk @ 24.0 MHz XI */ #define TUSB6010_REFCLK_19 52083 /* psec/clk @ 19.2 MHz CLKIN */ -#ifdef CONFIG_ARCH_OMAP2 - -extern int __init tusb6010_setup_interface( - struct musb_hdrc_platform_data *data, - unsigned ps_refclk, unsigned waitpin, - unsigned async_cs, unsigned sync_cs, - unsigned irq, unsigned dmachan); - -#endif /* OMAP2 */ - #endif /* __LINUX_USB_MUSB_H */ |