lkml.org 
[lkml]   [2021]   [Mar]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.11 018/306] gpio: pca953x: Set IRQ type when handle Intel Galileo Gen 2
    Date
    From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

    commit eb441337c7147514ab45036cadf09c3a71e4ce31 upstream.

    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@linux.intel.com>
    Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
    Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/gpio/gpio-pca953x.c | 78 ++++++++++++--------------------------------
    1 file changed, 23 insertions(+), 55 deletions(-)

    --- a/drivers/gpio/gpio-pca953x.c
    +++ b/drivers/gpio/gpio-pca953x.c
    @@ -112,8 +112,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[] = {
    {
    @@ -132,59 +153,6 @@ static const struct dmi_system_id pca953
    },
    {}
    };
    -
    -#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[] = {

    \
     
     \ /
      Last update: 2021-03-15 15:04    [W:7.003 / U:0.204 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site