From 1c8732bb0355b929b09173464cdca7df4d516f89 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 13:34:39 +0200 Subject: gpio: support threaded interrupts in irqchip helpers Some off-chip GPIO expanders need to be communicated by I2C or SPI traffic, but may still support IRQs. By the sleeping nature of such buses, such IRQ handlers need to be threaded. Support such handlers in the gpiochip irqchip helpers by flagging IRQs as threaded if the .can_sleep property of the gpiochip is true. Helpfully deny registration of chained IRQ handlers if the .can_sleep property is set, as such chips will invariably need a nested handler rather than a chained handler. Cc: Thomas Gleixner Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f48817d97480..c12fe9dfd2db 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1363,6 +1363,11 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, int parent_irq, irq_flow_handler_t parent_handler) { + if (gpiochip->can_sleep) { + chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n"); + return; + } + irq_set_chained_handler(parent_irq, parent_handler); /* * The parent irqchip is already using the chip_data for this @@ -1389,6 +1394,9 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, irq_set_chip_data(irq, chip); irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); + /* Chips that can sleep need nested thread handlers */ + if (chip->can_sleep) + irq_set_nested_thread(irq, 1); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else @@ -1401,9 +1409,13 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) { + struct gpio_chip *chip = d->host_data; + #ifdef CONFIG_ARM set_irq_flags(irq, 0); #endif + if (chip->can_sleep) + irq_set_nested_thread(irq, 0); irq_set_chip_and_handler(irq, NULL, NULL); irq_set_chip_data(irq, NULL); } -- cgit v1.2.3 From 033f275236ec0a5ce54b73d5a4b3d0d46f155615 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 12:38:56 +0200 Subject: gpio: tc3589x: use managed resources Grab state container and irq using the devm_* functions and save some lines of hairy clean-up code. Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tc3589x.c | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 1019320984d7..113e50cb1f59 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -329,7 +329,8 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) if (irq < 0) return irq; - tc3589x_gpio = kzalloc(sizeof(struct tc3589x_gpio), GFP_KERNEL); + tc3589x_gpio = devm_kzalloc(&pdev->dev, sizeof(struct tc3589x_gpio), + GFP_KERNEL); if (!tc3589x_gpio) return -ENOMEM; @@ -354,23 +355,25 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_RSTCTRL_GPIRST, 0); if (ret < 0) - goto out_free; + return ret; ret = tc3589x_gpio_irq_init(tc3589x_gpio, np); if (ret) - goto out_free; + return ret; - ret = request_threaded_irq(irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT, - "tc3589x-gpio", tc3589x_gpio); + ret = devm_request_threaded_irq(&pdev->dev, + irq, NULL, tc3589x_gpio_irq, + IRQF_ONESHOT, "tc3589x-gpio", + tc3589x_gpio); if (ret) { dev_err(&pdev->dev, "unable to get irq: %d\n", ret); - goto out_free; + return ret; } ret = gpiochip_add(&tc3589x_gpio->chip); if (ret) { dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); - goto out_freeirq; + return ret; } if (pdata && pdata->setup) @@ -379,12 +382,6 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tc3589x_gpio); return 0; - -out_freeirq: - free_irq(irq, tc3589x_gpio); -out_free: - kfree(tc3589x_gpio); - return ret; } static int tc3589x_gpio_remove(struct platform_device *pdev) @@ -392,7 +389,6 @@ static int tc3589x_gpio_remove(struct platform_device *pdev) struct tc3589x_gpio *tc3589x_gpio = platform_get_drvdata(pdev); struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; struct tc3589x_gpio_platform_data *pdata = tc3589x->pdata->gpio; - int irq = platform_get_irq(pdev, 0); int ret; if (pdata && pdata->remove) @@ -405,10 +401,6 @@ static int tc3589x_gpio_remove(struct platform_device *pdev) return ret; } - free_irq(irq, tc3589x_gpio); - - kfree(tc3589x_gpio); - return 0; } -- cgit v1.2.3 From 5c81f2078b7be63be49916128cc86bc17be7f348 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 12:50:40 +0200 Subject: gpio: tc3589x: get rid of static IRQ base The static IRQ base is not used on any platforms with this chip (only Ux500). Get rid of it forever, and rely on dynamic IRQ descriptor allocation. Cc: Samuel Ortiz Cc: Lee Jones Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tc3589x.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 113e50cb1f59..4b0d8ccbe561 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -32,9 +32,6 @@ struct tc3589x_gpio { struct device *dev; struct mutex irq_lock; struct irq_domain *domain; - - int irq_base; - /* Caches of interrupt control registers for bus_lock */ u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; @@ -290,8 +287,6 @@ static struct irq_domain_ops tc3589x_irq_ops = { static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, struct device_node *np) { - int base = tc3589x_gpio->irq_base; - /* * If this results in a linear domain, irq_create_mapping() will * take care of allocating IRQ descriptors at runtime. When a base @@ -299,7 +294,7 @@ static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, * domain is instantiated. */ tc3589x_gpio->domain = irq_domain_add_simple(np, - tc3589x_gpio->chip.ngpio, base, &tc3589x_irq_ops, + tc3589x_gpio->chip.ngpio, 0, &tc3589x_irq_ops, tc3589x_gpio); if (!tc3589x_gpio->domain) { dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); @@ -348,9 +343,6 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) tc3589x_gpio->chip.of_node = np; #endif - tc3589x_gpio->irq_base = tc3589x->irq_base ? - tc3589x->irq_base + TC3589x_INT_GPIO(0) : 0; - /* Bring the GPIO module out of reset */ ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_RSTCTRL_GPIRST, 0); -- cgit v1.2.3 From cf42f1cfe419f20425fc0c27b9930b6b51fe77b2 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 13:38:33 +0200 Subject: gpio: tc3589x: use gpiolib irqchip helpers Now that the gpiolib irqchip helpers can support nested, threaded IRQ handlers, switch the TC3589x driver over to using this new infrastructure. Tested on the Ux500. Cc: Thomas Gleixner Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-tc3589x.c | 114 +++++++++----------------------------------- 2 files changed, 24 insertions(+), 91 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a86c49a605c6..5ad9e927baba 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -579,6 +579,7 @@ config GPIO_STP_XWAY config GPIO_TC3589X bool "TC3589X GPIOs" depends on MFD_TC3589X + select GPIOLIB_IRQCHIP help This enables support for the GPIOs found on the TC3589X I/O Expander. diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 4b0d8ccbe561..51f7cbd9ff71 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include @@ -31,7 +29,6 @@ struct tc3589x_gpio { struct tc3589x *tc3589x; struct device *dev; struct mutex irq_lock; - struct irq_domain *domain; /* Caches of interrupt control registers for bus_lock */ u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS]; u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS]; @@ -92,30 +89,6 @@ static int tc3589x_gpio_direction_input(struct gpio_chip *chip, return tc3589x_set_bits(tc3589x, reg, 1 << pos, 0); } -/** - * tc3589x_gpio_irq_get_irq(): Map a hardware IRQ on a chip to a Linux IRQ - * - * @tc3589x_gpio: tc3589x_gpio_irq controller to operate on. - * @irq: index of the hardware interrupt requested in the chip IRQs - * - * Useful for drivers to request their own IRQs. - */ -static int tc3589x_gpio_irq_get_irq(struct tc3589x_gpio *tc3589x_gpio, - int hwirq) -{ - if (!tc3589x_gpio) - return -EINVAL; - - return irq_create_mapping(tc3589x_gpio->domain, hwirq); -} - -static int tc3589x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct tc3589x_gpio *tc3589x_gpio = to_tc3589x_gpio(chip); - - return tc3589x_gpio_irq_get_irq(tc3589x_gpio, offset); -} - static struct gpio_chip template_chip = { .label = "tc3589x", .owner = THIS_MODULE, @@ -123,13 +96,13 @@ static struct gpio_chip template_chip = { .get = tc3589x_gpio_get, .direction_output = tc3589x_gpio_direction_output, .set = tc3589x_gpio_set, - .to_irq = tc3589x_gpio_to_irq, .can_sleep = true, }; static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type) { - struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -156,14 +129,16 @@ static int tc3589x_gpio_irq_set_type(struct irq_data *d, unsigned int type) static void tc3589x_gpio_irq_lock(struct irq_data *d) { - struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip); mutex_lock(&tc3589x_gpio->irq_lock); } static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d) { - struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip); struct tc3589x *tc3589x = tc3589x_gpio->tc3589x; static const u8 regmap[] = { [REG_IBE] = TC3589x_GPIOIBE0, @@ -191,7 +166,8 @@ static void tc3589x_gpio_irq_sync_unlock(struct irq_data *d) static void tc3589x_gpio_irq_mask(struct irq_data *d) { - struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -201,7 +177,8 @@ static void tc3589x_gpio_irq_mask(struct irq_data *d) static void tc3589x_gpio_irq_unmask(struct irq_data *d) { - struct tc3589x_gpio *tc3589x_gpio = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct tc3589x_gpio *tc3589x_gpio = container_of(gc, struct tc3589x_gpio, chip); int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); @@ -239,7 +216,8 @@ static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) while (stat) { int bit = __ffs(stat); int line = i * 8 + bit; - int irq = tc3589x_gpio_irq_get_irq(tc3589x_gpio, line); + int irq = irq_find_mapping(tc3589x_gpio->chip.irqdomain, + line); handle_nested_irq(irq); stat &= ~(1 << bit); @@ -251,59 +229,6 @@ static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) return IRQ_HANDLED; } -static int tc3589x_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - struct tc3589x *tc3589x_gpio = d->host_data; - - irq_set_chip_data(irq, tc3589x_gpio); - irq_set_chip_and_handler(irq, &tc3589x_gpio_irq_chip, - handle_simple_irq); - irq_set_nested_thread(irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - - return 0; -} - -static void tc3589x_gpio_irq_unmap(struct irq_domain *d, unsigned int irq) -{ -#ifdef CONFIG_ARM - set_irq_flags(irq, 0); -#endif - irq_set_chip_and_handler(irq, NULL, NULL); - irq_set_chip_data(irq, NULL); -} - -static struct irq_domain_ops tc3589x_irq_ops = { - .map = tc3589x_gpio_irq_map, - .unmap = tc3589x_gpio_irq_unmap, - .xlate = irq_domain_xlate_twocell, -}; - -static int tc3589x_gpio_irq_init(struct tc3589x_gpio *tc3589x_gpio, - struct device_node *np) -{ - /* - * If this results in a linear domain, irq_create_mapping() will - * take care of allocating IRQ descriptors at runtime. When a base - * is provided, the IRQ descriptors will be allocated when the - * domain is instantiated. - */ - tc3589x_gpio->domain = irq_domain_add_simple(np, - tc3589x_gpio->chip.ngpio, 0, &tc3589x_irq_ops, - tc3589x_gpio); - if (!tc3589x_gpio->domain) { - dev_err(tc3589x_gpio->dev, "Failed to create irqdomain\n"); - return -ENOSYS; - } - - return 0; -} - static int tc3589x_gpio_probe(struct platform_device *pdev) { struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); @@ -349,10 +274,6 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) if (ret < 0) return ret; - ret = tc3589x_gpio_irq_init(tc3589x_gpio, np); - if (ret) - return ret; - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, tc3589x_gpio_irq, IRQF_ONESHOT, "tc3589x-gpio", @@ -368,6 +289,17 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) return ret; } + ret = gpiochip_irqchip_add(&tc3589x_gpio->chip, + &tc3589x_gpio_irq_chip, + 0, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&pdev->dev, + "could not connect irqchip to gpiochip\n"); + return ret; + } + if (pdata && pdata->setup) pdata->setup(tc3589x, tc3589x_gpio->chip.base); -- cgit v1.2.3 From 0815c2c0934feb0a99e24bddb8b319f94ae22c9e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Apr 2014 11:33:31 +0200 Subject: gpio: timberdale: simplify dependencies GPIO_TIMBERDALE doesn't need an explicit dependency on HAS_IOMEM, because it depends on MFD_TIMBERDALE which itself depends on HAS_IOMEM already. Signed-off-by: Jean Delvare Cc: Linus Walleij Cc: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 5ad9e927baba..110e7009b10a 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -740,7 +740,7 @@ config GPIO_SODAVILLE config GPIO_TIMBERDALE bool "Support for timberdale GPIO IP" - depends on MFD_TIMBERDALE && HAS_IOMEM + depends on MFD_TIMBERDALE ---help--- Add support for the GPIO IP in the timberdale FPGA. -- cgit v1.2.3 From caebd9db7677166994570db69210cdaa3e30e1fb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:13 +0200 Subject: gpio: omap: convert to use irq_domain_add_simple() The GPIO OMAP driver supports different OMAP SoC families and not all of them have the needed support to use the linear IRQ domain mapping like OMAP1 that use the legacy domain mapping. But this special check is not necessary since the simple IRQ domain mapping is able to handle both cases. Having a zero IRQ offset will be interpreted as a linear domain case while a non-zero value will be interpreted as a legacy domain case. Signed-off-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 19b886c21b1d..3ee9b8d26f71 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1138,9 +1138,7 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; -#ifdef CONFIG_ARCH_OMAP1 - int irq_base; -#endif + int irq_base = 0; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1185,21 +1183,16 @@ static int omap_gpio_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_OMAP1 /* * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop - * irq_alloc_descs() and irq_domain_add_legacy() and just use a - * linear IRQ domain mapping for all OMAP platforms. + * irq_alloc_descs() since a base IRQ offset will no longer be needed. */ irq_base = irq_alloc_descs(-1, 0, bank->width, 0); if (irq_base < 0) { dev_err(dev, "Couldn't allocate IRQ numbers\n"); return -ENODEV; } - - bank->domain = irq_domain_add_legacy(node, bank->width, irq_base, - 0, &irq_domain_simple_ops, NULL); -#else - bank->domain = irq_domain_add_linear(node, bank->width, - &irq_domain_simple_ops, NULL); #endif + bank->domain = irq_domain_add_simple(node, bank->width, irq_base, + &irq_domain_simple_ops, NULL); if (!bank->domain) { dev_err(dev, "Couldn't register an IRQ domain\n"); return -ENODEV; -- cgit v1.2.3 From 6ef7f385610a235c7041206da0f92f760b5d0e8d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:14 +0200 Subject: gpio: omap: check gpiochip_add() return value The gpiochip_add() function can fail if the chip cannot be registered so the return value has to be checked and the error propagated in case it happens. Signed-off-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 3ee9b8d26f71..e71788835319 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -1081,10 +1081,11 @@ omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start, IRQ_NOREQUEST | IRQ_NOPROBE, 0); } -static void omap_gpio_chip_init(struct gpio_bank *bank) +static int omap_gpio_chip_init(struct gpio_bank *bank) { int j; static int gpio; + int ret; /* * REVISIT eventually switch from OMAP-specific gpio structs @@ -1110,7 +1111,11 @@ static void omap_gpio_chip_init(struct gpio_bank *bank) } bank->chip.ngpio = bank->width; - gpiochip_add(&bank->chip); + ret = gpiochip_add(&bank->chip); + if (ret) { + dev_err(bank->dev, "Could not register gpio chip\n", ret); + return ret; + } for (j = 0; j < bank->width; j++) { int irq = irq_create_mapping(bank->domain, j); @@ -1139,6 +1144,7 @@ static int omap_gpio_probe(struct platform_device *pdev) struct resource *res; struct gpio_bank *bank; int irq_base = 0; + int ret; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1223,7 +1229,11 @@ static int omap_gpio_probe(struct platform_device *pdev) mpuio_init(bank); omap_gpio_mod_init(bank); - omap_gpio_chip_init(bank); + + ret = omap_gpio_chip_init(bank); + if (ret) + return ret; + omap_gpio_show_rev(bank); pm_runtime_put(bank->dev); -- cgit v1.2.3 From cd0a3748f3137c282e3a037b295b47f597e73230 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:15 +0200 Subject: gpio: omap: add a GPIO_OMAP option instead of using ARCH_OMAP The ARCH_OMAP config option was used to built the GPIO OMAP driver but this is not consistent with the rest of the GPIO drivers that have their own Kconfig option. Also, this make it harder to add dependencies or reverse dependencies (i.e: select) since that would mean touching the sub-arch config option. So is better to add a boolean Kconfig option for this driver that defaults to true if ARCH_OMAP is enabled. Signed-off-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 7 +++++++ drivers/gpio/Makefile | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 110e7009b10a..43a65ed010de 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -243,6 +243,13 @@ config GPIO_OCTEON Say yes here to support the on-chip GPIO lines on the OCTEON family of SOCs. +config GPIO_OMAP + bool "TI OMAP GPIO support" + default y if ARCH_OMAP + depends on ARM && ARCH_OMAP + help + Say yes here to enable GPIO support for TI OMAP SoCs. + config GPIO_PL061 bool "PrimeCell PL061 GPIO support" depends on ARM_AMBA diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 6309aff1d806..d10f6a9d875a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o -obj-$(CONFIG_ARCH_OMAP) += gpio-omap.o +obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o obj-$(CONFIG_GPIO_PCF857X) += gpio-pcf857x.o obj-$(CONFIG_GPIO_PCH) += gpio-pch.o -- cgit v1.2.3 From fb655f57cee30f9121cce3653117d2c40affe194 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 6 Apr 2014 16:58:16 +0200 Subject: gpio: omap: convert driver to use gpiolib irqchip Converts the GPIO OMAP driver to register its chained irq handler and irqchip using the helpers in the gpiolib core. Signed-off-by: Javier Martinez Canillas Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-omap.c | 107 ++++++++++++++++++++++------------------------- 2 files changed, 52 insertions(+), 56 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 43a65ed010de..c58b828e882f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -247,6 +247,7 @@ config GPIO_OMAP bool "TI OMAP GPIO support" default y if ARCH_OMAP depends on ARM && ARCH_OMAP + select GPIOLIB_IRQCHIP help Say yes here to enable GPIO support for TI OMAP SoCs. diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e71788835319..8cc9e91e7e4e 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,6 @@ struct gpio_bank { struct list_head node; void __iomem *base; u16 irq; - struct irq_domain *domain; u32 non_wakeup_gpios; u32 enabled_non_wakeup_gpios; struct gpio_regs context; @@ -95,11 +93,10 @@ static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) return bank->chip.base + gpio_irq; } -static int omap_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +static inline struct gpio_bank *_irq_data_get_bank(struct irq_data *d) { - struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip); - - return irq_find_mapping(bank->domain, offset); + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + return container_of(chip, struct gpio_bank, chip); } static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) @@ -479,7 +476,7 @@ static int gpio_is_input(struct gpio_bank *bank, int mask) static int gpio_irq_type(struct irq_data *d, unsigned type) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned gpio = 0; int retval; unsigned long flags; @@ -514,14 +511,6 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) return -EINVAL; } - retval = gpio_lock_as_irq(&bank->chip, offset); - if (retval) { - dev_err(bank->dev, "unable to lock offset %d for IRQ\n", - offset); - spin_unlock_irqrestore(&bank->lock, flags); - return retval; - } - bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); spin_unlock_irqrestore(&bank->lock, flags); @@ -664,7 +653,7 @@ static void _reset_gpio(struct gpio_bank *bank, int gpio) /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ static int gpio_wake_enable(struct irq_data *d, unsigned int enable) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); return _set_gpio_wakeup(bank, gpio, enable); @@ -732,11 +721,12 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) unsigned int bit; struct gpio_bank *bank; int unmasked = 0; - struct irq_chip *chip = irq_desc_get_chip(desc); + struct irq_chip *irqchip = irq_desc_get_chip(desc); + struct gpio_chip *chip = irq_get_handler_data(irq); - chained_irq_enter(chip, desc); + chained_irq_enter(irqchip, desc); - bank = irq_get_handler_data(irq); + bank = container_of(chip, struct gpio_bank, chip); isr_reg = bank->base + bank->regs->irqstatus; pm_runtime_get_sync(bank->dev); @@ -764,7 +754,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) configured, we could unmask GPIO bank interrupt immediately */ if (!level_mask && !unmasked) { unmasked = 1; - chained_irq_exit(chip, desc); + chained_irq_exit(irqchip, desc); } if (!isr) @@ -784,7 +774,8 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) if (bank->toggle_mask & (1 << bit)) _toggle_gpio_edge_triggering(bank, bit); - generic_handle_irq(irq_find_mapping(bank->domain, bit)); + generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, + bit)); } } /* if bank has any level sensitive GPIO pin interrupt @@ -793,13 +784,13 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) interrupt */ exit: if (!unmasked) - chained_irq_exit(chip, desc); + chained_irq_exit(irqchip, desc); pm_runtime_put(bank->dev); } static void gpio_irq_shutdown(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; unsigned offset = GPIO_INDEX(bank, gpio); @@ -821,7 +812,7 @@ static void gpio_irq_shutdown(struct irq_data *d) static void gpio_ack_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); _clear_gpio_irqstatus(bank, gpio); @@ -829,7 +820,7 @@ static void gpio_ack_irq(struct irq_data *d) static void gpio_mask_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned long flags; @@ -841,7 +832,7 @@ static void gpio_mask_irq(struct irq_data *d) static void gpio_unmask_irq(struct irq_data *d) { - struct gpio_bank *bank = irq_data_get_irq_chip_data(d); + struct gpio_bank *bank = _irq_data_get_bank(d); unsigned int gpio = irq_to_gpio(bank, d->hwirq); unsigned int irq_mask = GPIO_BIT(bank, gpio); u32 trigger = irqd_get_trigger_type(d); @@ -1085,6 +1076,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) { int j; static int gpio; + int irq_base = 0; int ret; /* @@ -1098,7 +1090,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) bank->chip.direction_output = gpio_output; bank->chip.set_debounce = gpio_debounce; bank->chip.set = gpio_set; - bank->chip.to_irq = omap_gpio_to_irq; if (bank->is_mpuio) { bank->chip.label = "mpuio"; if (bank->regs->wkup_en) @@ -1113,24 +1104,46 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) ret = gpiochip_add(&bank->chip); if (ret) { - dev_err(bank->dev, "Could not register gpio chip\n", ret); + dev_err(bank->dev, "Could not register gpio chip %d\n", ret); return ret; } +#ifdef CONFIG_ARCH_OMAP1 + /* + * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop + * irq_alloc_descs() since a base IRQ offset will no longer be needed. + */ + irq_base = irq_alloc_descs(-1, 0, bank->width, 0); + if (irq_base < 0) { + dev_err(bank->dev, "Couldn't allocate IRQ numbers\n"); + return -ENODEV; + } +#endif + + ret = gpiochip_irqchip_add(&bank->chip, &gpio_irq_chip, + irq_base, gpio_irq_handler, + IRQ_TYPE_NONE); + + if (ret) { + dev_err(bank->dev, "Couldn't add irqchip to gpiochip %d\n", ret); + ret = gpiochip_remove(&bank->chip); + return -ENODEV; + } + + gpiochip_set_chained_irqchip(&bank->chip, &gpio_irq_chip, + bank->irq, gpio_irq_handler); + for (j = 0; j < bank->width; j++) { - int irq = irq_create_mapping(bank->domain, j); + int irq = irq_find_mapping(bank->chip.irqdomain, j); irq_set_lockdep_class(irq, &gpio_lock_class); - irq_set_chip_data(irq, bank); if (bank->is_mpuio) { omap_mpuio_alloc_gc(bank, irq, bank->width); - } else { - irq_set_chip_and_handler(irq, &gpio_irq_chip, - handle_simple_irq); - set_irq_flags(irq, IRQF_VALID); + irq_set_chip_and_handler(irq, NULL, NULL); + set_irq_flags(irq, 0); } } - irq_set_chained_handler(bank->irq, gpio_irq_handler); - irq_set_handler_data(bank->irq, bank); + + return 0; } static const struct of_device_id omap_gpio_match[]; @@ -1143,7 +1156,6 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct omap_gpio_platform_data *pdata; struct resource *res; struct gpio_bank *bank; - int irq_base = 0; int ret; match = of_match_device(of_match_ptr(omap_gpio_match), dev); @@ -1166,6 +1178,7 @@ static int omap_gpio_probe(struct platform_device *pdev) bank->irq = res->start; bank->dev = dev; + bank->chip.dev = dev; bank->dbck_flag = pdata->dbck_flag; bank->stride = pdata->bank_stride; bank->width = pdata->bank_width; @@ -1186,24 +1199,6 @@ static int omap_gpio_probe(struct platform_device *pdev) pdata->get_context_loss_count; } -#ifdef CONFIG_ARCH_OMAP1 - /* - * REVISIT: Once we have OMAP1 supporting SPARSE_IRQ, we can drop - * irq_alloc_descs() since a base IRQ offset will no longer be needed. - */ - irq_base = irq_alloc_descs(-1, 0, bank->width, 0); - if (irq_base < 0) { - dev_err(dev, "Couldn't allocate IRQ numbers\n"); - return -ENODEV; - } -#endif - bank->domain = irq_domain_add_simple(node, bank->width, irq_base, - &irq_domain_simple_ops, NULL); - if (!bank->domain) { - dev_err(dev, "Couldn't register an IRQ domain\n"); - return -ENODEV; - } - if (bank->regs->set_dataout && bank->regs->clr_dataout) bank->set_dataout = _set_gpio_dataout_reg; else @@ -1215,7 +1210,7 @@ static int omap_gpio_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bank->base = devm_ioremap_resource(dev, res); if (IS_ERR(bank->base)) { - irq_domain_remove(bank->domain); + irq_domain_remove(bank->chip.irqdomain); return PTR_ERR(bank->base); } -- cgit v1.2.3 From 11d3d334af07408ce3a68860c40006ddcd343da5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 7 Apr 2014 12:13:05 +0200 Subject: gpio: dwapb: drop irq_setup_generic_chip() The driver calls irq_alloc_domain_generic_chips() which creates a gc and adds it to gc_list. The driver later then calls irq_setup_generic_chip() which also initializes the gc and adds it to the gc_list() and this corrupts the list. Enable LIST_DEBUG and you see the kernel complain. This isn't required, irq_alloc_domain_generic_chips() did the init. Signed-off-by: Sebastian Andrzej Siewior Tested-by: Alan Tull Signed-off-by: Linus Walleij --- drivers/gpio/gpio-dwapb.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index ed5711f77e2d..4d25a06bb45e 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -260,9 +260,6 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, ct->regs.ack = GPIO_PORTA_EOI; ct->regs.mask = GPIO_INTMASK; - irq_setup_generic_chip(irq_gc, IRQ_MSK(port->bgc.gc.ngpio), - IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0); - irq_set_chained_handler(irq, dwapb_irq_handler); irq_set_handler_data(irq, gpio); -- cgit v1.2.3 From 9ea8d8102bbd32d97fe25decd4bf47ad2a63e031 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 8 Apr 2014 11:44:49 +0800 Subject: gpio: zevio: Remove of_match_ptr around zevio_gpio_of_match This is a DT-only driver and it will be built only when CONFIG_OF is set. So it's pointless to use of_match_ptr. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-zevio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 9bf5034b6cdb..7184f4577848 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -209,7 +209,7 @@ static struct platform_driver zevio_gpio_driver = { .driver = { .name = "gpio-zevio", .owner = THIS_MODULE, - .of_match_table = of_match_ptr(zevio_gpio_of_match), + .of_match_table = zevio_gpio_of_match, }, .probe = zevio_gpio_probe, }; -- cgit v1.2.3 From 1e0d9823178f8793dec7d1e9cd08f9bee5123871 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Mon, 7 Apr 2014 14:20:32 +0200 Subject: gpio-sch: set output level after configuration of direction According to the datasheet, writing to the level register has no effect when GPIO is programmed as input. Actually the the level register is read-only when configured as input. Thus presetting the output level before switching to output is _NOT_ possible. Any writes are lost! Hence we set the level after configuring the GPIO as output. But we cannot prevent a short low pulse if direction is set to high and an external pull-up is connected. Signed-off-by: Daniel Krueger Signed-off-by: Alexander Stein Signed-off-by: Linus Walleij --- drivers/gpio/gpio-sch.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 5af65719b95d..a9b1cd16c848 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c @@ -97,8 +97,6 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc, u8 curr_dirs; unsigned short offset, bit; - sch_gpio_core_set(gc, gpio_num, val); - spin_lock(&gpio_lock); offset = CGIO + gpio_num / 8; @@ -109,6 +107,17 @@ static int sch_gpio_core_direction_out(struct gpio_chip *gc, outb(curr_dirs & ~(1 << bit), gpio_ba + offset); spin_unlock(&gpio_lock); + + /* + * according to the datasheet, writing to the level register has no + * effect when GPIO is programmed as input. + * Actually the the level register is read-only when configured as input. + * Thus presetting the output level before switching to output is _NOT_ possible. + * Hence we set the level after configuring the GPIO as output. + * But we cannot prevent a short low pulse if direction is set to high + * and an external pull-up is connected. + */ + sch_gpio_core_set(gc, gpio_num, val); return 0; } @@ -178,8 +187,6 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc, u8 curr_dirs; unsigned short offset, bit; - sch_gpio_resume_set(gc, gpio_num, val); - offset = RGIO + gpio_num / 8; bit = gpio_num % 8; @@ -190,6 +197,17 @@ static int sch_gpio_resume_direction_out(struct gpio_chip *gc, outb(curr_dirs & ~(1 << bit), gpio_ba + offset); spin_unlock(&gpio_lock); + + /* + * according to the datasheet, writing to the level register has no + * effect when GPIO is programmed as input. + * Actually the the level register is read-only when configured as input. + * Thus presetting the output level before switching to output is _NOT_ possible. + * Hence we set the level after configuring the GPIO as output. + * But we cannot prevent a short low pulse if direction is set to high + * and an external pull-up is connected. + */ + sch_gpio_resume_set(gc, gpio_num, val); return 0; } -- cgit v1.2.3 From e45d1c80c0eee88e82751461e9cac49d9ed287bc Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Apr 2014 14:01:46 +0200 Subject: gpio: put GPIO IRQs into their own lock class Another feature that is duplicated in a number of GPIO irqchips is that these cascades IRQs are assigned their own lock class so as to avoid warnings about lockdep recursions. Do this also in the generic GPIO irqchip helpers for smooth transition to this core infrastructure. Cc: Thomas Gleixner Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c12fe9dfd2db..ee1819fdcf35 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1377,6 +1377,12 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, } EXPORT_SYMBOL_GPL(gpiochip_set_chained_irqchip); +/* + * This lock class tells lockdep that GPIO irqs are in a different + * category than their parents, so it won't report false recursion. + */ +static struct lock_class_key gpiochip_irq_lock_class; + /** * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip * @d: the irqdomain used by this irqchip @@ -1393,6 +1399,7 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, struct gpio_chip *chip = d->host_data; irq_set_chip_data(irq, chip); + irq_set_lockdep_class(irq, &gpiochip_irq_lock_class); irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); /* Chips that can sleep need nested thread handlers */ if (chip->can_sleep) -- cgit v1.2.3 From ef7de2625fdd40c2d26a10bf87cc1626017adc18 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 8 Apr 2014 07:59:39 +0800 Subject: gpio: zevio: Get correct gpio output value Read gpio output value from ZEVIO_GPIO_OUTPUT. The spin_lock is required to ensure the direction is not changed before reading input/ouput value. Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-zevio.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 7184f4577848..6270f755d0ed 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -81,9 +81,15 @@ static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin, static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin) { struct zevio_gpio *controller = to_zevio_gpio(chip); + u32 val, dir; - /* Only reading allowed, so no spinlock needed */ - u32 val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); + spin_lock(&controller->lock); + dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION); + if (dir & BIT(ZEVIO_GPIO_BIT(pin))) + val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); + else + val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT); + spin_unlock(&controller->lock); return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1; } -- cgit v1.2.3 From ccd9726e05f0b181016db1adcff633cf9baf5c4e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 22 Apr 2014 14:38:21 +0200 Subject: gpiolib: of: remove gpio_to_desc() usage As demonstrated by commit 390d82e312c56b75407a3606cbcde8c4bc7f10ae "gpiolib: ACPI: remove gpio_to_desc() usage" gpio_to_desc() must die. Replace one of its usage by the newly-introduced gpiochip_get_desc() function. Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 2024d45e5503..db98d3a12f70 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -48,7 +48,7 @@ static int of_gpiochip_find_and_xlate(struct gpio_chip *gc, void *data) if (ret < 0) return false; - gg_data->out_gpio = gpio_to_desc(ret + gc->base); + gg_data->out_gpio = gpiochip_get_desc(gc, ret); return true; } -- cgit v1.2.3 From 9dacc6de4c0906667d704e3d6ef72dd3f15911a8 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 12 Apr 2014 09:41:31 +0400 Subject: gpio: ge: Convert to platform driver This patch converts GE I/O FPGA GPIO driver to platform driver. Signed-off-by: Alexander Shiyan Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ge.c | 174 +++++++++++++++---------------------------------- 1 file changed, 53 insertions(+), 121 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-ge.c b/drivers/gpio/gpio-ge.c index 7b95a4a8318c..1237a73c3c91 100644 --- a/drivers/gpio/gpio-ge.c +++ b/drivers/gpio/gpio-ge.c @@ -18,15 +18,9 @@ */ #include -#include -#include #include -#include #include -#include #include -#include -#include #include #define GEF_GPIO_DIRECT 0x00 @@ -39,28 +33,26 @@ #define GEF_GPIO_OVERRUN 0x1C #define GEF_GPIO_MODE 0x20 -static void _gef_gpio_set(void __iomem *reg, unsigned int offset, int value) +static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { + struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); unsigned int data; - data = ioread32be(reg); - /* value: 0=low; 1=high */ - if (value & 0x1) - data = data | (0x1 << offset); + data = ioread32be(mmchip->regs + GEF_GPIO_OUT); + if (value) + data = data | BIT(offset); else - data = data & ~(0x1 << offset); - - iowrite32be(data, reg); + data = data & ~BIT(offset); + iowrite32be(data, mmchip->regs + GEF_GPIO_OUT); } - static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset) { unsigned int data; struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT); - data = data | (0x1 << offset); + data = data | BIT(offset); iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT); return 0; @@ -71,11 +63,11 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) unsigned int data; struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - /* Set direction before switching to input */ - _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value); + /* Set value before switching to output */ + gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value); data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT); - data = data & ~(0x1 << offset); + data = data & ~BIT(offset); iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT); return 0; @@ -83,116 +75,56 @@ static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value) static int gef_gpio_get(struct gpio_chip *chip, unsigned offset) { - unsigned int data; - int state = 0; struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - data = ioread32be(mmchip->regs + GEF_GPIO_IN); - state = (int)((data >> offset) & 0x1); - - return state; + return !!(ioread32be(mmchip->regs + GEF_GPIO_IN) & BIT(offset)); } -static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip); - - _gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value); -} +static const struct of_device_id gef_gpio_ids[] = { + { + .compatible = "gef,sbc610-gpio", + .data = (void *)19, + }, { + .compatible = "gef,sbc310-gpio", + .data = (void *)6, + }, { + .compatible = "ge,imp3a-gpio", + .data = (void *)16, + }, + { } +}; +MODULE_DEVICE_TABLE(of, gef_gpio_ids); -static int __init gef_gpio_init(void) +static int __init gef_gpio_probe(struct platform_device *pdev) { - struct device_node *np; - int retval; - struct of_mm_gpio_chip *gef_gpio_chip; - - for_each_compatible_node(np, NULL, "gef,sbc610-gpio") { - - pr_debug("%s: Initialising GEF GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->gc.of_gpio_n_cells = 2; - gef_gpio_chip->gc.ngpio = 19; - gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->gc.get = gef_gpio_get; - gef_gpio_chip->gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } - - for_each_compatible_node(np, NULL, "gef,sbc310-gpio") { - - pr_debug("%s: Initialising GEF GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->gc.of_gpio_n_cells = 2; - gef_gpio_chip->gc.ngpio = 6; - gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->gc.get = gef_gpio_get; - gef_gpio_chip->gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } - - for_each_compatible_node(np, NULL, "ge,imp3a-gpio") { - - pr_debug("%s: Initialising GE GPIO\n", np->full_name); - - /* Allocate chip structure */ - gef_gpio_chip = kzalloc(sizeof(*gef_gpio_chip), GFP_KERNEL); - if (!gef_gpio_chip) { - pr_err("%s: Unable to allocate structure\n", - np->full_name); - continue; - } - - /* Setup pointers to chip functions */ - gef_gpio_chip->gc.of_gpio_n_cells = 2; - gef_gpio_chip->gc.ngpio = 16; - gef_gpio_chip->gc.direction_input = gef_gpio_dir_in; - gef_gpio_chip->gc.direction_output = gef_gpio_dir_out; - gef_gpio_chip->gc.get = gef_gpio_get; - gef_gpio_chip->gc.set = gef_gpio_set; - - /* This function adds a memory mapped GPIO chip */ - retval = of_mm_gpiochip_add(np, gef_gpio_chip); - if (retval) { - kfree(gef_gpio_chip); - pr_err("%s: Unable to add GPIO\n", np->full_name); - } - } + const struct of_device_id *of_id = + of_match_device(gef_gpio_ids, &pdev->dev); + struct of_mm_gpio_chip *mmchip; + + mmchip = devm_kzalloc(&pdev->dev, sizeof(*mmchip), GFP_KERNEL); + if (!mmchip) + return -ENOMEM; + + /* Setup pointers to chip functions */ + mmchip->gc.ngpio = (u16)(uintptr_t)of_id->data; + mmchip->gc.of_gpio_n_cells = 2; + mmchip->gc.direction_input = gef_gpio_dir_in; + mmchip->gc.direction_output = gef_gpio_dir_out; + mmchip->gc.get = gef_gpio_get; + mmchip->gc.set = gef_gpio_set; + + /* This function adds a memory mapped GPIO chip */ + return of_mm_gpiochip_add(pdev->dev.of_node, mmchip); +}; - return 0; +static struct platform_driver gef_gpio_driver = { + .driver = { + .name = "gef-gpio", + .owner = THIS_MODULE, + .of_match_table = gef_gpio_ids, + }, }; -arch_initcall(gef_gpio_init); +module_platform_driver_probe(gef_gpio_driver, gef_gpio_probe); MODULE_DESCRIPTION("GE I/O FPGA GPIO driver"); MODULE_AUTHOR("Martyn Welch Date: Mon, 14 Apr 2014 15:30:41 +0800 Subject: gpio: max730x: Remove kfree(ts) in __max730x_remove() The memory for ts is allocated by devm_kzalloc now, so the kfree is not required. Signed-off-by: Axel Lin Acked-by: Juergen Beisert Reviewed-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-max730x.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-max730x.c b/drivers/gpio/gpio-max730x.c index 8672755f95c9..0814584fcdc1 100644 --- a/drivers/gpio/gpio-max730x.c +++ b/drivers/gpio/gpio-max730x.c @@ -237,10 +237,9 @@ int __max730x_remove(struct device *dev) ts->write(dev, 0x04, 0x00); ret = gpiochip_remove(&ts->chip); - if (!ret) { + if (!ret) mutex_destroy(&ts->lock); - kfree(ts); - } else + else dev_err(dev, "Failed to remove GPIO controller: %d\n", ret); return ret; -- cgit v1.2.3 From f604cf0919b806bdedef5f53dd1f43796166997c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 15 Apr 2014 09:03:54 +0800 Subject: gpio: pl061/sx150x: Remove unneeded include of linux/workqueue.h Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 1 - drivers/gpio/gpio-sx150x.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index b0f475243cef..84553d35bdfa 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c index 13d73fb2b5e1..b51ca9f5c140 100644 --- a/drivers/gpio/gpio-sx150x.c +++ b/drivers/gpio/gpio-sx150x.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #define NO_UPDATE_PENDING -1 -- cgit v1.2.3 From 7e9fcc9d62626c752e38d5eeb78687d006fc24cf Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 15 Apr 2014 10:15:27 +0800 Subject: gpio: sch311x: Slightly refactor sch311x_detect for better readability Signed-off-by: Axel Lin Signed-off-by: Linus Walleij --- drivers/gpio/gpio-sch311x.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-sch311x.c b/drivers/gpio/gpio-sch311x.c index 0357387b3645..f942b80ee403 100644 --- a/drivers/gpio/gpio-sch311x.c +++ b/drivers/gpio/gpio-sch311x.c @@ -327,14 +327,22 @@ static int __init sch311x_detect(int sio_config_port, unsigned short *addr) if (err) return err; - /* Check device ID. We currently know about: - * SCH3112 (0x7c), SCH3114 (0x7d), and SCH3116 (0x7f). */ + /* Check device ID. */ reg = sch311x_sio_inb(sio_config_port, 0x20); - if (!(reg == 0x7c || reg == 0x7d || reg == 0x7f)) { + switch (reg) { + case 0x7c: /* SCH3112 */ + dev_id = 2; + break; + case 0x7d: /* SCH3114 */ + dev_id = 4; + break; + case 0x7f: /* SCH3116 */ + dev_id = 6; + break; + default: err = -ENODEV; goto exit; } - dev_id = reg == 0x7c ? 2 : reg == 0x7d ? 4 : 6; /* Select logical device A (runtime registers) */ sch311x_sio_outb(sio_config_port, 0x07, 0x0a); -- cgit v1.2.3 From 9288ecad7522e9d4fa34c3cb3ac8f762aa6b8f7c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 12 Apr 2014 12:45:18 +0800 Subject: gpio: kempld: Fix autoloading of module Make the module alias match the platform device name, so gpio-kempld module should now autoload correctly. Signed-off-by: Axel Lin Reviewed-by: Guenter Roeck Signed-off-by: Linus Walleij --- drivers/gpio/gpio-kempld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index c6d88173f5a2..ebe102325569 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -216,4 +216,4 @@ module_platform_driver(kempld_gpio_driver); MODULE_DESCRIPTION("KEM PLD GPIO Driver"); MODULE_AUTHOR("Michael Brunner "); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:gpio-kempld"); +MODULE_ALIAS("platform:kempld-gpio"); -- cgit v1.2.3 From df0c6c80232f2ad442dcf79a3a420eb8ac624e42 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Apr 2014 20:33:13 +0200 Subject: gpio: rcar: Add minimal runtime PM support This is just enough to automatically enable the functional clock, if present. Clock management during suspend/resume is still to be added. Signed-off-by: Geert Uytterhoeven Cc: linux-gpio@vger.kernel.org Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rcar.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 03c91482432c..bfcfeeefcf78 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -377,6 +378,9 @@ static int gpio_rcar_probe(struct platform_device *pdev) platform_set_drvdata(pdev, p); + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); @@ -460,6 +464,8 @@ static int gpio_rcar_probe(struct platform_device *pdev) err1: irq_domain_remove(p->irq_domain); err0: + pm_runtime_put(dev); + pm_runtime_disable(dev); return ret; } @@ -473,6 +479,8 @@ static int gpio_rcar_remove(struct platform_device *pdev) return ret; irq_domain_remove(p->irq_domain); + pm_runtime_put(&pdev->dev); + pm_runtime_disable(&pdev->dev); return 0; } -- cgit v1.2.3 From 95ad6b9da5d28dbd8a10e4e0091242504b3d13d1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 11 Apr 2014 14:16:01 +0800 Subject: gpio: rdc321x: Convert to use devm_kzalloc This saves a few unwind code. Signed-off-by: Axel Lin Acked-by: Florian Fainelli Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rdc321x.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index 88577c3272a5..7a319e5138a5 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -141,7 +141,8 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) return -ENODEV; } - rdc321x_gpio_dev = kzalloc(sizeof(struct rdc321x_gpio), GFP_KERNEL); + rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio), + GFP_KERNEL); if (!rdc321x_gpio_dev) { dev_err(&pdev->dev, "failed to allocate private data\n"); return -ENOMEM; @@ -150,8 +151,7 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1"); if (!r) { dev_err(&pdev->dev, "failed to get gpio-reg1 resource\n"); - err = -ENODEV; - goto out_free; + return -ENODEV; } spin_lock_init(&rdc321x_gpio_dev->lock); @@ -162,8 +162,7 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg2"); if (!r) { dev_err(&pdev->dev, "failed to get gpio-reg2 resource\n"); - err = -ENODEV; - goto out_free; + return -ENODEV; } rdc321x_gpio_dev->reg2_ctrl_base = r->start; @@ -187,21 +186,17 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) rdc321x_gpio_dev->reg1_data_base, &rdc321x_gpio_dev->data_reg[0]); if (err) - goto out_free; + return err; err = pci_read_config_dword(rdc321x_gpio_dev->sb_pdev, rdc321x_gpio_dev->reg2_data_base, &rdc321x_gpio_dev->data_reg[1]); if (err) - goto out_free; + return err; dev_info(&pdev->dev, "registering %d GPIOs\n", rdc321x_gpio_dev->chip.ngpio); return gpiochip_add(&rdc321x_gpio_dev->chip); - -out_free: - kfree(rdc321x_gpio_dev); - return err; } static int rdc321x_gpio_remove(struct platform_device *pdev) @@ -213,8 +208,6 @@ static int rdc321x_gpio_remove(struct platform_device *pdev) if (ret) dev_err(&pdev->dev, "failed to unregister chip\n"); - kfree(rdc321x_gpio_dev); - return ret; } -- cgit v1.2.3 From 1333b90f33623cdc4028a3523bc186330573990a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 23 Apr 2014 16:45:12 +0200 Subject: gpio: do not set up hardware for IRQ_TYPE_NONE Some GPIO irqchip drivers exploit the irqdomain mapping function to set up the IRQ default type in the hardware, make sure that if we pass IRQ_TYPE_NONE, no hardware setup whatsoever takes place (this should be the norm) until later when the IRQ gets utilized. Cc: Ezequiel Garcia Cc: Santosh Shilimkar Cc: linux-omap Tested-by: Peter Ujfalusi Tested-by: Javier Martinez Canillas Tested-by: Nishanth Menon Acked-by: Nishanth Menon Tested-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ee1819fdcf35..97d173e9aa2d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1409,7 +1409,12 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, #else irq_set_noprobe(irq); #endif - irq_set_irq_type(irq, chip->irq_default_type); + /* + * No set-up of the hardware will happen if IRQ_TYPE_NONE + * is passed as default type. + */ + if (chip->irq_default_type != IRQ_TYPE_NONE) + irq_set_irq_type(irq, chip->irq_default_type); return 0; } @@ -1490,7 +1495,8 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) * @first_irq: if not dynamically assigned, the base (first) IRQ to * allocate gpiochip irqs from * @handler: the irq handler to use (often a predefined irq core function) - * @type: the default type for IRQs on this irqchip + * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE + * to have the core avoid setting up any default type in the hardware. * * This function closely associates a certain irqchip with a certain * gpiochip, providing an irq domain to translate the local IRQs to -- cgit v1.2.3 From 47a95fe71662fa38ff3abe9956f1ca1451fa6e70 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 23 Apr 2014 17:28:08 +0200 Subject: gpio: of: Remove unneeded dummy function of_find_gpio() is always called under an IS_ENABLED(CONFIG_OF), so the dummy implementation provided for !OF configurations is not needed. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 97d173e9aa2d..51c09534676b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2596,7 +2596,6 @@ void gpiod_add_lookup_table(struct gpiod_lookup_table *table) mutex_unlock(&gpio_lookup_lock); } -#ifdef CONFIG_OF static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) @@ -2621,14 +2620,6 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, return desc; } -#else -static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, - unsigned int idx, - enum gpio_lookup_flags *flags) -{ - return ERR_PTR(-ENODEV); -} -#endif static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, -- cgit v1.2.3 From 9370084e685666fe33e9d62707433fa112446b03 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Thu, 24 Apr 2014 08:57:39 +0200 Subject: gpio: omap: implement get_direction This patch implements gpio_chip's get_direction() routine, that lets other drivers get particular GPIOs direction using struct gpio_desc. Signed-off-by: Yegor Yefremov Acked-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Tested-by: Tony Lindgren Reviewed-by: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 8cc9e91e7e4e..47c6056fe850 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define OFF_MODE 1 @@ -927,6 +928,21 @@ static inline void mpuio_init(struct gpio_bank *bank) /*---------------------------------------------------------------------*/ +static int gpio_get_direction(struct gpio_chip *chip, unsigned offset) +{ + struct gpio_bank *bank; + unsigned long flags; + void __iomem *reg; + int dir; + + bank = container_of(chip, struct gpio_bank, chip); + reg = bank->base + bank->regs->direction; + spin_lock_irqsave(&bank->lock, flags); + dir = !!(readl_relaxed(reg) & BIT(offset)); + spin_unlock_irqrestore(&bank->lock, flags); + return dir; +} + static int gpio_input(struct gpio_chip *chip, unsigned offset) { struct gpio_bank *bank; @@ -1085,6 +1101,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank) */ bank->chip.request = omap_gpio_request; bank->chip.free = omap_gpio_free; + bank->chip.get_direction = gpio_get_direction; bank->chip.direction_input = gpio_input; bank->chip.get = gpio_get; bank->chip.direction_output = gpio_output; -- cgit v1.2.3 From dd34c37aa3e81715a1ed8da61fa438072428e188 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 23 Apr 2014 17:28:09 +0200 Subject: gpio: of: Allow -gpio suffix for property names Many bindings use the -gpio suffix in property names. Support this in addition to the -gpios suffix when requesting GPIOs using the new descriptor-based API. Signed-off-by: Thierry Reding Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 51c09534676b..86eb0467fc5a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2600,17 +2600,23 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { + static const char *suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ enum of_gpio_flags of_flags; struct gpio_desc *desc; + unsigned int i; - if (con_id) - snprintf(prop_name, 32, "%s-gpios", con_id); - else - snprintf(prop_name, 32, "gpios"); + for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + if (con_id) + snprintf(prop_name, 32, "%s-%s", con_id, suffixes[i]); + else + snprintf(prop_name, 32, "%s", suffixes[i]); - desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx, - &of_flags); + desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx, + &of_flags); + if (!IS_ERR(desc)) + break; + } if (IS_ERR(desc)) return desc; -- cgit v1.2.3 From 0879162f33bf8a2fe637a22bb77d20233f486ac4 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 25 Apr 2014 16:54:22 +0200 Subject: gpio: Fix gpio_get -> gpiod_get typo in kernel-doc The function is called gpiod_get(), not gpio_get(). Fix the kernel-doc comment to match the name. Signed-off-by: Thierry Reding Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 86eb0467fc5a..4ad110e793c5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2723,7 +2723,7 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, } /** - * gpio_get - obtain a GPIO for a given GPIO function + * gpiod_get - obtain a GPIO for a given GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs * @con_id: function within the GPIO consumer * -- cgit v1.2.3 From 5f077644b95229ab3b27ee422e2b702d5e89653d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Apr 2014 02:00:47 +0200 Subject: gpio: em: use BIT() macro instead of shifting bits Using the BIT() macro instead of shifting bits makes the code less error prone and also more readable. Signed-off-by: Javier Martinez Canillas Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 8765bd6f48e1..1da1aa418d7e 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -212,7 +212,7 @@ static void __em_gio_set(struct gpio_chip *chip, unsigned int reg, { /* upper 16 bits contains mask and lower 16 actual value */ em_gio_write(gpio_to_priv(chip), reg, - (1 << (shift + 16)) | (value << shift)); + (BIT(shift + 16)) | (value << shift)); } static void em_gio_set(struct gpio_chip *chip, unsigned offset, int value) -- cgit v1.2.3 From 459b81808f76f4a0e902e4988200373a627a57a8 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Apr 2014 02:00:48 +0200 Subject: gpio: kempld: use BIT() macro instead of shifting bits Using the BIT() macro instead of shifting bits makes the code less error prone and also more readable. Signed-off-by: Javier Martinez Canillas Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-kempld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-kempld.c b/drivers/gpio/gpio-kempld.c index ebe102325569..1e5e51987d31 100644 --- a/drivers/gpio/gpio-kempld.c +++ b/drivers/gpio/gpio-kempld.c @@ -24,7 +24,7 @@ #include #define KEMPLD_GPIO_MAX_NUM 16 -#define KEMPLD_GPIO_MASK(x) (1 << ((x) % 8)) +#define KEMPLD_GPIO_MASK(x) (BIT((x) % 8)) #define KEMPLD_GPIO_DIR_NUM(x) (0x40 + (x) / 8) #define KEMPLD_GPIO_LVL_NUM(x) (0x42 + (x) / 8) #define KEMPLD_GPIO_EVT_LVL_EDGE 0x46 -- cgit v1.2.3 From b1e9fec2b8690b153b0b9ebbe9dfe6a246d55e4a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Apr 2014 02:00:49 +0200 Subject: gpio: omap: use BIT() macro instead of shifting bits Using the BIT() macro instead of shifting bits makes the code less error prone and also more readable. Signed-off-by: Javier Martinez Canillas Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 47c6056fe850..01d50a090d87 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -83,11 +83,11 @@ struct gpio_bank { }; #define GPIO_INDEX(bank, gpio) (gpio % bank->width) -#define GPIO_BIT(bank, gpio) (1 << GPIO_INDEX(bank, gpio)) +#define GPIO_BIT(bank, gpio) (BIT(GPIO_INDEX(bank, gpio))) #define GPIO_MOD_CTRL_BIT BIT(0) #define BANK_USED(bank) (bank->mod_usage || bank->irq_usage) -#define LINE_USED(line, offset) (line & (1 << offset)) +#define LINE_USED(line, offset) (line & (BIT(offset))) static int irq_to_gpio(struct gpio_bank *bank, unsigned int gpio_irq) { @@ -108,9 +108,9 @@ static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input) reg += bank->regs->direction; l = readl_relaxed(reg); if (is_input) - l |= 1 << gpio; + l |= BIT(gpio); else - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); writel_relaxed(l, reg); bank->context.oe = l; } @@ -153,14 +153,14 @@ static int _get_gpio_datain(struct gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->datain; - return (readl_relaxed(reg) & (1 << offset)) != 0; + return (readl_relaxed(reg) & (BIT(offset))) != 0; } static int _get_gpio_dataout(struct gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->dataout; - return (readl_relaxed(reg) & (1 << offset)) != 0; + return (readl_relaxed(reg) & (BIT(offset))) != 0; } static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) @@ -297,7 +297,7 @@ static inline void set_gpio_trigger(struct gpio_bank *bank, int gpio, unsigned trigger) { void __iomem *base = bank->base; - u32 gpio_bit = 1 << gpio; + u32 gpio_bit = BIT(gpio); _gpio_rmw(base, bank->regs->leveldetect0, gpio_bit, trigger & IRQ_TYPE_LEVEL_LOW); @@ -366,9 +366,9 @@ static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) l = readl_relaxed(reg); if ((l >> gpio) & 1) - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); else - l |= 1 << gpio; + l |= BIT(gpio); writel_relaxed(l, reg); } @@ -390,11 +390,11 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, l = readl_relaxed(reg); if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) - bank->toggle_mask |= 1 << gpio; + bank->toggle_mask |= BIT(gpio); if (trigger & IRQ_TYPE_EDGE_RISING) - l |= 1 << gpio; + l |= BIT(gpio); else if (trigger & IRQ_TYPE_EDGE_FALLING) - l &= ~(1 << gpio); + l &= ~(BIT(gpio)); else return -EINVAL; @@ -411,10 +411,10 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, if (trigger & IRQ_TYPE_EDGE_RISING) l |= 2 << (gpio << 1); if (trigger & IRQ_TYPE_EDGE_FALLING) - l |= 1 << (gpio << 1); + l |= BIT(gpio << 1); /* Enable wake-up during idle for dynamic tick */ - _gpio_rmw(base, bank->regs->wkup_en, 1 << gpio, trigger); + _gpio_rmw(base, bank->regs->wkup_en, BIT(gpio), trigger); bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); writel_relaxed(l, reg); @@ -428,7 +428,7 @@ static void _enable_gpio_module(struct gpio_bank *bank, unsigned offset) void __iomem *reg = bank->base + bank->regs->pinctrl; /* Claim the pin for MPU */ - writel_relaxed(readl_relaxed(reg) | (1 << offset), reg); + writel_relaxed(readl_relaxed(reg) | (BIT(offset)), reg); } if (bank->regs->ctrl && !BANK_USED(bank)) { @@ -451,7 +451,7 @@ static void _disable_gpio_module(struct gpio_bank *bank, unsigned offset) !LINE_USED(bank->mod_usage, offset) && !LINE_USED(bank->irq_usage, offset)) { /* Disable wake-up during idle for dynamic tick */ - _gpio_rmw(base, bank->regs->wkup_en, 1 << offset, 0); + _gpio_rmw(base, bank->regs->wkup_en, BIT(offset), 0); bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); } @@ -507,12 +507,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type) if (!LINE_USED(bank->mod_usage, offset)) { _enable_gpio_module(bank, offset); _set_gpio_direction(bank, offset, 1); - } else if (!gpio_is_input(bank, 1 << offset)) { + } else if (!gpio_is_input(bank, BIT(offset))) { spin_unlock_irqrestore(&bank->lock, flags); return -EINVAL; } - bank->irq_usage |= 1 << GPIO_INDEX(bank, gpio); + bank->irq_usage |= BIT(GPIO_INDEX(bank, gpio)); spin_unlock_irqrestore(&bank->lock, flags); if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) @@ -549,7 +549,7 @@ static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank) { void __iomem *reg = bank->base; u32 l; - u32 mask = (1 << bank->width) - 1; + u32 mask = (BIT(bank->width)) - 1; reg += bank->regs->irqenable; l = readl_relaxed(reg); @@ -681,7 +681,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) _set_gpio_triggering(bank, offset, IRQ_TYPE_NONE); _enable_gpio_module(bank, offset); } - bank->mod_usage |= 1 << offset; + bank->mod_usage |= BIT(offset); spin_unlock_irqrestore(&bank->lock, flags); return 0; @@ -693,7 +693,7 @@ static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) unsigned long flags; spin_lock_irqsave(&bank->lock, flags); - bank->mod_usage &= ~(1 << offset); + bank->mod_usage &= ~(BIT(offset)); _disable_gpio_module(bank, offset); _reset_gpio(bank, bank->chip.base + offset); spin_unlock_irqrestore(&bank->lock, flags); @@ -763,7 +763,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) while (isr) { bit = __ffs(isr); - isr &= ~(1 << bit); + isr &= ~(BIT(bit)); /* * Some chips can't respond to both rising and falling @@ -772,7 +772,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) * to respond to the IRQ for the opposite direction. * This will be indicated in the bank toggle_mask. */ - if (bank->toggle_mask & (1 << bit)) + if (bank->toggle_mask & (BIT(bit))) _toggle_gpio_edge_triggering(bank, bit); generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, @@ -798,7 +798,7 @@ static void gpio_irq_shutdown(struct irq_data *d) spin_lock_irqsave(&bank->lock, flags); gpio_unlock_as_irq(&bank->chip, offset); - bank->irq_usage &= ~(1 << offset); + bank->irq_usage &= ~(BIT(offset)); _disable_gpio_module(bank, offset); _reset_gpio(bank, gpio); spin_unlock_irqrestore(&bank->lock, flags); @@ -961,7 +961,7 @@ static int gpio_get(struct gpio_chip *chip, unsigned offset) u32 mask; bank = container_of(chip, struct gpio_bank, chip); - mask = (1 << offset); + mask = (BIT(offset)); if (gpio_is_input(bank, mask)) return _get_gpio_datain(bank, offset); -- cgit v1.2.3 From bea415041c28907d721f0647b3b80f613f0c4d37 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sun, 27 Apr 2014 02:00:50 +0200 Subject: gpio: pl061: use BIT() macro instead of shifting bits Using the BIT() macro instead of shifting bits makes the code less error prone and also more readable. Signed-off-by: Javier Martinez Canillas Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pl061.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 84553d35bdfa..84b49cfb81a8 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -87,7 +87,7 @@ static int pl061_direction_input(struct gpio_chip *gc, unsigned offset) spin_lock_irqsave(&chip->lock, flags); gpiodir = readb(chip->base + GPIODIR); - gpiodir &= ~(1 << offset); + gpiodir &= ~(BIT(offset)); writeb(gpiodir, chip->base + GPIODIR); spin_unlock_irqrestore(&chip->lock, flags); @@ -105,16 +105,16 @@ static int pl061_direction_output(struct gpio_chip *gc, unsigned offset, return -EINVAL; spin_lock_irqsave(&chip->lock, flags); - writeb(!!value << offset, chip->base + (1 << (offset + 2))); + writeb(!!value << offset, chip->base + (BIT(offset + 2))); gpiodir = readb(chip->base + GPIODIR); - gpiodir |= 1 << offset; + gpiodir |= BIT(offset); writeb(gpiodir, chip->base + GPIODIR); /* * gpio value is set again, because pl061 doesn't allow to set value of * a gpio pin before configuring it in OUT mode. */ - writeb(!!value << offset, chip->base + (1 << (offset + 2))); + writeb(!!value << offset, chip->base + (BIT(offset + 2))); spin_unlock_irqrestore(&chip->lock, flags); return 0; @@ -124,14 +124,14 @@ static int pl061_get_value(struct gpio_chip *gc, unsigned offset) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - return !!readb(chip->base + (1 << (offset + 2))); + return !!readb(chip->base + (BIT(offset + 2))); } static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value) { struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - writeb(!!value << offset, chip->base + (1 << (offset + 2))); + writeb(!!value << offset, chip->base + (BIT(offset + 2))); } static int pl061_irq_type(struct irq_data *d, unsigned trigger) @@ -206,7 +206,7 @@ static void pl061_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); + u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); u8 gpioie; spin_lock(&chip->lock); @@ -219,7 +219,7 @@ static void pl061_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc); - u8 mask = 1 << (irqd_to_hwirq(d) % PL061_GPIO_NR); + u8 mask = BIT(irqd_to_hwirq(d) % PL061_GPIO_NR); u8 gpioie; spin_lock(&chip->lock); @@ -301,9 +301,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id) for (i = 0; i < PL061_GPIO_NR; i++) { if (pdata) { - if (pdata->directions & (1 << i)) + if (pdata->directions & (BIT(i))) pl061_direction_output(&chip->gc, i, - pdata->values & (1 << i)); + pdata->values & (BIT(i))); else pl061_direction_input(&chip->gc, i); } @@ -330,7 +330,7 @@ static int pl061_suspend(struct device *dev) chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE); for (offset = 0; offset < PL061_GPIO_NR; offset++) { - if (chip->csave_regs.gpio_dir & (1 << offset)) + if (chip->csave_regs.gpio_dir & (BIT(offset))) chip->csave_regs.gpio_data |= pl061_get_value(&chip->gc, offset) << offset; } @@ -344,10 +344,10 @@ static int pl061_resume(struct device *dev) int offset; for (offset = 0; offset < PL061_GPIO_NR; offset++) { - if (chip->csave_regs.gpio_dir & (1 << offset)) + if (chip->csave_regs.gpio_dir & (BIT(offset))) pl061_direction_output(&chip->gc, offset, chip->csave_regs.gpio_data & - (1 << offset)); + (BIT(offset))); else pl061_direction_input(&chip->gc, offset); } -- cgit v1.2.3 From 9d5d96ef2c3cb6da6eec7dd9d107ea63781368a0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 28 Apr 2014 11:07:03 +0200 Subject: gpio: always enable GPIO_OMAP on ARCH_OMAP Commit 4df42de9d3e "gpio: omap: add a GPIO_OMAP option instead of using ARCH_OMAP" made it possible to build OMAP kernels without the GPIO driver, which at least on OMAP2 and OMAP3 causes build errors because of functions used by the platform power management code: arch/arm/mach-omap2/built-in.o: In function `omap_sram_idle': arch/arm/mach-omap2/pm24xx.c:129: undefined reference to `omap2_gpio_prepare_for_idle' arch/arm/mach-omap2/pm24xx.c:129: undefined reference to `omap2_gpio_resume_after_idle' We presumably always want the GPIO driver on OMAP, so this adds a slightly broader dependency and only allows disabling the driver only when no OMAP2PLUS platform is selected. However, it seems entirely reasonable to include the driver in build tests on other platforms, so we should also allow building it for COMPILE_TEST builds and select the required GENERIC_IRQ_CHIP that may not already be enabled on other platforms. Signed-off-by: Arnd Bergmann Acked-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c58b828e882f..664df4d08459 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -244,9 +244,10 @@ config GPIO_OCTEON family of SOCs. config GPIO_OMAP - bool "TI OMAP GPIO support" + bool "TI OMAP GPIO support" if COMPILE_TEST && !ARCH_OMAP2PLUS default y if ARCH_OMAP - depends on ARM && ARCH_OMAP + depends on ARM + select GENERIC_IRQ_CHIP select GPIOLIB_IRQCHIP help Say yes here to enable GPIO support for TI OMAP SoCs. -- cgit v1.2.3 From e8a71aaa88c1c47c4fd91e75a329888e75dcc3c3 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:31:31 +0900 Subject: gpio: adp5520: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-adp5520.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-adp5520.c b/drivers/gpio/gpio-adp5520.c index 613265944e2e..f1ade8fa3218 100644 --- a/drivers/gpio/gpio-adp5520.c +++ b/drivers/gpio/gpio-adp5520.c @@ -106,10 +106,8 @@ static int adp5520_gpio_probe(struct platform_device *pdev) } dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&pdev->dev, "failed to alloc memory\n"); + if (dev == NULL) return -ENOMEM; - } dev->master = pdev->dev.parent; -- cgit v1.2.3 From 1a25908d79dfe3cbfe5d45eaec3797d4e6c3c19a Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:32:01 +0900 Subject: gpio: adp5588: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-adp5588.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-adp5588.c b/drivers/gpio/gpio-adp5588.c index d974020b78bb..ef19bc33f2bd 100644 --- a/drivers/gpio/gpio-adp5588.c +++ b/drivers/gpio/gpio-adp5588.c @@ -379,10 +379,8 @@ static int adp5588_gpio_probe(struct i2c_client *client, } dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - dev_err(&client->dev, "failed to alloc memory\n"); + if (dev == NULL) return -ENOMEM; - } dev->client = client; -- cgit v1.2.3 From 9ea9363c1b012cba2c4a123b34eec8a3007c6140 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:33:26 +0900 Subject: gpio: davinci: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-davinci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index 339f9dac591b..9f0682534e2f 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -230,10 +230,8 @@ static int davinci_gpio_probe(struct platform_device *pdev) chips = devm_kzalloc(dev, ngpio * sizeof(struct davinci_gpio_controller), GFP_KERNEL); - if (!chips) { - dev_err(dev, "Memory allocation failed\n"); + if (!chips) return -ENOMEM; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { -- cgit v1.2.3 From d4c4f883388c8279d36457a28bc8a28e94dff2d8 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:34:04 +0900 Subject: gpio: em: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-em.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 1da1aa418d7e..cde36054c387 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c @@ -284,7 +284,6 @@ static int em_gio_probe(struct platform_device *pdev) p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); if (!p) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); ret = -ENOMEM; goto err0; } -- cgit v1.2.3 From 4920c4aa2d551c0e6b3a56280ba08dafef59d8b1 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:35:07 +0900 Subject: gpio: janz-ttl: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-janz-ttl.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 2ecd3a09c743..255806bcbfe5 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -158,7 +158,6 @@ static int ttl_probe(struct platform_device *pdev) mod = kzalloc(sizeof(*mod), GFP_KERNEL); if (!mod) { - dev_err(dev, "unable to allocate private data\n"); ret = -ENOMEM; goto out_return; } -- cgit v1.2.3 From 1981d0844d62bef533deab531f3f7e176195c2bf Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:36:26 +0900 Subject: gpio: lynxpoint: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-lynxpoint.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index 9a82a9074a2c..2bea89b72508 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -375,10 +375,8 @@ static int lp_gpio_probe(struct platform_device *pdev) int ret = -ENODEV; lg = devm_kzalloc(dev, sizeof(struct lp_gpio), GFP_KERNEL); - if (!lg) { - dev_err(dev, "can't allocate lp_gpio chip data\n"); + if (!lg) return -ENOMEM; - } lg->pdev = pdev; platform_set_drvdata(pdev, lg); -- cgit v1.2.3 From 40b295fa7a344d42d7ddaac6a3dbc035aa7f3c42 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:37:09 +0900 Subject: gpio: moxart: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-moxart.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-moxart.c b/drivers/gpio/gpio-moxart.c index ccd45704e5fd..4661e181be04 100644 --- a/drivers/gpio/gpio-moxart.c +++ b/drivers/gpio/gpio-moxart.c @@ -113,10 +113,8 @@ static int moxart_gpio_probe(struct platform_device *pdev) int ret; mgc = devm_kzalloc(dev, sizeof(*mgc), GFP_KERNEL); - if (!mgc) { - dev_err(dev, "can't allocate GPIO chip container\n"); + if (!mgc) return -ENOMEM; - } mgc->gpio = moxart_template_chip; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- cgit v1.2.3 From 6c8365f68ab38bfac58a53cbd244c04da0d76a73 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:38:21 +0900 Subject: gpio: mvebu: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Jason Cooper Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index d42509422394..4d398ff83ad0 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -574,10 +574,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev) soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION; mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip), GFP_KERNEL); - if (!mvchip) { - dev_err(&pdev->dev, "Cannot allocate memory\n"); + if (!mvchip) return -ENOMEM; - } if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) { dev_err(&pdev->dev, "Missing ngpios OF property\n"); -- cgit v1.2.3 From 5605beb29b454a0aac59fb1e3d903080ee60cb49 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:39:07 +0900 Subject: gpio: palmas: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-palmas.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index da9d33252e56..a5ec6022e789 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c @@ -173,10 +173,8 @@ static int palmas_gpio_probe(struct platform_device *pdev) palmas_gpio = devm_kzalloc(&pdev->dev, sizeof(*palmas_gpio), GFP_KERNEL); - if (!palmas_gpio) { - dev_err(&pdev->dev, "Could not allocate palmas_gpio\n"); + if (!palmas_gpio) return -ENOMEM; - } palmas_gpio->palmas = palmas; palmas_gpio->gpio_chip.owner = THIS_MODULE; -- cgit v1.2.3 From 4b7dfd7f6f1ac7898cd2c0fa9b490e35b2f4beac Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:39:42 +0900 Subject: gpio: rc5t583: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rc5t583.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rc5t583.c b/drivers/gpio/gpio-rc5t583.c index 9b423173ab50..562b0c4d9cc8 100644 --- a/drivers/gpio/gpio-rc5t583.c +++ b/drivers/gpio/gpio-rc5t583.c @@ -119,10 +119,8 @@ static int rc5t583_gpio_probe(struct platform_device *pdev) rc5t583_gpio = devm_kzalloc(&pdev->dev, sizeof(*rc5t583_gpio), GFP_KERNEL); - if (!rc5t583_gpio) { - dev_warn(&pdev->dev, "Mem allocation for rc5t583_gpio failed"); + if (!rc5t583_gpio) return -ENOMEM; - } rc5t583_gpio->gpio_chip.label = "gpio-rc5t583", rc5t583_gpio->gpio_chip.owner = THIS_MODULE, -- cgit v1.2.3 From 41893360afb9d49181ce9714286de61ee50c48b0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:40:59 +0900 Subject: gpio: rcar: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Laurent Pinchart Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rcar.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index bfcfeeefcf78..0c9f803fc1ac 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -363,7 +363,6 @@ static int gpio_rcar_probe(struct platform_device *pdev) p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); if (!p) { - dev_err(dev, "failed to allocate driver data\n"); ret = -ENOMEM; goto err0; } -- cgit v1.2.3 From 84e27f97ea46de21a78ffeb230a5a0de83f664f3 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:42:04 +0900 Subject: gpio: rdc321x: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-rdc321x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-rdc321x.c b/drivers/gpio/gpio-rdc321x.c index 7a319e5138a5..9fa7e53331c9 100644 --- a/drivers/gpio/gpio-rdc321x.c +++ b/drivers/gpio/gpio-rdc321x.c @@ -143,10 +143,8 @@ static int rdc321x_gpio_probe(struct platform_device *pdev) rdc321x_gpio_dev = devm_kzalloc(&pdev->dev, sizeof(struct rdc321x_gpio), GFP_KERNEL); - if (!rdc321x_gpio_dev) { - dev_err(&pdev->dev, "failed to allocate private data\n"); + if (!rdc321x_gpio_dev) return -ENOMEM; - } r = platform_get_resource_byname(pdev, IORESOURCE_IO, "gpio-reg1"); if (!r) { -- cgit v1.2.3 From 48b9750cdb62ed93c9a1a934bb2c59c371850d08 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:42:56 +0900 Subject: gpio: SPEAr: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Viresh Kumar Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-spear-spics.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c index 30bcc539425d..353263c85d26 100644 --- a/drivers/gpio/gpio-spear-spics.c +++ b/drivers/gpio/gpio-spear-spics.c @@ -129,10 +129,8 @@ static int spics_gpio_probe(struct platform_device *pdev) int ret; spics = devm_kzalloc(&pdev->dev, sizeof(*spics), GFP_KERNEL); - if (!spics) { - dev_err(&pdev->dev, "memory allocation fail\n"); + if (!spics) return -ENOMEM; - } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); spics->base = devm_ioremap_resource(&pdev->dev, res); -- cgit v1.2.3 From c88a73b37fc9781347f6d7ca9134d84a1475d7f6 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:44:14 +0900 Subject: gpio: tegra: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index 2b49f878b56c..c6bdc2ed2445 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -458,10 +458,8 @@ static int tegra_gpio_probe(struct platform_device *pdev) tegra_gpio_banks = devm_kzalloc(&pdev->dev, tegra_gpio_bank_count * sizeof(*tegra_gpio_banks), GFP_KERNEL); - if (!tegra_gpio_banks) { - dev_err(&pdev->dev, "Couldn't allocate bank structure\n"); + if (!tegra_gpio_banks) return -ENODEV; - } irq_domain = irq_domain_add_linear(pdev->dev.of_node, tegra_gpio_chip.ngpio, -- cgit v1.2.3 From e1ccdb823e108320b2c8bc6ea94884bd06397b75 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:44:48 +0900 Subject: gpio: tps6586x: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tps6586x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tps6586x.c b/drivers/gpio/gpio-tps6586x.c index 8994dfa13491..a69fbea41253 100644 --- a/drivers/gpio/gpio-tps6586x.c +++ b/drivers/gpio/gpio-tps6586x.c @@ -97,10 +97,8 @@ static int tps6586x_gpio_probe(struct platform_device *pdev) pdata = dev_get_platdata(pdev->dev.parent); tps6586x_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps6586x_gpio), GFP_KERNEL); - if (!tps6586x_gpio) { - dev_err(&pdev->dev, "Could not allocate tps6586x_gpio\n"); + if (!tps6586x_gpio) return -ENOMEM; - } tps6586x_gpio->parent = pdev->dev.parent; -- cgit v1.2.3 From 0661175a2ae7f83a3d8963e36ca4cbffc6a686d0 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:45:46 +0900 Subject: gpio: tps65910: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tps65910.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index b6e818e68007..e2f8cda235ea 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -123,10 +123,8 @@ static int tps65910_gpio_probe(struct platform_device *pdev) tps65910_gpio = devm_kzalloc(&pdev->dev, sizeof(*tps65910_gpio), GFP_KERNEL); - if (!tps65910_gpio) { - dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n"); + if (!tps65910_gpio) return -ENOMEM; - } tps65910_gpio->tps65910 = tps65910; -- cgit v1.2.3 From 50908d61ea483e0670768a712c166c3e4b2a30a3 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 29 Apr 2014 17:46:22 +0900 Subject: gpio: zevio: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Reviewed-by: Javier Martinez Canillas Signed-off-by: Linus Walleij --- drivers/gpio/gpio-zevio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 6270f755d0ed..4c173ad4c23c 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -178,10 +178,8 @@ static int zevio_gpio_probe(struct platform_device *pdev) int status, i; controller = devm_kzalloc(&pdev->dev, sizeof(*controller), GFP_KERNEL); - if (!controller) { - dev_err(&pdev->dev, "not enough free memory\n"); + if (!controller) return -ENOMEM; - } /* Copy our reference */ controller->chip.gc = zevio_gpio_chip; -- cgit v1.2.3 From f77b644859599ec77220b9c4d061ed71d2751107 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:03:30 +0900 Subject: gpio: grgpio: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Acked-by: Andreas Larsson Signed-off-by: Linus Walleij --- drivers/gpio/gpio-grgpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-grgpio.c b/drivers/gpio/gpio-grgpio.c index 84d2478ec294..3c3f515b7916 100644 --- a/drivers/gpio/gpio-grgpio.c +++ b/drivers/gpio/gpio-grgpio.c @@ -481,7 +481,7 @@ out: return ret; } -static struct of_device_id grgpio_match[] = { +static const struct of_device_id grgpio_match[] = { {.name = "GAISLER_GPIO"}, {.name = "01_01a"}, {}, -- cgit v1.2.3 From ac791804ac8133a89e998872fefaa33717f9aeba Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:05:17 +0900 Subject: gpio: mcp23s08: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 99a68310e7c0..d7f384f9cde0 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -714,7 +714,7 @@ fail: #ifdef CONFIG_OF #ifdef CONFIG_SPI_MASTER -static struct of_device_id mcp23s08_spi_of_match[] = { +static const struct of_device_id mcp23s08_spi_of_match[] = { { .compatible = "microchip,mcp23s08", .data = (void *) MCP_TYPE_S08, @@ -738,7 +738,7 @@ MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match); #endif #if IS_ENABLED(CONFIG_I2C) -static struct of_device_id mcp23s08_i2c_of_match[] = { +static const struct of_device_id mcp23s08_i2c_of_match[] = { { .compatible = "microchip,mcp23008", .data = (void *) MCP_TYPE_008, -- cgit v1.2.3 From 271b17b69adcf813e3f7cfa8db5f3eaa7fb81cce Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:06:08 +0900 Subject: gpio: mvebu: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 4d398ff83ad0..8018d308226a 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -535,7 +535,7 @@ static void mvebu_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) #define mvebu_gpio_dbg_show NULL #endif -static struct of_device_id mvebu_gpio_of_match[] = { +static const struct of_device_id mvebu_gpio_of_match[] = { { .compatible = "marvell,orion-gpio", .data = (void *) MVEBU_GPIO_SOC_VARIANT_ORION, -- cgit v1.2.3 From 722782fee83b716bc1e162311f8f486aeb4edc45 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:06:50 +0900 Subject: gpio: palmas: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-palmas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-palmas.c b/drivers/gpio/gpio-palmas.c index a5ec6022e789..86bdbe362068 100644 --- a/drivers/gpio/gpio-palmas.c +++ b/drivers/gpio/gpio-palmas.c @@ -148,7 +148,7 @@ static const struct palmas_device_data tps80036_dev_data = { .ngpio = 16, }; -static struct of_device_id of_palmas_gpio_match[] = { +static const struct of_device_id of_palmas_gpio_match[] = { { .compatible = "ti,palmas-gpio", .data = &palmas_dev_data,}, { .compatible = "ti,tps65913-gpio", .data = &palmas_dev_data,}, { .compatible = "ti,tps65914-gpio", .data = &palmas_dev_data,}, -- cgit v1.2.3 From 30373b639aa46d9f28f6b030cab9c0a54b9705d5 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:07:42 +0900 Subject: gpio: tegra: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index c6bdc2ed2445..4e8fb8261a87 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -408,7 +408,7 @@ static struct tegra_gpio_soc_config tegra30_gpio_config = { .upper_offset = 0x80, }; -static struct of_device_id tegra_gpio_of_match[] = { +static const struct of_device_id tegra_gpio_of_match[] = { { .compatible = "nvidia,tegra30-gpio", .data = &tegra30_gpio_config }, { .compatible = "nvidia,tegra20-gpio", .data = &tegra20_gpio_config }, { }, -- cgit v1.2.3 From 9992bc95e1dcc4f2395fd5511683eaeb079facf7 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:08:20 +0900 Subject: gpio: xilinx: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Reviewed-by: Michal Simek Signed-off-by: Linus Walleij --- drivers/gpio/gpio-xilinx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-xilinx.c b/drivers/gpio/gpio-xilinx.c index 792a05ad4649..12481867daf1 100644 --- a/drivers/gpio/gpio-xilinx.c +++ b/drivers/gpio/gpio-xilinx.c @@ -289,7 +289,7 @@ static int xgpio_of_probe(struct device_node *np) return 0; } -static struct of_device_id xgpio_of_match[] = { +static const struct of_device_id xgpio_of_match[] = { { .compatible = "xlnx,xps-gpio-1.00.a", }, { /* end of list */ }, }; -- cgit v1.2.3 From a49f2e748de7b163c9e5099edf5f6f9f6fc70dbb Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Wed, 7 May 2014 18:09:01 +0900 Subject: gpio: zevio: Make of_device_id array const Make of_device_id array const, because all OF functions handle it as const. Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-zevio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 4c173ad4c23c..54e54e4cc6c4 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -202,7 +202,7 @@ static int zevio_gpio_probe(struct platform_device *pdev) return 0; } -static struct of_device_id zevio_gpio_of_match[] = { +static const struct of_device_id zevio_gpio_of_match[] = { { .compatible = "lsi,zevio-gpio", }, { }, }; -- cgit v1.2.3 From dd640039e8de4135fd59d4d963487d1239d6fabe Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 24 Apr 2014 17:54:50 -0300 Subject: gpio: mvebu: Remove initcall-based driver initialization There's no reason to use an initcall to initialize this driver, and regular module_platform_driver() can be used instead. Signed-off-by: Ezequiel Garcia Reviewed-by: Javier Martinez Canillas Acked-by: Jason Cooper Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mvebu.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 8018d308226a..418e38650363 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -736,9 +736,4 @@ static struct platform_driver mvebu_gpio_driver = { }, .probe = mvebu_gpio_probe, }; - -static int __init mvebu_gpio_init(void) -{ - return platform_driver_register(&mvebu_gpio_driver); -} -postcore_initcall(mvebu_gpio_init); +module_platform_driver(mvebu_gpio_driver); -- cgit v1.2.3 From 3275d0723a4cfad2199905623202edaa1ecba8c2 Mon Sep 17 00:00:00 2001 From: Toby Smith Date: Wed, 30 Apr 2014 18:01:40 +1000 Subject: gpio: pca953x: return IRQ_NONE when appropriate The irq handler should return IRQ_NONE or IRQ_HANDLED to report if we have handled the interrupt. Signed-off-by: Toby Smith Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index d550d8e58705..83cc2c8f105f 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -503,10 +503,11 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) struct pca953x_chip *chip = devid; u8 pending[MAX_BANK]; u8 level; + unsigned nhandled = 0; int i; if (!pca953x_irq_pending(chip, pending)) - return IRQ_HANDLED; + return IRQ_NONE; for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { @@ -514,10 +515,11 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) handle_nested_irq(irq_find_mapping(chip->domain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); + nhandled++; } } - return IRQ_HANDLED; + return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; } static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, -- cgit v1.2.3 From 91329132c909bbeb27699556b98b7f745ddb2ed9 Mon Sep 17 00:00:00 2001 From: Toby Smith Date: Wed, 30 Apr 2014 18:01:41 +1000 Subject: gpio: pca953x: request a shared interrupt Request a shared interrupt when requesting a pca953x GPIO interrupt Signed-off-by: Toby Smith Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pca953x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 83cc2c8f105f..6398f8a0f40c 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -586,7 +586,8 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, client->irq, NULL, pca953x_irq_handler, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, + IRQF_TRIGGER_LOW | IRQF_ONESHOT | + IRQF_SHARED, dev_name(&client->dev), chip); if (ret) { dev_err(&client->dev, "failed to request irq %d\n", -- cgit v1.2.3 From 29a1f2333e07bbbecb920cc78fd035fe8f53207a Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 25 Apr 2014 17:10:06 +0200 Subject: gpio: Add helpers for optional GPIOs Introduce gpiod_get_optional() and gpiod_get_index_optional() helpers that make it easier for drivers to handle optional GPIOs. Currently in order to handle optional GPIOs, a driver needs to special case error handling for -ENOENT, such as this: gpio = gpiod_get(dev, "foo"); if (IS_ERR(gpio)) { if (PTR_ERR(gpio) != -ENOENT) return PTR_ERR(gpio); gpio = NULL; } if (gpio) { /* set up GPIO */ } With these new helpers the above is reduced to: gpio = gpiod_get_optional(dev, "foo"); if (IS_ERR(gpio)) return PTR_ERR(gpio); if (gpio) { /* set up GPIO */ } While at it, device-managed variants of these functions are also provided. Signed-off-by: Thierry Reding Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/devres.c | 43 +++++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 307464fd015f..65978cf85f79 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -51,6 +51,22 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev, } EXPORT_SYMBOL(devm_gpiod_get); +/** + * devm_gpiod_get_optional - Resource-managed gpiod_get_optional() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * + * Managed gpiod_get_optional(). GPIO descriptors returned from this function + * are automatically disposed on driver detach. See gpiod_get_optional() for + * detailed information about behavior and return values. + */ +struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev, + const char *con_id) +{ + return devm_gpiod_get_index_optional(dev, con_id, 0); +} +EXPORT_SYMBOL(devm_gpiod_get_optional); + /** * devm_gpiod_get_index - Resource-managed gpiod_get_index() * @dev: GPIO consumer @@ -86,6 +102,33 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev, } EXPORT_SYMBOL(devm_gpiod_get_index); +/** + * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional() + * @dev: GPIO consumer + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer + * + * Managed gpiod_get_index_optional(). GPIO descriptors returned from this + * function are automatically disposed on driver detach. See + * gpiod_get_index_optional() for detailed information about behavior and + * return values. + */ +struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev, + const char *con_id, + unsigned int index) +{ + struct gpio_desc *desc; + + desc = devm_gpiod_get_index(dev, con_id, index); + if (IS_ERR(desc)) { + if (PTR_ERR(desc) == -ENOENT) + return NULL; + } + + return desc; +} +EXPORT_SYMBOL(devm_gpiod_get_index_optional); + /** * devm_gpiod_put - Resource-managed gpiod_put() * @desc: GPIO descriptor to dispose of diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4ad110e793c5..d9c9cb4665db 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2737,6 +2737,22 @@ struct gpio_desc *__must_check gpiod_get(struct device *dev, const char *con_id) } EXPORT_SYMBOL_GPL(gpiod_get); +/** + * gpiod_get_optional - obtain an optional GPIO for a given GPIO function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * + * This is equivalent to gpiod_get(), except that when no GPIO was assigned to + * the requested function it will return NULL. This is convenient for drivers + * that need to handle optional GPIOs. + */ +struct gpio_desc *__must_check gpiod_get_optional(struct device *dev, + const char *con_id) +{ + return gpiod_get_index_optional(dev, con_id, 0); +} +EXPORT_SYMBOL_GPL(gpiod_get_optional); + /** * gpiod_get_index - obtain a GPIO from a multi-index GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs @@ -2799,6 +2815,33 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, } EXPORT_SYMBOL_GPL(gpiod_get_index); +/** + * gpiod_get_index_optional - obtain an optional GPIO from a multi-index GPIO + * function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @index: index of the GPIO to obtain in the consumer + * + * This is equivalent to gpiod_get_index(), except that when no GPIO with the + * specified index was assigned to the requested function it will return NULL. + * This is convenient for drivers that need to handle optional GPIOs. + */ +struct gpio_desc *__must_check gpiod_get_index_optional(struct device *dev, + const char *con_id, + unsigned int index) +{ + struct gpio_desc *desc; + + desc = gpiod_get_index(dev, con_id, index); + if (IS_ERR(desc)) { + if (PTR_ERR(desc) == -ENOENT) + return NULL; + } + + return desc; +} +EXPORT_SYMBOL_GPL(gpiod_get_index_optional); + /** * gpiod_put - dispose of a GPIO descriptor * @desc: GPIO descriptor to dispose of -- cgit v1.2.3 From 345477ffe2ed0c53ffbbfeae73f9bca38e827d0d Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Wed, 23 Apr 2014 11:41:03 +0530 Subject: gpio: omap: prepare and unprepare the debounce clock Replace the clk_enable()s with a clk_prepare_enable() and the clk_disables()s with a clk_disable_unprepare() This never showed issues due to the OMAP platform code (hwmod) leaving these clocks in clk_prepare()ed state by default. Reported-by: Kishon Vijay Abraham I Signed-off-by: Rajendra Nayak Acked-by: Javier Martinez Canillas Acked-by: Santosh Shilimkar Cc: Kevin Hilman Signed-off-by: Linus Walleij --- drivers/gpio/gpio-omap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 01d50a090d87..00f29aa1fb9d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -178,7 +178,7 @@ static inline void _gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) static inline void _gpio_dbck_enable(struct gpio_bank *bank) { if (bank->dbck_enable_mask && !bank->dbck_enabled) { - clk_enable(bank->dbck); + clk_prepare_enable(bank->dbck); bank->dbck_enabled = true; writel_relaxed(bank->dbck_enable_mask, @@ -196,7 +196,7 @@ static inline void _gpio_dbck_disable(struct gpio_bank *bank) */ writel_relaxed(0, bank->base + bank->regs->debounce_en); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); bank->dbck_enabled = false; } } @@ -229,7 +229,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, l = GPIO_BIT(bank, gpio); - clk_enable(bank->dbck); + clk_prepare_enable(bank->dbck); reg = bank->base + bank->regs->debounce; writel_relaxed(debounce, reg); @@ -243,7 +243,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, bank->dbck_enable_mask = val; writel_relaxed(val, reg); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); /* * Enable debounce clock per module. * This call is mandatory because in omap_gpio_request() when @@ -288,7 +288,7 @@ static void _clear_gpio_debounce(struct gpio_bank *bank, unsigned gpio) bank->context.debounce = 0; writel_relaxed(bank->context.debounce, bank->base + bank->regs->debounce); - clk_disable(bank->dbck); + clk_disable_unprepare(bank->dbck); bank->dbck_enabled = false; } } -- cgit v1.2.3 From a435e1802b3620c830ee27a3f5cdbf936dac469d Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Mon, 12 May 2014 17:40:42 +0200 Subject: gpio: bt8xx: use devm function for memory allocation Signed-off-by: abdoulaye berthe Signed-off-by: Linus Walleij --- drivers/gpio/gpio-bt8xx.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-bt8xx.c b/drivers/gpio/gpio-bt8xx.c index ecb3ca2d1d10..6557147d9331 100644 --- a/drivers/gpio/gpio-bt8xx.c +++ b/drivers/gpio/gpio-bt8xx.c @@ -178,7 +178,7 @@ static int bt8xxgpio_probe(struct pci_dev *dev, struct bt8xxgpio *bg; int err; - bg = kzalloc(sizeof(*bg), GFP_KERNEL); + bg = devm_kzalloc(&dev->dev, sizeof(struct bt8xxgpio), GFP_KERNEL); if (!bg) return -ENOMEM; @@ -188,9 +188,9 @@ static int bt8xxgpio_probe(struct pci_dev *dev, err = pci_enable_device(dev); if (err) { printk(KERN_ERR "bt8xxgpio: Can't enable device.\n"); - goto err_freebg; + return err; } - if (!request_mem_region(pci_resource_start(dev, 0), + if (!devm_request_mem_region(&dev->dev, pci_resource_start(dev, 0), pci_resource_len(dev, 0), "bt8xxgpio")) { printk(KERN_WARNING "bt8xxgpio: Can't request iomem (0x%llx).\n", @@ -201,11 +201,11 @@ static int bt8xxgpio_probe(struct pci_dev *dev, pci_set_master(dev); pci_set_drvdata(dev, bg); - bg->mmio = ioremap(pci_resource_start(dev, 0), 0x1000); + bg->mmio = devm_ioremap(&dev->dev, pci_resource_start(dev, 0), 0x1000); if (!bg->mmio) { printk(KERN_ERR "bt8xxgpio: ioremap() failed\n"); err = -EIO; - goto err_release_mem; + goto err_disable; } /* Disable interrupts */ @@ -220,18 +220,13 @@ static int bt8xxgpio_probe(struct pci_dev *dev, err = gpiochip_add(&bg->gpio); if (err) { printk(KERN_ERR "bt8xxgpio: Failed to register GPIOs\n"); - goto err_release_mem; + goto err_disable; } return 0; -err_release_mem: - release_mem_region(pci_resource_start(dev, 0), - pci_resource_len(dev, 0)); err_disable: pci_disable_device(dev); -err_freebg: - kfree(bg); return err; } @@ -250,8 +245,6 @@ static void bt8xxgpio_remove(struct pci_dev *pdev) release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); pci_disable_device(pdev); - - kfree(bg); } #ifdef CONFIG_PM -- cgit v1.2.3 From 0ed3398ed8086597ff53d119fa48fa466f2f2754 Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Tue, 13 May 2014 03:21:42 +0200 Subject: gpio: timberdale: use devm functions This eases memory allocation and provides appropriate logging. Signed-off-by: abdoulaye berthe Signed-off-by: Linus Walleij --- drivers/gpio/gpio-timberdale.c | 47 ++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-timberdale.c b/drivers/gpio/gpio-timberdale.c index f9a8fbde108e..efc7c129016d 100644 --- a/drivers/gpio/gpio-timberdale.c +++ b/drivers/gpio/gpio-timberdale.c @@ -224,6 +224,7 @@ static struct irq_chip timbgpio_irqchip = { static int timbgpio_probe(struct platform_device *pdev) { int err, i; + struct device *dev = &pdev->dev; struct gpio_chip *gc; struct timbgpio *tgpio; struct resource *iomem; @@ -231,35 +232,35 @@ static int timbgpio_probe(struct platform_device *pdev) int irq = platform_get_irq(pdev, 0); if (!pdata || pdata->nr_pins > 32) { - err = -EINVAL; - goto err_mem; + dev_err(dev, "Invalid platform data\n"); + return -EINVAL; } iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!iomem) { - err = -EINVAL; - goto err_mem; + dev_err(dev, "Unable to get resource\n"); + return -EINVAL; } - tgpio = kzalloc(sizeof(*tgpio), GFP_KERNEL); + tgpio = devm_kzalloc(dev, sizeof(struct timbgpio), GFP_KERNEL); if (!tgpio) { - err = -EINVAL; - goto err_mem; + dev_err(dev, "Memory alloc failed\n"); + return -EINVAL; } tgpio->irq_base = pdata->irq_base; spin_lock_init(&tgpio->lock); - if (!request_mem_region(iomem->start, resource_size(iomem), - DRIVER_NAME)) { - err = -EBUSY; - goto err_request; + if (!devm_request_mem_region(dev, iomem->start, resource_size(iomem), + DRIVER_NAME)) { + dev_err(dev, "Region already claimed\n"); + return -EBUSY; } - tgpio->membase = ioremap(iomem->start, resource_size(iomem)); + tgpio->membase = devm_ioremap(dev, iomem->start, resource_size(iomem)); if (!tgpio->membase) { - err = -ENOMEM; - goto err_ioremap; + dev_err(dev, "Cannot ioremap\n"); + return -ENOMEM; } gc = &tgpio->gpio; @@ -279,7 +280,7 @@ static int timbgpio_probe(struct platform_device *pdev) err = gpiochip_add(gc); if (err) - goto err_chipadd; + return err; platform_set_drvdata(pdev, tgpio); @@ -302,17 +303,6 @@ static int timbgpio_probe(struct platform_device *pdev) irq_set_chained_handler(irq, timbgpio_irq); return 0; - -err_chipadd: - iounmap(tgpio->membase); -err_ioremap: - release_mem_region(iomem->start, resource_size(iomem)); -err_request: - kfree(tgpio); -err_mem: - printk(KERN_ERR DRIVER_NAME": Failed to register GPIOs: %d\n", err); - - return err; } static int timbgpio_remove(struct platform_device *pdev) @@ -320,7 +310,6 @@ static int timbgpio_remove(struct platform_device *pdev) int err; struct timbgpio_platform_data *pdata = dev_get_platdata(&pdev->dev); struct timbgpio *tgpio = platform_get_drvdata(pdev); - struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq = platform_get_irq(pdev, 0); if (irq >= 0 && tgpio->irq_base > 0) { @@ -338,10 +327,6 @@ static int timbgpio_remove(struct platform_device *pdev) if (err) printk(KERN_ERR DRIVER_NAME": failed to remove gpio_chip\n"); - iounmap(tgpio->membase); - release_mem_region(iomem->start, resource_size(iomem)); - kfree(tgpio); - return 0; } -- cgit v1.2.3 From ae28193e01c8467f448e77234a074bae05b7a66f Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Tue, 13 May 2014 18:42:12 +0200 Subject: gpio: janzttl: use devm function This uses dem function for mem allocation Signed-off-by: abdoulaye berthe Signed-off-by: Linus Walleij --- drivers/gpio/gpio-janz-ttl.c | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-janz-ttl.c b/drivers/gpio/gpio-janz-ttl.c index 255806bcbfe5..42852eaaf020 100644 --- a/drivers/gpio/gpio-janz-ttl.c +++ b/drivers/gpio/gpio-janz-ttl.c @@ -152,33 +152,21 @@ static int ttl_probe(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); if (!pdata) { dev_err(dev, "no platform data\n"); - ret = -ENXIO; - goto out_return; + return -ENXIO; } - mod = kzalloc(sizeof(*mod), GFP_KERNEL); - if (!mod) { - ret = -ENOMEM; - goto out_return; - } + mod = devm_kzalloc(dev, sizeof(*mod), GFP_KERNEL); + if (!mod) + return -ENOMEM; platform_set_drvdata(pdev, mod); spin_lock_init(&mod->lock); /* get access to the MODULbus registers for this module */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(dev, "MODULbus registers not found\n"); - ret = -ENODEV; - goto out_free_mod; - } - - mod->regs = ioremap(res->start, resource_size(res)); - if (!mod->regs) { - dev_err(dev, "MODULbus registers not ioremap\n"); - ret = -ENOMEM; - goto out_free_mod; - } + mod->regs = devm_ioremap_resource(dev, res); + if (IS_ERR(mod->regs)) + return PTR_ERR(mod->regs); ttl_setup_device(mod); @@ -197,17 +185,10 @@ static int ttl_probe(struct platform_device *pdev) ret = gpiochip_add(gpio); if (ret) { dev_err(dev, "unable to add GPIO chip\n"); - goto out_iounmap_regs; + return ret; } return 0; - -out_iounmap_regs: - iounmap(mod->regs); -out_free_mod: - kfree(mod); -out_return: - return ret; } static int ttl_remove(struct platform_device *pdev) @@ -222,8 +203,6 @@ static int ttl_remove(struct platform_device *pdev) return ret; } - iounmap(mod->regs); - kfree(mod); return 0; } -- cgit v1.2.3 From 1aeede0b3c055665fb722a012d3cd834146fc112 Mon Sep 17 00:00:00 2001 From: abdoulaye berthe Date: Wed, 14 May 2014 00:36:54 +0200 Subject: gpio: gpioep93xx: use devm functions This uses devm functions for mem allocation Signed-off-by: abdoulaye berthe Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ep93xx.c | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index 80829f3c6543..dd39f27f3cb2 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -344,37 +344,24 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) { struct ep93xx_gpio *ep93xx_gpio; struct resource *res; - void __iomem *mmio; int i; - int ret; + struct device *dev = &pdev->dev; - ep93xx_gpio = kzalloc(sizeof(*ep93xx_gpio), GFP_KERNEL); + ep93xx_gpio = devm_kzalloc(dev, sizeof(struct ep93xx_gpio), GFP_KERNEL); if (!ep93xx_gpio) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENXIO; - goto exit_free; - } - - if (!request_mem_region(res->start, resource_size(res), pdev->name)) { - ret = -EBUSY; - goto exit_free; - } - - mmio = ioremap(res->start, resource_size(res)); - if (!mmio) { - ret = -ENXIO; - goto exit_release; - } - ep93xx_gpio->mmio_base = mmio; + ep93xx_gpio->mmio_base = devm_request_and_ioremap(dev, res); + if (IS_ERR(ep93xx_gpio->mmio_base)) + return PTR_ERR(ep93xx_gpio->mmio_base); for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++) { struct bgpio_chip *bgc = &ep93xx_gpio->bgc[i]; struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i]; - if (ep93xx_gpio_add_bank(bgc, &pdev->dev, mmio, bank)) + if (ep93xx_gpio_add_bank(bgc, &pdev->dev, + ep93xx_gpio->mmio_base, bank)) dev_warn(&pdev->dev, "Unable to add gpio bank %s\n", bank->label); } @@ -382,13 +369,6 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) ep93xx_gpio_init_irq(); return 0; - -exit_release: - release_mem_region(res->start, resource_size(res)); -exit_free: - kfree(ep93xx_gpio); - dev_info(&pdev->dev, "%s failed with errno %d\n", __func__, ret); - return ret; } static struct platform_driver ep93xx_gpio_driver = { -- cgit v1.2.3 From f01d907582f8461546379aa415a7c6d5cfb8e5fd Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Sat, 17 May 2014 14:54:50 +0900 Subject: gpio: make of_get_named_gpiod_flags() private of_get_named_gpiod_flags() is visible and directly usable by GPIO consumers, but it really should not as the gpiod interface relies on the simpler gpiod_get() to provide properly-configured GPIOs. of_get_named_gpiod_flags() is just used internally by gpiolib to implement gpiod_get(), and by the old of_get_named_gpio_flags() function, therefore it makes sense to make it gpiolib-private. As a side-effect, the unused (and unneeded) of_get_gpiod_flags() inline function is also removed, and of_get_named_gpio_flags() is moved from a static inline function to a regular one in gpiolib-of.c This results in all references to gpiod_* functions in of_gpio.h being gone, which is the way it should be since this file is part of the old integer GPIO interface. Changes since v1: - Fixed compilation error when CONFIG_OF_GPIO is not defined - Fixed warning due to of_gpio_flags enum not being declared in private gpiolib.h header Signed-off-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 14 ++++++++++++++ drivers/gpio/gpiolib.h | 5 +++++ 2 files changed, 19 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index db98d3a12f70..af7e25c9a9ae 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -96,6 +96,20 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, } EXPORT_SYMBOL(of_get_named_gpiod_flags); +int of_get_named_gpio_flags(struct device_node *np, const char *list_name, + int index, enum of_gpio_flags *flags) +{ + struct gpio_desc *desc; + + desc = of_get_named_gpiod_flags(np, list_name, index, flags); + + if (IS_ERR(desc)) + return PTR_ERR(desc); + else + return desc_to_gpio(desc); +} +EXPORT_SYMBOL(of_get_named_gpio_flags); + /** * of_gpio_simple_xlate - translate gpio_spec to the GPIO number and flags * @gc: pointer to the gpio_chip structure diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index cf092941a9fd..1a4103dd38df 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -15,6 +15,8 @@ #include #include +enum of_gpio_flags; + /** * struct acpi_gpio_info - ACPI GPIO specific information * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo @@ -46,4 +48,7 @@ acpi_get_gpiod_by_index(struct device *dev, int index, int gpiochip_request_own_desc(struct gpio_desc *desc, const char *label); void gpiochip_free_own_desc(struct gpio_desc *desc); +struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, + const char *list_name, int index, enum of_gpio_flags *flags); + #endif /* GPIOLIB_H */ -- cgit v1.2.3 From 3ff35cbcfa4bc7d7dbdd0279e32ea677567ded02 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 16 May 2014 11:59:14 +0200 Subject: gpio-pch: Fix Kconfig dependencies The gpio-pch driver is for a companion chip to the Intel Atom E600 series processors. These are 32-bit x86 processors so the driver is only needed on X86_32. Add COMPILE_TEST as an alternative, so that the driver can still be build-tested elsewhere. Signed-off-by: Jean Delvare Cc: Linus Walleij Cc: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 664df4d08459..3c603e8c2173 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -715,7 +715,7 @@ config GPIO_INTEL_MID config GPIO_PCH tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7223/ML7831) GPIO" - depends on PCI && X86 + depends on PCI && (X86_32 || COMPILE_TEST) select GENERIC_IRQ_CHIP help This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff -- cgit v1.2.3 From 7b42e3dbdafcc0454ffbce0a88b6d3f456e70d85 Mon Sep 17 00:00:00 2001 From: Anthony Fee Date: Mon, 19 May 2014 18:49:14 +0100 Subject: gpio: generic: add request function pointer gpiolib will require all gpio drivers to expicitly set the request function pointer in the future. To encourage gpio driver developers to adhere to this standard gpio-generic.c now sets this function pointer. Signed-off-by: Anthony Fee Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-generic.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-generic.c b/drivers/gpio/gpio-generic.c index b5dff9e742f8..fea8c82bb8fc 100644 --- a/drivers/gpio/gpio-generic.c +++ b/drivers/gpio/gpio-generic.c @@ -388,6 +388,14 @@ static int bgpio_setup_direction(struct bgpio_chip *bgc, return 0; } +static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin) +{ + if (gpio_pin < chip->ngpio) + return 0; + + return -EINVAL; +} + int bgpio_remove(struct bgpio_chip *bgc) { return gpiochip_remove(&bgc->gc); @@ -413,6 +421,7 @@ int bgpio_init(struct bgpio_chip *bgc, struct device *dev, bgc->gc.label = dev_name(dev); bgc->gc.base = -1; bgc->gc.ngpio = bgc->bits; + bgc->gc.request = bgpio_request; ret = bgpio_setup_io(bgc, dat, set, clr); if (ret) -- cgit v1.2.3 From dc62b56a68d3d6dd1044e1f7d0c8310339cb5b5f Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Tue, 20 May 2014 17:07:38 +0800 Subject: gpio / ACPI: use *_cansleep version of gpiod_get/set APIs The GPIO operation region handler should be called where sleep is allowed, so we should use the *_cansleep version of gpiod_get/set APIs or we will get a warning message complaining invalid context if the GPIO chip has the cansleep flag set. Signed-off-by: Aaron Lu Acked-by: Mika Westerberg Acked-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 401add28933f..4a987917c186 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -449,9 +449,10 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, mutex_unlock(&achip->conn_lock); if (function == ACPI_WRITE) - gpiod_set_raw_value(desc, !!((1 << i) & *value)); + gpiod_set_raw_value_cansleep(desc, + !!((1 << i) & *value)); else - *value |= (u64)gpiod_get_raw_value(desc) << i; + *value |= (u64)gpiod_get_raw_value_cansleep(desc) << i; } out: -- cgit v1.2.3 From 349b6c5355964d306d7d957c3af6179f3d6391ed Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 27 May 2014 15:15:21 +0200 Subject: gpio: pch: add slab include After change 3ff35cbcfa4bc7d7dbdd0279e32ea677567ded02 "gpio-pch: Fix Kconfig dependencies" which enabled COMPILE_TEST as an alternative for the PCH driver, we get build failures like this: drivers/gpio/gpio-pch.c: In function 'pch_gpio_probe': drivers/gpio/gpio-pch.c:359:2: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] drivers/gpio/gpio-pch.c:359:7: warning: assignment makes pointer from integer without a cast [enabled by default] drivers/gpio/gpio-pch.c:442:2: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration] Fix this by including explicitly. Cc: Jean Delvare Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pch.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pch.c b/drivers/gpio/gpio-pch.c index 83a156397474..d6eac9b17db9 100644 --- a/drivers/gpio/gpio-pch.c +++ b/drivers/gpio/gpio-pch.c @@ -20,6 +20,7 @@ #include #include #include +#include #define PCH_EDGE_FALLING 0 #define PCH_EDGE_RISING BIT(0) -- cgit v1.2.3 From 821e85f2a8433614b84cea194ac4f1302ef47ec9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 23 May 2014 13:42:14 +0200 Subject: gpio: Add run-time dependencies to R-Car driver The Renesas R-Car GPIO driver is only useful on shmobile unless build testing. Signed-off-by: Jean Delvare Cc: Magnus Damm Cc: Alexandre Courbot Acked-by: Simon Horman Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3c603e8c2173..8f0799d876c5 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -268,7 +268,7 @@ config GPIO_PXA config GPIO_RCAR tristate "Renesas R-Car GPIO" - depends on ARM + depends on ARM && (ARCH_SHMOBILE || COMPILE_TEST) help Say yes here to support GPIO on Renesas R-Car SoCs. -- cgit v1.2.3 From 3e3bed913e8bbd78f38cefd5d575475f45c05dd0 Mon Sep 17 00:00:00 2001 From: Michael Stickel Date: Mon, 26 May 2014 10:03:16 +0200 Subject: gpio: mcp23s08: fixed count variable for devicetree probing Fixed missing increase of count variable for devicetree path in driver probing. The gpio-mcp23s08 driver has two paths for getting the platform registration information. One for the classic platform initialization and one for openfirmware devicetree based initialization. The devicetree based path is missing the increase of the count variable, which results in the count variable to become negative in the later use, where it is decreased. The count variable is used as an index into a vector. This results in accessing invalid memory space and can result in an exception. Tested this with an AM3352 SoC with two mcp23s17 on two chip selects as well as on a shared chip select. Signed-off-by: Michael Stickel Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index d7f384f9cde0..00fbb30b9b10 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -895,8 +895,13 @@ static int mcp23s08_probe(struct spi_device *spi) return -ENODEV; } - for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) + for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) { pullups[addr] = 0; + if (spi_present_mask & (1 << addr)) + chips++; + } + if (!chips) + return -ENODEV; } else { type = spi_get_device_id(spi)->driver_data; pdata = dev_get_platdata(&spi->dev); @@ -935,6 +940,10 @@ static int mcp23s08_probe(struct spi_device *spi) if (!(spi_present_mask & (1 << addr))) continue; chips--; + if (chips < 0) { + dev_err(&spi->dev, "FATAL: invalid negative chip id\n"); + goto fail; + } data->mcp[addr] = &data->chip[chips]; status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, 0x40 | (addr << 1), type, base, -- cgit v1.2.3 From c829f956f14b61cd6c390c5daced537613798239 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 27 May 2014 15:25:51 +0900 Subject: gpio: ep93xx: Use devm_ioremap_resource() Use devm_ioremap_resource() because devm_request_and_ioremap() is obsoleted by devm_ioremap_resource(). Signed-off-by: Jingoo Han Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ep93xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index dd39f27f3cb2..dcc2bb4074ef 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -352,7 +352,7 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ep93xx_gpio->mmio_base = devm_request_and_ioremap(dev, res); + ep93xx_gpio->mmio_base = devm_ioremap_resource(dev, res); if (IS_ERR(ep93xx_gpio->mmio_base)) return PTR_ERR(ep93xx_gpio->mmio_base); -- cgit v1.2.3 From 6a2f4b7dadd5e2b3e02e28af1ddb32d17ac5b310 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 26 May 2014 22:58:14 +0200 Subject: gpio: dwapb: use a second irq chip Right new have one irq chip running always in level mode. It would nicer to have two irq chips where one is handling level type interrupts and the other one is doing edge interrupts. So we can have at runtime two users where one is using edge and the other level. Acked-by: Alan Tull Acked-by: Jamie Iles Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Linus Walleij --- drivers/gpio/gpio-dwapb.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 4d25a06bb45e..cd3b81435274 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -198,6 +198,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type) break; } + irq_setup_alt_chip(d, type); + writel(level, gpio->regs + GPIO_INTTYPE_LEVEL); writel(polarity, gpio->regs + GPIO_INT_POLARITY); spin_unlock_irqrestore(&bgc->lock, flags); @@ -213,7 +215,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, struct irq_chip_generic *irq_gc; unsigned int hwirq, ngpio = gc->ngpio; struct irq_chip_type *ct; - int err, irq; + int err, irq, i; irq = irq_of_parse_and_map(node, 0); if (!irq) { @@ -227,7 +229,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, if (!gpio->domain) return; - err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1, + err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2, "gpio-dwapb", handle_level_irq, IRQ_NOREQUEST, 0, IRQ_GC_INIT_NESTED_LOCK); @@ -248,17 +250,24 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio, irq_gc->reg_base = gpio->regs; irq_gc->private = gpio; - ct = irq_gc->chip_types; - ct->chip.irq_ack = irq_gc_ack_set_bit; - ct->chip.irq_mask = irq_gc_mask_set_bit; - ct->chip.irq_unmask = irq_gc_mask_clr_bit; - ct->chip.irq_set_type = dwapb_irq_set_type; - ct->chip.irq_enable = dwapb_irq_enable; - ct->chip.irq_disable = dwapb_irq_disable; - ct->chip.irq_request_resources = dwapb_irq_reqres; - ct->chip.irq_release_resources = dwapb_irq_relres; - ct->regs.ack = GPIO_PORTA_EOI; - ct->regs.mask = GPIO_INTMASK; + for (i = 0; i < 2; i++) { + ct = &irq_gc->chip_types[i]; + ct->chip.irq_ack = irq_gc_ack_set_bit; + ct->chip.irq_mask = irq_gc_mask_set_bit; + ct->chip.irq_unmask = irq_gc_mask_clr_bit; + ct->chip.irq_set_type = dwapb_irq_set_type; + ct->chip.irq_enable = dwapb_irq_enable; + ct->chip.irq_disable = dwapb_irq_disable; + ct->chip.irq_request_resources = dwapb_irq_reqres; + ct->chip.irq_release_resources = dwapb_irq_relres; + ct->regs.ack = GPIO_PORTA_EOI; + ct->regs.mask = GPIO_INTMASK; + ct->type = IRQ_TYPE_LEVEL_MASK; + } + + irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK; + irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH; + irq_gc->chip_types[1].handler = handle_edge_irq; irq_set_chained_handler(irq, dwapb_irq_handler); irq_set_handler_data(irq, gpio); -- cgit v1.2.3 From 596a1c5f51e2945d036fae208b67f64a47346c68 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 28 May 2014 09:14:06 +0200 Subject: gpio: mcp23s08: switch chip count to int Commit 3e3bed913e8bbd78f38cefd5d575475f45c05dd0 "gpio: mcp23s08: fixed count variable for devicetree probing" introduced a loop check to see if the number of chips were unconsistent and going below zero counting downwards, but this requires the counting variable to be able to be negative, so switch the variable from unsigned to int. Cc: Michael Stickel Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mcp23s08.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mcp23s08.c b/drivers/gpio/gpio-mcp23s08.c index 00fbb30b9b10..f3bee370bcf2 100644 --- a/drivers/gpio/gpio-mcp23s08.c +++ b/drivers/gpio/gpio-mcp23s08.c @@ -867,7 +867,7 @@ static int mcp23s08_probe(struct spi_device *spi) { struct mcp23s08_platform_data *pdata; unsigned addr; - unsigned chips = 0; + int chips = 0; struct mcp23s08_driver_data *data; int status, type; unsigned base = -1, -- cgit v1.2.3 From e6b698f69adce0119b5f5ed00789d1a0e0af975f Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 23 May 2014 11:27:26 +0530 Subject: gpio: pcf857x: Avoid calling irq_domain_cleanup twice Currently irq_domain_cleanup is called twice if irq_domain_init fails. This causes the following crash. Unable to handle kernel paging request at virtual address 00100104 pgd = c0004000 [00100104] *pgd=00000000 Internal error: Oops: 805 [#1] SMP ARM Modules linked in: CPU: 0 PID: 6 Comm: kworker/u4:0 Not tainted 3.12.15-01889-gedd10a8-dirty #4 Workqueue: deferwq deferred_probe_work_func task: ed0ee800 ti: ed116000 task.ti: ed116000 PC is at irq_domain_remove+0x3c/0x8c LR is at 0x0 pc : [] lr : [<00000000>] psr: a0000013 sp : ed117b50 ip : 00100100 fp : ed117b64 r10: ed5d1a04 r9 : 00000008 r8 : 00000000 r7 : ffffffea r6 : ed5d1a20 r5 : ed5d1a00 r4 : ed5e7540 r3 : 00200200 r2 : 00100100 r1 : c08aa180 r0 : 00200200 Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c53c7d Table: 8000406a DAC: 00000017 Process kworker/u4:0 (pid: 6, stack limit = 0xed116248) Stack: (0xed117b50 to 0xed118000) 7b40: 0000016b ed5d5f10 ed117b74 ed117b68 7b60: c02c8910 c0089704 ed117bb4 ed117b78 c02c8e14 c02c8900 ed5d1a04 ed5d4e80 ... ... fe0: 00000000 00000000 00000000 00000000 00000013 00000000 384a13ea 1590210a Backtrace: [] (irq_domain_remove+0x0/0x8c) from [] (pcf857x_irq_domain_cleanup+0x1c/0x20) r4:ed5d5f10 r3:0000016b [] (pcf857x_irq_domain_cleanup+0x0/0x20) from [] (pcf857x_probe+0x2a8/0x364) [] (pcf857x_probe+0x0/0x364) from [] (i2c_device_probe+0x80/0xc0) [] (i2c_device_probe+0x0/0xc0) from [] (driver_probe_device+0x104/0x240) r6:00000000 r5:ed5d1a20 r4:c08c709c r3:c047872c [] (driver_probe_device+0x0/0x240) from [] (__device_attach+0x48/0x4c) r7:ed4fc480 r6:c036c510 r5:ed5d1a20 r4:c0866bb8 [] (__device_attach+0x0/0x4c) from [] (bus_for_each_drv+0x4c/0x94) r5:ed5d1a20 r4:00000000 [] (bus_for_each_drv+0x0/0x94) from [] (device_attach+0x78/0x90) r6:c087fe50 r5:ed5d1a54 r4:ed5d1a20 [] (device_attach+0x0/0x90) from [] (bus_probe_device+0x8c/0xb4) r6:c087fe50 r5:ed5d1a20 r4:ed5d1a20 r3:ed17e1c0 [] (bus_probe_device+0x0/0xb4) from [] (device_add+0x34c/0x624) r6:ed5d1a28 r5:00000000 r4:ed5d1a20 r3:fffffffe [] (device_add+0x0/0x624) from [] (device_register+0x1c/0x20) ... ... [] (process_one_work+0x0/0x37c) from [] (worker_thread+0x13c/0x3c4) [] (worker_thread+0x0/0x3c4) from [] (kthread+0xac/0xb8) [] (kthread+0x0/0xb8) from [] (ret_from_fork+0x14/0x3c) r7:00000000 r6:00000000 r5:c0067040 r4:ed105d20 Code: e59fc04c e591e000 e59f0048 e154000e (e5823004) ---[ end trace 59dd1e90032c4217 ]--- Signed-off-by: George Cherian Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pcf857x.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 82735822bc9d..5acffed10e77 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -319,7 +319,7 @@ static int pcf857x_probe(struct i2c_client *client, status = pcf857x_irq_domain_init(gpio, client); if (status < 0) { dev_err(&client->dev, "irq_domain init failed\n"); - goto fail; + goto fail_irq_domain; } } @@ -414,12 +414,13 @@ static int pcf857x_probe(struct i2c_client *client, return 0; fail: - dev_dbg(&client->dev, "probe error %d for '%s'\n", - status, client->name); - if (client->irq) pcf857x_irq_domain_cleanup(gpio); +fail_irq_domain: + dev_dbg(&client->dev, "probe error %d for '%s'\n", + status, client->name); + return status; } -- cgit v1.2.3 From 5795cf35030bfa180a6f5c948681821f7019fc18 Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 23 May 2014 11:27:27 +0530 Subject: gpio: pcf857x: Add IRQF_SHARED when request irq It's quite possible that multiple pcf857x can be hooked up to the same interrupt line with the processor. So add IRQF_SHARED in request irq.. Signed-off-by: George Cherian Signed-off-by: Linus Walleij --- drivers/gpio/gpio-pcf857x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index 5acffed10e77..27b46751ea7e 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -262,7 +262,7 @@ static int pcf857x_irq_domain_init(struct pcf857x *gpio, /* enable real irq */ status = devm_request_threaded_irq(&client->dev, client->irq, NULL, pcf857x_irq, IRQF_ONESHOT | - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_SHARED, dev_name(&client->dev), gpio); if (status) -- cgit v1.2.3 From 7bcbce55f20e41c014df4d5d9c8448f7b5e49d79 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 9 May 2014 13:27:57 +0200 Subject: gpio: pca953x: use gpiolib irqchip helpers This switches the PCA953x driver over to using the gpiolib irqchip helpers to handle the threaded interrups cascaded off this GPIO chip. Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-pca953x.c | 93 ++++++++++++++++----------------------------- 2 files changed, 33 insertions(+), 61 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8f0799d876c5..fa3cb189f972 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -519,6 +519,7 @@ config GPIO_PCA953X config GPIO_PCA953X_IRQ bool "Interrupt controller support for PCA953x" depends on GPIO_PCA953X=y + select GPIOLIB_IRQCHIP help Say yes here to enable the pca953x to be used as an interrupt controller. It requires the driver to be built in the kernel. diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6398f8a0f40c..e721a37c3473 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -15,8 +15,6 @@ #include #include #include -#include -#include #include #include #include @@ -91,7 +89,6 @@ struct pca953x_chip { u8 irq_stat[MAX_BANK]; u8 irq_trig_raise[MAX_BANK]; u8 irq_trig_fall[MAX_BANK]; - struct irq_domain *domain; #endif struct i2c_client *client; @@ -100,6 +97,11 @@ struct pca953x_chip { int chip_type; }; +static inline struct pca953x_chip *to_pca(struct gpio_chip *gc) +{ + return container_of(gc, struct pca953x_chip, gpio_chip); +} + static int pca953x_read_single(struct pca953x_chip *chip, int reg, u32 *val, int off) { @@ -202,12 +204,10 @@ static int pca953x_read_regs(struct pca953x_chip *chip, int reg, u8 *val) static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); reg_val = chip->reg_direction[off / BANK_SZ] | (1u << (off % BANK_SZ)); @@ -233,12 +233,10 @@ exit: static int pca953x_gpio_direction_output(struct gpio_chip *gc, unsigned off, int val) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); /* set output level */ if (val) @@ -285,12 +283,10 @@ exit: static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u32 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); switch (chip->chip_type) { case PCA953X_TYPE: @@ -315,12 +311,10 @@ static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) { - struct pca953x_chip *chip; + struct pca953x_chip *chip = to_pca(gc); u8 reg_val; int ret, offset = 0; - chip = container_of(gc, struct pca953x_chip, gpio_chip); - mutex_lock(&chip->i2c_lock); if (val) reg_val = chip->reg_output[off / BANK_SZ] @@ -367,38 +361,34 @@ static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) } #ifdef CONFIG_GPIO_PCA953X_IRQ -static int pca953x_gpio_to_irq(struct gpio_chip *gc, unsigned off) -{ - struct pca953x_chip *chip; - - chip = container_of(gc, struct pca953x_chip, gpio_chip); - return irq_create_mapping(chip->domain, off); -} - static void pca953x_irq_mask(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ)); } static void pca953x_irq_unmask(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ); } static void pca953x_irq_bus_lock(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); mutex_lock(&chip->irq_lock); } static void pca953x_irq_bus_sync_unlock(struct irq_data *d) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); u8 new_irqs; int level, i; @@ -420,7 +410,8 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d) static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { - struct pca953x_chip *chip = irq_data_get_irq_chip_data(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct pca953x_chip *chip = to_pca(gc); int bank_nb = d->hwirq / BANK_SZ; u8 mask = 1 << (d->hwirq % BANK_SZ); @@ -512,7 +503,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { level = __ffs(pending[i]); - handle_nested_irq(irq_find_mapping(chip->domain, + handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); nhandled++; @@ -522,27 +513,6 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) return (nhandled > 0) ? IRQ_HANDLED : IRQ_NONE; } -static int pca953x_gpio_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) -{ - irq_clear_status_flags(irq, IRQ_NOREQUEST); - irq_set_chip_data(irq, d->host_data); - irq_set_chip(irq, &pca953x_irq_chip); - irq_set_nested_thread(irq, true); -#ifdef CONFIG_ARM - set_irq_flags(irq, IRQF_VALID); -#else - irq_set_noprobe(irq); -#endif - - return 0; -} - -static const struct irq_domain_ops pca953x_irq_simple_ops = { - .map = pca953x_gpio_irq_map, - .xlate = irq_domain_xlate_twocell, -}; - static int pca953x_irq_setup(struct pca953x_chip *chip, const struct i2c_device_id *id, int irq_base) @@ -574,14 +544,6 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, chip->irq_stat[i] &= chip->reg_direction[i]; mutex_init(&chip->irq_lock); - chip->domain = irq_domain_add_simple(client->dev.of_node, - chip->gpio_chip.ngpio, - irq_base, - &pca953x_irq_simple_ops, - chip); - if (!chip->domain) - return -ENODEV; - ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, @@ -595,7 +557,16 @@ static int pca953x_irq_setup(struct pca953x_chip *chip, return ret; } - chip->gpio_chip.to_irq = pca953x_gpio_to_irq; + ret = gpiochip_irqchip_add(&chip->gpio_chip, + &pca953x_irq_chip, + irq_base, + handle_simple_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(&client->dev, + "could not connect irqchip to gpiochip\n"); + return ret; + } } return 0; @@ -759,11 +730,11 @@ static int pca953x_probe(struct i2c_client *client, if (ret) return ret; - ret = pca953x_irq_setup(chip, id, irq_base); + ret = gpiochip_add(&chip->gpio_chip); if (ret) return ret; - ret = gpiochip_add(&chip->gpio_chip); + ret = pca953x_irq_setup(chip, id, irq_base); if (ret) return ret; -- cgit v1.2.3 From fc346270124a1a05a5b3c47f277d467ff410b3ae Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 29 May 2014 16:52:46 +0200 Subject: gpio: select IRQ_DOMAIN for gpiolib irqchip helpers These helpers depend on the IRQ_DOMAIN so select it explicitly, as it will not be present on all platforms such as Intel desktops and laptops using Intel-MID. Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fa3cb189f972..4a1b5113e527 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -56,6 +56,7 @@ config GPIO_ACPI depends on ACPI config GPIOLIB_IRQCHIP + select IRQ_DOMAIN bool config DEBUG_GPIO @@ -710,7 +711,7 @@ config GPIO_AMD8111 config GPIO_INTEL_MID bool "Intel Mid GPIO support" depends on PCI && X86 - select IRQ_DOMAIN + select GPIOLIB_IRQCHIP help Say Y here to support Intel Mid GPIO. -- cgit v1.2.3