pinctrl: cy8c95x0: Override IRQ for one of the expanders on Galileo Gen 1
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Fri, 2 Sep 2022 18:26:48 +0000 (21:26 +0300)
committerLinus Walleij <linus.walleij@linaro.org>
Thu, 8 Sep 2022 08:06:11 +0000 (10:06 +0200)
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>
drivers/pinctrl/pinctrl-cy8c95x0.c

index 18a9f5a8ab2de34f23b011d6535d7d619fcb98a4..a427909501820de04be6f691d7a0a2e883102329 100644 (file)
@@ -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)