From 71b8f600b034c7f5780f6fb311dabfe331c64feb Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 28 Nov 2019 09:37:17 +0100 Subject: gpio: Handle counting of Freescale chipselects We have a special quirk to handle the Freescale nonstandard SPI chipselect GPIOs in the gpiolib-of.c file, but it currently only handles the case where the GPIOs are actually requested (gpiod_*get()). We also need to handle that the SPI core attempts to count the GPIOs before use, and that needs a similar quirk in the OF part of the library. Cc: Christophe Leroy Reported-by: Christophe Leroy Fixes: 0f0581b24bd0 ("spi: fsl: Convert to use CS GPIO descriptors") Signed-off-by: Linus Walleij Tested-by: Christophe Leroy Link: https://lore.kernel.org/r/20191128083718.39177-2-linus.walleij@linaro.org Signed-off-by: Mark Brown --- drivers/gpio/gpiolib-of.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 1eea2c6c2e1d..4b19e7e26b90 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -23,6 +23,29 @@ #include "gpiolib.h" #include "gpiolib-of.h" +/** + * of_gpio_spi_cs_get_count() - special GPIO counting for SPI + * Some elder GPIO controllers need special quirks. Currently we handle + * the Freescale GPIO controller with bindings that doesn't use the + * established "cs-gpios" for chip selects but instead rely on + * "gpios" for the chip select lines. If we detect this, we redirect + * the counting of "cs-gpios" to count "gpios" transparent to the + * driver. + */ +int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) +{ + struct device_node *np = dev->of_node; + + if (!IS_ENABLED(CONFIG_SPI_MASTER)) + return 0; + if (!con_id || strcmp(con_id, "cs")) + return 0; + if (!of_device_is_compatible(np, "fsl,spi") && + !of_device_is_compatible(np, "aeroflexgaisler,spictrl")) + return 0; + return of_gpio_named_count(np, "gpios"); +} + /* * This is used by external users of of_gpio_count() from * @@ -35,6 +58,10 @@ int of_gpio_get_count(struct device *dev, const char *con_id) char propname[32]; unsigned int i; + ret = of_gpio_spi_cs_get_count(dev, con_id); + if (ret > 0) + return ret; + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(propname, sizeof(propname), "%s-%s", -- cgit v1.2.3 From a1f4c96b799b80118b50bd47320deb9013b7ff40 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 30 Nov 2019 09:28:28 +0800 Subject: gpiolib: of: Make of_gpio_spi_cs_get_count static Fix sparse warning: drivers/gpio/gpiolib-of.c:35:5: warning: symbol 'of_gpio_spi_cs_get_count' was not declared. Should it be static? Reported-by: Hulk Robot Signed-off-by: YueHaibing Reviewed-by: Linus Walleij Link: https://lore.kernel.org/r/20191130012828.14504-1-yuehaibing@huawei.com Signed-off-by: Mark Brown --- 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 4b19e7e26b90..f90a161ca97a 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -32,7 +32,7 @@ * the counting of "cs-gpios" to count "gpios" transparent to the * driver. */ -int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) +static int of_gpio_spi_cs_get_count(struct device *dev, const char *con_id) { struct device_node *np = dev->of_node; -- cgit v1.2.3 From 634f0348fe336fce8f6cab1933139115e983ed2f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Tue, 26 Nov 2019 11:30:27 -0800 Subject: gpio: xtensa: fix driver build Commit cad6fade6e78 ("xtensa: clean up WSR*/RSR*/get_sr/set_sr") removed {RSR,WSR}_CPENABLE from xtensa code, but did not fix up all users, breaking gpio-xtensa driver build. Update gpio-xtensa to use new xtensa_{get,set}_sr API. Cc: stable@vger.kernel.org # v5.0+ Fixes: cad6fade6e78 ("xtensa: clean up WSR*/RSR*/get_sr/set_sr") Signed-off-by: Max Filippov Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-xtensa.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-xtensa.c b/drivers/gpio/gpio-xtensa.c index 08d7c3b32038..c8af34a6368f 100644 --- a/drivers/gpio/gpio-xtensa.c +++ b/drivers/gpio/gpio-xtensa.c @@ -44,15 +44,14 @@ static inline unsigned long enable_cp(unsigned long *cpenable) unsigned long flags; local_irq_save(flags); - RSR_CPENABLE(*cpenable); - WSR_CPENABLE(*cpenable | BIT(XCHAL_CP_ID_XTIOP)); - + *cpenable = xtensa_get_sr(cpenable); + xtensa_set_sr(*cpenable | BIT(XCHAL_CP_ID_XTIOP), cpenable); return flags; } static inline void disable_cp(unsigned long flags, unsigned long cpenable) { - WSR_CPENABLE(cpenable); + xtensa_set_sr(cpenable, cpenable); local_irq_restore(flags); } -- cgit v1.2.3 From 322f6a3182d42df18059a89c53b09d33919f755e Mon Sep 17 00:00:00 2001 From: "Johnson CH Chen (陳昭勳)" Date: Tue, 26 Nov 2019 06:51:11 +0000 Subject: gpio: mpc8xxx: Add platform device to gpiochip->parent Dear Linus Walleij, In old kernels, some APIs still try to use parent->of_node from struct gpio_chip, and it could be resulted in kernel panic because parent is NULL. Adding platform device to gpiochip->parent can fix this problem. Signed-off-by: Johnson Chen Link: https://patchwork.kernel.org/patch/11234609 Link: https://lore.kernel.org/r/HK0PR01MB3521489269F76467DFD7843FFA450@HK0PR01MB3521.apcprd01.prod.exchangelabs.com Signed-off-by: Linus Walleij --- drivers/gpio/gpio-mpc8xxx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index f1e164cecff8..5ae30de3490a 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -346,6 +346,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) return -ENOMEM; gc = &mpc8xxx_gc->gc; + gc->parent = &pdev->dev; if (of_property_read_bool(np, "little-endian")) { ret = bgpio_init(gc, &pdev->dev, 4, -- cgit v1.2.3 From d935bd50dd14a7714cbdba9a76435dbb56edb1ae Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 27 Nov 2019 10:59:19 +0100 Subject: gpio: Fix error message on out-of-range GPIO in lookup table When a GPIO offset in a lookup table is out-of-range, the printed error message (1) does not include the actual out-of-range value, and (2) contains an off-by-one error in the upper bound. Avoid user confusion by also printing the actual GPIO offset, and correcting the upper bound of the range. While at it, use "%u" for unsigned int. Sample impact: -requested GPIO 0 is out of range [0..32] for chip e6052000.gpio +requested GPIO 0 (45) is out of range [0..31] for chip e6052000.gpio Fixes: 2a3cf6a3599e9015 ("gpiolib: return -ENOENT if no GPIO mapping exists") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20191127095919.4214-1-geert+renesas@glider.be Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9913886ede90..dce0b31f4125 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -4472,8 +4472,9 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, if (chip->ngpio <= p->chip_hwnum) { dev_err(dev, - "requested GPIO %d is out of range [0..%d] for chip %s\n", - idx, chip->ngpio, chip->label); + "requested GPIO %u (%u) is out of range [0..%u] for chip %s\n", + idx, p->chip_hwnum, chip->ngpio - 1, + chip->label); return ERR_PTR(-EINVAL); } -- cgit v1.2.3 From bc7bc688366a4f2544699e40cce45393b7f24408 Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Wed, 11 Dec 2019 08:46:31 +0800 Subject: gpio: mockup: Fix usage of new GPIO_LINE_DIRECTION Restore the external behavior of gpio-mockup to what it was prior to the change to using GPIO_LINE_DIRECTION. Fixes: e42615ec233b ("gpio: Use new GPIO_LINE_DIRECTION") Signed-off-by: Kent Gibson Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mockup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index 56d647a30e3e..c4fdc192ea4e 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -226,7 +226,7 @@ static int gpio_mockup_get_direction(struct gpio_chip *gc, unsigned int offset) int direction; mutex_lock(&chip->lock); - direction = !chip->lines[offset].dir; + direction = chip->lines[offset].dir; mutex_unlock(&chip->lock); return direction; @@ -395,7 +395,7 @@ static int gpio_mockup_probe(struct platform_device *pdev) struct gpio_chip *gc; struct device *dev; const char *name; - int rv, base; + int rv, base, i; u16 ngpio; dev = &pdev->dev; @@ -447,6 +447,9 @@ static int gpio_mockup_probe(struct platform_device *pdev) if (!chip->lines) return -ENOMEM; + for (i = 0; i < gc->ngpio; i++) + chip->lines[i].dir = GPIO_LINE_DIRECTION_IN; + if (device_property_read_bool(dev, "named-gpio-lines")) { rv = gpio_mockup_name_lines(dev, chip); if (rv) -- cgit v1.2.3 From 11e299de3aced4ea23a9fb1fef6c983c8d516302 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Dec 2019 21:28:31 +0100 Subject: gpio: aspeed: avoid return type warning gcc has a hard time tracking whether BUG_ON(1) ends execution or not: drivers/gpio/gpio-aspeed-sgpio.c: In function 'bank_reg': drivers/gpio/gpio-aspeed-sgpio.c:112:1: error: control reaches end of non-void function [-Werror=return-type] Use the simpler BUG() that gcc knows cannot continue. Fixes: f8b410e3695a ("gpio: aspeed-sgpio: Rename and add Kconfig/Makefile") Signed-off-by: Arnd Bergmann Acked-by: Andrew Jeffery Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-aspeed-sgpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c index 7e99860ca447..8319812593e3 100644 --- a/drivers/gpio/gpio-aspeed-sgpio.c +++ b/drivers/gpio/gpio-aspeed-sgpio.c @@ -107,7 +107,7 @@ static void __iomem *bank_reg(struct aspeed_sgpio *gpio, return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; default: /* acturally if code runs to here, it's an error case */ - BUG_ON(1); + BUG(); } } -- cgit v1.2.3 From 9cc7a18bcbd47e82960a059127497ab09c4abd05 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 10 Dec 2019 20:54:01 +0100 Subject: gpio: xgs-iproc: remove __exit annotation for iproc_gpio_remove When built into the kernel, the driver causes a link problem: `iproc_gpio_remove' referenced in section `.data' of drivers/gpio/gpio-xgs-iproc.o: defined in discarded section `.exit.text' of drivers/gpio/gpio-xgs-iproc.o Remove the incorrect annotation. Fixes: 6a41b6c5fc20 ("gpio: Add xgs-iproc driver") Signed-off-by: Arnd Bergmann Reviewed-by: Chris Packham Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-xgs-iproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c index 773e5c24309e..b21c2e436b61 100644 --- a/drivers/gpio/gpio-xgs-iproc.c +++ b/drivers/gpio/gpio-xgs-iproc.c @@ -280,7 +280,7 @@ static int iproc_gpio_probe(struct platform_device *pdev) return 0; } -static int __exit iproc_gpio_remove(struct platform_device *pdev) +static int iproc_gpio_remove(struct platform_device *pdev) { struct iproc_gpio_chip *chip; -- cgit v1.2.3 From 256efaea1fdc4e38970489197409a26125ee0aaa Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 7 Dec 2019 16:20:18 +0000 Subject: gpiolib: fix up emulated open drain outputs gpiolib has a corner case with open drain outputs that are emulated. When such outputs are outputting a logic 1, emulation will set the hardware to input mode, which will cause gpiod_get_direction() to report that it is in input mode. This is different from the behaviour with a true open-drain output. Unify the semantics here. Cc: Suggested-by: Linus Walleij Signed-off-by: Russell King Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9913886ede90..8a08a9d4f071 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -220,6 +220,14 @@ int gpiod_get_direction(struct gpio_desc *desc) chip = gpiod_to_chip(desc); offset = gpio_chip_hwgpio(desc); + /* + * Open drain emulation using input mode may incorrectly report + * input here, fix that up. + */ + if (test_bit(FLAG_OPEN_DRAIN, &desc->flags) && + test_bit(FLAG_IS_OUT, &desc->flags)) + return 0; + if (!chip->get_direction) return -ENOTSUPP; -- cgit v1.2.3 From 2688302bf1924ebccab2a3b298dd50b4f744d48d Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 9 Dec 2019 14:35:44 +0200 Subject: gpio: pca953x: Switch to bitops in IRQ callbacks Since we have driver converted to use bitmap API we must use traditional bit operations (set_bit(), clear_bit(), etc.) against it. Currently IRQ callbacks are missed in the conversion and thus broken. Let's fix it right here right now. Fixes: 35d13d94893f ("gpio: pca953x: convert to use bitmap API") Signed-off-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-pca953x.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6652bee01966..9853547e7276 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -568,16 +568,18 @@ static void pca953x_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - chip->irq_mask[d->hwirq / BANK_SZ] &= ~BIT(d->hwirq % BANK_SZ); + clear_bit(hwirq, chip->irq_mask); } static void pca953x_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - chip->irq_mask[d->hwirq / BANK_SZ] |= BIT(d->hwirq % BANK_SZ); + set_bit(hwirq, chip->irq_mask); } static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on) @@ -635,8 +637,7 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - int bank_nb = d->hwirq / BANK_SZ; - u8 mask = BIT(d->hwirq % BANK_SZ); + irq_hw_number_t hwirq = irqd_to_hwirq(d); if (!(type & IRQ_TYPE_EDGE_BOTH)) { dev_err(&chip->client->dev, "irq %d: unsupported type %d\n", @@ -644,15 +645,8 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - if (type & IRQ_TYPE_EDGE_FALLING) - chip->irq_trig_fall[bank_nb] |= mask; - else - chip->irq_trig_fall[bank_nb] &= ~mask; - - if (type & IRQ_TYPE_EDGE_RISING) - chip->irq_trig_raise[bank_nb] |= mask; - else - chip->irq_trig_raise[bank_nb] &= ~mask; + assign_bit(hwirq, chip->irq_trig_fall, type & IRQ_TYPE_EDGE_FALLING); + assign_bit(hwirq, chip->irq_trig_raise, type & IRQ_TYPE_EDGE_RISING); return 0; } @@ -661,10 +655,10 @@ static void pca953x_irq_shutdown(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct pca953x_chip *chip = gpiochip_get_data(gc); - u8 mask = BIT(d->hwirq % BANK_SZ); + irq_hw_number_t hwirq = irqd_to_hwirq(d); - chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask; - chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask; + clear_bit(hwirq, chip->irq_trig_raise); + clear_bit(hwirq, chip->irq_trig_fall); } static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pending) -- cgit v1.2.3 From 286e7beaa4cc7734894ee214569de4669ed9891e Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Fri, 13 Dec 2019 14:00:34 +0100 Subject: gpio: tegra186: Allow building on Tegra194-only configurations The driver is compatible with both Tegra186 and Tegra194, but currently it cannot be selected if only Tegra194 support is enabled. Allow builds with only Tegra194 support enabled to select this driver. While at it, select this driver by default on Tegra194 builds because it is an essential part of the system. Signed-off-by: Thierry Reding Link: https://lore.kernel.org/r/20191213130034.219227-1-thierry.reding@gmail.com Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8adffd42f8cb..6ab25fe1c423 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -553,8 +553,8 @@ config GPIO_TEGRA config GPIO_TEGRA186 tristate "NVIDIA Tegra186 GPIO support" - default ARCH_TEGRA_186_SOC - depends on ARCH_TEGRA_186_SOC || COMPILE_TEST + default ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC + depends on ARCH_TEGRA_186_SOC || ARCH_TEGRA_194_SOC || COMPILE_TEST depends on OF_GPIO select GPIOLIB_IRQCHIP select IRQ_DOMAIN_HIERARCHY -- cgit v1.2.3 From ee8598ae527ea0408e440c073e0945fc37488fe6 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 16 Dec 2019 17:37:10 +0100 Subject: gpio: mockup: fix coding style I have missed two indentation issues in commit 64e7112ee307 ("gpio: mockup: add set_config to support pull up/down"). This commit fixes them. Fixes: 64e7112ee307 ("gpio: mockup: add set_config to support pull up/down") Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mockup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-mockup.c b/drivers/gpio/gpio-mockup.c index c4fdc192ea4e..94b8d3ae27bc 100644 --- a/drivers/gpio/gpio-mockup.c +++ b/drivers/gpio/gpio-mockup.c @@ -156,7 +156,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, mutex_lock(&chip->lock); if (test_bit(FLAG_REQUESTED, &desc->flags) && - !test_bit(FLAG_IS_OUT, &desc->flags)) { + !test_bit(FLAG_IS_OUT, &desc->flags)) { curr = __gpio_mockup_get(chip, offset); if (curr == value) goto out; @@ -165,7 +165,7 @@ static int gpio_mockup_apply_pull(struct gpio_mockup_chip *chip, irq_type = irq_get_trigger_type(irq); if ((value == 1 && (irq_type & IRQ_TYPE_EDGE_RISING)) || - (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) + (value == 0 && (irq_type & IRQ_TYPE_EDGE_FALLING))) irq_sim_fire(sim, offset); } -- cgit v1.2.3 From c5706c7defc79de68a115b5536376298a8fef111 Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Mon, 6 Jan 2020 04:51:54 +0300 Subject: gpio: max77620: Add missing dependency on GPIOLIB_IRQCHIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Driver fails to compile in a minimized kernel's configuration because of the missing dependency on GPIOLIB_IRQCHIP. error: ‘struct gpio_chip’ has no member named ‘irq’ 44 | virq = irq_find_mapping(gpio->gpio_chip.irq.domain, offset); Signed-off-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20200106015154.12040-1-digetx@gmail.com Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpio') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 6ab25fe1c423..2ed599236a1c 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1148,6 +1148,7 @@ config GPIO_MADERA config GPIO_MAX77620 tristate "GPIO support for PMIC MAX77620 and MAX20024" depends on MFD_MAX77620 + select GPIOLIB_IRQCHIP help GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor. MAX77620 PMIC has 8 pins that can be configured as GPIOs. The -- cgit v1.2.3 From 36f2e7207f21a83ca0054116191f119ac64583ab Mon Sep 17 00:00:00 2001 From: Swapna Manupati Date: Thu, 26 Dec 2019 17:42:11 +0530 Subject: gpio: zynq: Fix for bug in zynq_gpio_restore_context API This patch writes the inverse value of Interrupt Mask Status register into the Interrupt Enable register in zynq_gpio_restore_context API to fix the bug. Fixes: e11de4de28c0 ("gpio: zynq: Add support for suspend resume") Signed-off-by: Swapna Manupati Signed-off-by: Michal Simek Signed-off-by: Srinivas Neeli Link: https://lore.kernel.org/r/1577362338-28744-2-git-send-email-srinivas.neeli@xilinx.com Signed-off-by: Linus Walleij --- drivers/gpio/gpio-zynq.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 4c3f6370eab4..05ba16fffdad 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -684,6 +684,8 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) unsigned int bank_num; for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++) { + writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr + + ZYNQ_GPIO_INTDIS_OFFSET(bank_num)); writel_relaxed(gpio->context.datalsw[bank_num], gpio->base_addr + ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num)); @@ -693,9 +695,6 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) writel_relaxed(gpio->context.dirm[bank_num], gpio->base_addr + ZYNQ_GPIO_DIRM_OFFSET(bank_num)); - writel_relaxed(gpio->context.int_en[bank_num], - gpio->base_addr + - ZYNQ_GPIO_INTEN_OFFSET(bank_num)); writel_relaxed(gpio->context.int_type[bank_num], gpio->base_addr + ZYNQ_GPIO_INTTYPE_OFFSET(bank_num)); @@ -705,6 +704,9 @@ static void zynq_gpio_restore_context(struct zynq_gpio *gpio) writel_relaxed(gpio->context.int_any[bank_num], gpio->base_addr + ZYNQ_GPIO_INTANY_OFFSET(bank_num)); + writel_relaxed(~(gpio->context.int_en[bank_num]), + gpio->base_addr + + ZYNQ_GPIO_INTEN_OFFSET(bank_num)); } } -- cgit v1.2.3 From 1ad1b54099c231aed8f6f257065c1b322583f264 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 5 Jan 2020 17:03:56 +0100 Subject: gpiolib: acpi: Turn dmi_system_id table into a generic quirk table Turn the existing run_edge_events_on_boot_blacklist dmi_system_id table into a generic quirk table, storing the quirks in the driver_data ptr. This is a preparation patch for adding other types of (DMI based) quirks. Cc: stable@vger.kernel.org Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20200105160357.97154-2-hdegoede@redhat.com Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d30e57dc755c..2b47d906d536 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -21,6 +21,8 @@ #include "gpiolib.h" #include "gpiolib-acpi.h" +#define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l + static int run_edge_events_on_boot = -1; module_param(run_edge_events_on_boot, int, 0444); MODULE_PARM_DESC(run_edge_events_on_boot, @@ -1309,7 +1311,7 @@ static int acpi_gpio_handle_deferred_request_irqs(void) /* We must use _sync so that this runs after the first deferred_probe run */ late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); -static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { +static const struct dmi_system_id gpiolib_acpi_quirks[] = { { /* * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for @@ -1319,7 +1321,8 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), - } + }, + .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, }, { /* @@ -1331,15 +1334,23 @@ static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), - } + }, + .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, }, {} /* Terminating entry */ }; static int acpi_gpio_setup_params(void) { + const struct dmi_system_id *id; + long quirks = 0; + + id = dmi_first_match(gpiolib_acpi_quirks); + if (id) + quirks = (long)id->driver_data; + if (run_edge_events_on_boot < 0) { - if (dmi_check_system(run_edge_events_on_boot_blacklist)) + if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT) run_edge_events_on_boot = 0; else run_edge_events_on_boot = 1; -- cgit v1.2.3 From aa23ca3d98f756d5b1e503fb140665fb24a41a38 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 5 Jan 2020 17:03:57 +0100 Subject: gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism On some laptops enabling wakeup on the GPIO interrupts used for ACPI _AEI event handling causes spurious wakeups. This commit adds a new honor_wakeup option, defaulting to true (our current behavior), which can be used to disable wakeup on troublesome hardware to avoid these spurious wakeups. This is a workaround for an architectural problem with s2idle under Linux where we do not have any mechanism to immediately go back to sleep after wakeup events, other then for embedded-controller events using the standard ACPI EC interface, for details see: https://lore.kernel.org/linux-acpi/61450f9b-cbc6-0c09-8b3a-aff6bf9a0b3c@redhat.com/ One series of laptops which is not able to suspend without this workaround is the HP x2 10 Cherry Trail models, this commit adds a DMI based quirk which makes sets honor_wakeup to false on these models. Cc: stable@vger.kernel.org Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20200105160357.97154-3-hdegoede@redhat.com Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers/gpio') diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 2b47d906d536..31fee5e918b7 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -22,12 +22,18 @@ #include "gpiolib-acpi.h" #define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l +#define QUIRK_NO_WAKEUP 0x02l static int run_edge_events_on_boot = -1; module_param(run_edge_events_on_boot, int, 0444); MODULE_PARM_DESC(run_edge_events_on_boot, "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); +static int honor_wakeup = -1; +module_param(honor_wakeup, int, 0444); +MODULE_PARM_DESC(honor_wakeup, + "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto"); + /** * struct acpi_gpio_event - ACPI GPIO event handler data * @@ -283,7 +289,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, event->handle = evt_handle; event->handler = handler; event->irq = irq; - event->irq_is_wake = agpio->wake_capable == ACPI_WAKE_CAPABLE; + event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE; event->pin = pin; event->desc = desc; @@ -1337,6 +1343,23 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] = { }, .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, }, + { + /* + * Various HP X2 10 Cherry Trail models use an external + * embedded-controller connected via I2C + an ACPI GPIO + * event handler. The embedded controller generates various + * spurious wakeup events when suspended. So disable wakeup + * for its handler (it uses the only ACPI GPIO event handler). + * This breaks wakeup when opening the lid, the user needs + * to press the power-button to wakeup the system. The + * alternative is suspend simply not working, which is worse. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), + }, + .driver_data = (void *)QUIRK_NO_WAKEUP, + }, {} /* Terminating entry */ }; @@ -1356,6 +1379,13 @@ static int acpi_gpio_setup_params(void) run_edge_events_on_boot = 1; } + if (honor_wakeup < 0) { + if (quirks & QUIRK_NO_WAKEUP) + honor_wakeup = 0; + else + honor_wakeup = 1; + } + return 0; } -- cgit v1.2.3