On Thu, Mar 11, 2021 at 07:28:11PM +0100, gregkh@xxxxxxxxxxxxxxxxxxx wrote: > > The patch below does not apply to the 5.10-stable tree. > If someone wants it applied there, or to any other stable or longterm > tree, then please email the backport, including the original git commit > id to <stable@xxxxxxxxxxxxxxx>. This is strange. I have just cherry-picked it clean on top of v5.10.23. > ------------------ original commit in Linus's tree ------------------ > > From eb441337c7147514ab45036cadf09c3a71e4ce31 Mon Sep 17 00:00:00 2001 > From: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Date: Thu, 25 Feb 2021 18:33:20 +0200 > Subject: [PATCH] gpio: pca953x: Set IRQ type when handle Intel Galileo Gen 2 > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > The commit 0ea683931adb ("gpio: dwapb: Convert driver to using the > GPIO-lib-based IRQ-chip") indeliberately made a regression on how > IRQ line from GPIO I²C expander is handled. I.e. it reveals that > the quirk for Intel Galileo Gen 2 misses the part of setting IRQ type > which previously was predefined by gpio-dwapb driver. Now, we have to > reorganize the approach to call necessary parts, which can be done via > ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER quirk. > > Without this fix and with above mentioned change the kernel hangs > on the first IRQ event with: > > gpio gpiochip3: Persistence not supported for GPIO 1 > irq 32, desc: 62f8fb50, depth: 0, count: 0, unhandled: 0 > ->handle_irq(): 41c7b0ab, handle_bad_irq+0x0/0x40 > ->irq_data.chip(): e03f1e72, 0xc2539218 > ->action(): 0ecc7e6f > ->action->handler(): 8a3db21e, irq_default_primary_handler+0x0/0x10 > IRQ_NOPROBE set > unexpected IRQ trap at vector 20 > > Fixes: ba8c90c61847 ("gpio: pca953x: Override IRQ for one of the expanders on Galileo Gen 2") > Depends-on: 0ea683931adb ("gpio: dwapb: Convert driver to using the GPIO-lib-based IRQ-chip") > Signed-off-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Acked-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > Reviewed-by: Linus Walleij <linus.walleij@xxxxxxxxxx> > > diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c > index 5ea09fd01544..c91d05651596 100644 > --- a/drivers/gpio/gpio-pca953x.c > +++ b/drivers/gpio/gpio-pca953x.c > @@ -113,8 +113,29 @@ MODULE_DEVICE_TABLE(i2c, pca953x_id); > #ifdef CONFIG_GPIO_PCA953X_IRQ > > #include <linux/dmi.h> > -#include <linux/gpio.h> > -#include <linux/list.h> > + > +static const struct acpi_gpio_params pca953x_irq_gpios = { 0, 0, true }; > + > +static const struct acpi_gpio_mapping pca953x_acpi_irq_gpios[] = { > + { "irq-gpios", &pca953x_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER }, > + { } > +}; > + > +static int pca953x_acpi_get_irq(struct device *dev) > +{ > + int ret; > + > + ret = devm_acpi_dev_add_driver_gpios(dev, pca953x_acpi_irq_gpios); > + if (ret) > + dev_warn(dev, "can't add GPIO ACPI mapping\n"); > + > + ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0); > + if (ret < 0) > + return ret; > + > + dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret); > + return ret; > +} > > static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { > { > @@ -133,59 +154,6 @@ static const struct dmi_system_id pca953x_dmi_acpi_irq_info[] = { > }, > {} > }; > - > -#ifdef CONFIG_ACPI > -static int pca953x_acpi_get_pin(struct acpi_resource *ares, void *data) > -{ > - struct acpi_resource_gpio *agpio; > - int *pin = data; > - > - if (acpi_gpio_get_irq_resource(ares, &agpio)) > - *pin = agpio->pin_table[0]; > - return 1; > -} > - > -static int pca953x_acpi_find_pin(struct device *dev) > -{ > - struct acpi_device *adev = ACPI_COMPANION(dev); > - int pin = -ENOENT, ret; > - LIST_HEAD(r); > - > - ret = acpi_dev_get_resources(adev, &r, pca953x_acpi_get_pin, &pin); > - acpi_dev_free_resource_list(&r); > - if (ret < 0) > - return ret; > - > - return pin; > -} > -#else > -static inline int pca953x_acpi_find_pin(struct device *dev) { return -ENXIO; } > -#endif > - > -static int pca953x_acpi_get_irq(struct device *dev) > -{ > - int pin, ret; > - > - pin = pca953x_acpi_find_pin(dev); > - if (pin < 0) > - return pin; > - > - dev_info(dev, "Applying ACPI interrupt quirk (GPIO %d)\n", pin); > - > - if (!gpio_is_valid(pin)) > - return -EINVAL; > - > - ret = gpio_request(pin, "pca953x interrupt"); > - if (ret) > - return ret; > - > - ret = gpio_to_irq(pin); > - > - /* When pin is used as an IRQ, no need to keep it requested */ > - gpio_free(pin); > - > - return ret; > -} > #endif > > static const struct acpi_device_id pca953x_acpi_ids[] = { > -- With Best Regards, Andy Shevchenko