diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2022-09-02 21:26:48 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2022-09-08 10:06:11 +0200 |
commit | 785b1bd8546eb0d9e70bd4d859583c33aaceeb9b (patch) | |
tree | d29dbf1495977d9482be2d9ef3f26e50e0e050fb /drivers/pinctrl/pinctrl-cy8c95x0.c | |
parent | 618a43ff1f37603164ac82cfa0734a39c079a3e9 (diff) |
pinctrl: cy8c95x0: Override IRQ for one of the expanders on Galileo Gen 1
ACPI table on Intel Galileo Gen 1 has wrong pin number for IRQ resource
of the I²C GPIO expander. Since we know what that number is and luckily
have GPIO bases fixed for SoC's controllers, we may use a simple DMI quirk
to match the platform and retrieve GpioInt() pin on it for the expander in
question.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Link: https://lore.kernel.org/r/20220902182650.83098-15-andriy.shevchenko@linux.intel.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-cy8c95x0.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-cy8c95x0.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index 18a9f5a8ab2d..a42790950182 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -7,7 +7,9 @@ * Author: Naresh Solanki <Naresh.Solanki@9elements.com> */ +#include <linux/acpi.h> #include <linux/bitmap.h> +#include <linux/dmi.h> #include <linux/gpio/driver.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> @@ -73,6 +75,46 @@ static const struct of_device_id cy8c95x0_dt_ids[] = { MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids); +static const struct acpi_gpio_params cy8c95x0_irq_gpios = { 0, 0, true }; + +static const struct acpi_gpio_mapping cy8c95x0_acpi_irq_gpios[] = { + { "irq-gpios", &cy8c95x0_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER }, + { } +}; + +static int cy8c95x0_acpi_get_irq(struct device *dev) +{ + int ret; + + ret = devm_acpi_dev_add_driver_gpios(dev, cy8c95x0_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 cy8c95x0_dmi_acpi_irq_info[] = { + { + /* + * On Intel Galileo Gen 1 board the IRQ pin is provided + * as an absolute number instead of being relative. + * Since first controller (gpio-sch.c) and second + * (gpio-dwapb.c) are at the fixed bases, we may safely + * refer to the number in the global space to get an IRQ + * out of it. + */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"), + }, + }, + {} +}; + #define MAX_BANK 8 #define BANK_SZ 8 #define MAX_LINE (MAX_BANK * BANK_SZ) @@ -1309,6 +1351,12 @@ static int cy8c95x0_probe(struct i2c_client *client) bitmap_set(chip->shiftmask, 0, 20); mutex_init(&chip->i2c_lock); + if (dmi_first_match(cy8c95x0_dmi_acpi_irq_info)) { + ret = cy8c95x0_acpi_get_irq(&client->dev); + if (ret > 0) + client->irq = ret; + } + if (client->irq) { ret = cy8c95x0_irq_setup(chip, client->irq); if (ret) |