]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
gpiolib: acpi: Move quirks to a separate file
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Tue, 13 May 2025 10:00:34 +0000 (13:00 +0300)
committerAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Wed, 21 May 2025 09:25:24 +0000 (12:25 +0300)
The gpiolib-acpi.c is huge enough even without DMI quirks.
Move them to a separate file for a better maintenance.

No functional change intended.

Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
drivers/gpio/Makefile
drivers/gpio/gpiolib-acpi-core.c [moved from drivers/gpio/gpiolib-acpi.c with 79% similarity]
drivers/gpio/gpiolib-acpi-quirks.c [new file with mode: 0644]

index af130882ffeeef8b1d518867bfe1493ec4f21b5f..d9b44b482cc763197355697c11e98e7e39619191 100644 (file)
@@ -10,6 +10,7 @@ obj-$(CONFIG_OF_GPIO)         += gpiolib-of.o
 obj-$(CONFIG_GPIO_CDEV)                += gpiolib-cdev.o
 obj-$(CONFIG_GPIO_SYSFS)       += gpiolib-sysfs.o
 obj-$(CONFIG_GPIO_ACPI)                += gpiolib-acpi.o
+gpiolib-acpi-y                 := gpiolib-acpi-core.o gpiolib-acpi-quirks.o
 obj-$(CONFIG_GPIOLIB)          += gpiolib-swnode.o
 
 # Device drivers. Generally keep list sorted alphabetically
similarity index 79%
rename from drivers/gpio/gpiolib-acpi.c
rename to drivers/gpio/gpiolib-acpi-core.c
index 609e3a7f9636964a8db9fc0fabda13398e635c88..12b24a717e43f17621c054bfc4e9c2e287236d8c 100644 (file)
 #include "gpiolib.h"
 #include "gpiolib-acpi.h"
 
-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 char *ignore_wake;
-module_param(ignore_wake, charp, 0444);
-MODULE_PARM_DESC(ignore_wake,
-                "controller@pin combos on which to ignore the ACPI wake flag "
-                "ignore_wake=controller@pin[,controller@pin[,...]]");
-
-static char *ignore_interrupt;
-module_param(ignore_interrupt, charp, 0444);
-MODULE_PARM_DESC(ignore_interrupt,
-                "controller@pin combos on which to ignore interrupt "
-                "ignore_interrupt=controller@pin[,controller@pin[,...]]");
-
-struct acpi_gpiolib_dmi_quirk {
-       bool no_edge_events_on_boot;
-       char *ignore_wake;
-       char *ignore_interrupt;
-};
-
 /**
  * struct acpi_gpio_event - ACPI GPIO event handler data
  *
@@ -115,17 +92,6 @@ struct acpi_gpio_info {
        unsigned int quirks;
 };
 
-/*
- * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init
- * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
- * late_initcall_sync() handler, so that other builtin drivers can register their
- * OpRegions before the event handlers can run. This list contains GPIO chips
- * for which the acpi_gpiochip_request_irqs() call has been deferred.
- */
-static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
-static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
-static bool acpi_gpio_deferred_req_irqs_done;
-
 static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data)
 {
        /* First check the actual GPIO device */
@@ -350,79 +316,6 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip,
        return desc;
 }
 
-bool acpi_gpio_add_to_deferred_list(struct list_head *list)
-{
-       bool defer;
-
-       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
-       defer = !acpi_gpio_deferred_req_irqs_done;
-       if (defer)
-               list_add(list, &acpi_gpio_deferred_req_irqs_list);
-       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
-
-       return defer;
-}
-
-void acpi_gpio_remove_from_deferred_list(struct list_head *list)
-{
-       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
-       if (!list_empty(list))
-               list_del_init(list);
-       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
-}
-
-int acpi_gpio_need_run_edge_events_on_boot(void)
-{
-       return run_edge_events_on_boot;
-}
-
-bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list, const char *controller_in,
-                             unsigned int pin_in)
-{
-       const char *ignore_list, *controller, *pin_str;
-       unsigned int pin;
-       char *endp;
-       int len;
-
-       switch (list) {
-       case ACPI_GPIO_IGNORE_WAKE:
-               ignore_list = ignore_wake;
-               break;
-       case ACPI_GPIO_IGNORE_INTERRUPT:
-               ignore_list = ignore_interrupt;
-               break;
-       default:
-               return false;
-       }
-
-       controller = ignore_list;
-       while (controller) {
-               pin_str = strchr(controller, '@');
-               if (!pin_str)
-                       goto err;
-
-               len = pin_str - controller;
-               if (len == strlen(controller_in) &&
-                   strncmp(controller, controller_in, len) == 0) {
-                       pin = simple_strtoul(pin_str + 1, &endp, 10);
-                       if (*endp != 0 && *endp != ',')
-                               goto err;
-
-                       if (pin == pin_in)
-                               return true;
-               }
-
-               controller = strchr(controller, ',');
-               if (controller)
-                       controller++;
-       }
-
-       return false;
-err:
-       pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list);
-       return false;
-}
-
 static bool acpi_gpio_irq_is_wake(struct device *parent,
                                  const struct acpi_resource_gpio *agpio)
 {
@@ -1522,242 +1415,3 @@ int acpi_gpio_count(const struct fwnode_handle *fwnode, const char *con_id)
        }
        return count ? count : -ENOENT;
 }
-
-/* Run deferred acpi_gpiochip_request_irqs() */
-static int __init acpi_gpio_handle_deferred_request_irqs(void)
-{
-       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
-       acpi_gpio_process_deferred_list(&acpi_gpio_deferred_req_irqs_list);
-       acpi_gpio_deferred_req_irqs_done = true;
-       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
-
-       return 0;
-}
-/* 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 gpiolib_acpi_quirks[] __initconst = {
-       {
-               /*
-                * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
-                * a non existing micro-USB-B connector which puts the HDMI
-                * DDC pins in GPIO mode, breaking HDMI support.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .no_edge_events_on_boot = true,
-               },
-       },
-       {
-               /*
-                * The Terra Pad 1061 has a micro-USB-B id-pin handler, which
-                * instead of controlling the actual micro-USB-B turns the 5V
-                * boost for its USB-A connector off. The actual micro-USB-B
-                * connector is wired for charging only.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .no_edge_events_on_boot = true,
-               },
-       },
-       {
-               /*
-                * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an
-                * external embedded-controller connected via I2C + an ACPI GPIO
-                * event handler on INT33FFC:02 pin 12, causing spurious wakeups.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "INT33FC:02@12",
-               },
-       },
-       {
-               /*
-                * HP X2 10 models with Cherry Trail SoC + TI PMIC use an
-                * external embedded-controller connected via I2C + an ACPI GPIO
-                * event handler on INT33FF:01 pin 0, causing spurious wakeups.
-                * When suspending by closing the LID, the power to the USB
-                * keyboard is turned off, causing INT0002 ACPI events to
-                * trigger once the XHCI controller notices the keyboard is
-                * gone. So INT0002 events cause spurious wakeups too. Ignoring
-                * EC wakes 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 = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "INT33FF:01@0,INT0002:00@2",
-               },
-       },
-       {
-               /*
-                * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an
-                * external embedded-controller connected via I2C + an ACPI GPIO
-                * event handler on INT33FC:02 pin 28, causing spurious wakeups.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
-                       DMI_MATCH(DMI_BOARD_NAME, "815D"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "INT33FC:02@28",
-               },
-       },
-       {
-               /*
-                * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an
-                * external embedded-controller connected via I2C + an ACPI GPIO
-                * event handler on INT33FF:01 pin 0, causing spurious wakeups.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
-                       DMI_MATCH(DMI_BOARD_NAME, "813E"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "INT33FF:01@0",
-               },
-       },
-       {
-               /*
-                * Interrupt storm caused from edge triggered floating pin
-                * Found in BIOS UX325UAZ.300
-                * https://bugzilla.kernel.org/show_bug.cgi?id=216208
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_interrupt = "AMDI0030:00@18",
-               },
-       },
-       {
-               /*
-                * Spurious wakeups from TP_ATTN# pin
-                * Found in BIOS 1.7.8
-                * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
-                */
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "ELAN0415:00@9",
-               },
-       },
-       {
-               /*
-                * Spurious wakeups from TP_ATTN# pin
-                * Found in BIOS 1.7.8
-                * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
-                */
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "ELAN0415:00@9",
-               },
-       },
-       {
-               /*
-                * Spurious wakeups from TP_ATTN# pin
-                * Found in BIOS 1.7.7
-                */
-               .matches = {
-                       DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "SYNA1202:00@16",
-               },
-       },
-       {
-               /*
-                * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to
-                * a "dolby" button. At the ACPI level an _AEI event-handler
-                * is connected which sets an ACPI variable to 1 on both
-                * edges. This variable can be polled + cleared to 0 using
-                * WMI. But since the variable is set on both edges the WMI
-                * interface is pretty useless even when polling.
-                * So instead the x86-android-tablets code instantiates
-                * a gpio-keys platform device for it.
-                * Ignore the _AEI handler for the pin, so that it is not busy.
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_interrupt = "INT33FC:00@3",
-               },
-       },
-       {
-               /*
-                * Spurious wakeups from TP_ATTN# pin
-                * Found in BIOS 0.35
-                * https://gitlab.freedesktop.org/drm/amd/-/issues/3073
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "GPD"),
-                       DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_wake = "PNP0C50:00@8",
-               },
-       },
-       {
-               /*
-                * Spurious wakeups from GPIO 11
-                * Found in BIOS 1.04
-                * https://gitlab.freedesktop.org/drm/amd/-/issues/3954
-                */
-               .matches = {
-                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"),
-               },
-               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
-                       .ignore_interrupt = "AMDI0030:00@11",
-               },
-       },
-       {} /* Terminating entry */
-};
-
-static int __init acpi_gpio_setup_params(void)
-{
-       const struct acpi_gpiolib_dmi_quirk *quirk = NULL;
-       const struct dmi_system_id *id;
-
-       id = dmi_first_match(gpiolib_acpi_quirks);
-       if (id)
-               quirk = id->driver_data;
-
-       if (run_edge_events_on_boot < 0) {
-               if (quirk && quirk->no_edge_events_on_boot)
-                       run_edge_events_on_boot = 0;
-               else
-                       run_edge_events_on_boot = 1;
-       }
-
-       if (ignore_wake == NULL && quirk && quirk->ignore_wake)
-               ignore_wake = quirk->ignore_wake;
-
-       if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt)
-               ignore_interrupt = quirk->ignore_interrupt;
-
-       return 0;
-}
-
-/* Directly after dmi_setup() which runs as core_initcall() */
-postcore_initcall(acpi_gpio_setup_params);
diff --git a/drivers/gpio/gpiolib-acpi-quirks.c b/drivers/gpio/gpiolib-acpi-quirks.c
new file mode 100644 (file)
index 0000000..2196673
--- /dev/null
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACPI quirks for GPIO ACPI helpers
+ *
+ * Author: Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/dmi.h>
+#include <linux/kstrtox.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/printk.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include "gpiolib-acpi.h"
+
+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 char *ignore_wake;
+module_param(ignore_wake, charp, 0444);
+MODULE_PARM_DESC(ignore_wake,
+                "controller@pin combos on which to ignore the ACPI wake flag "
+                "ignore_wake=controller@pin[,controller@pin[,...]]");
+
+static char *ignore_interrupt;
+module_param(ignore_interrupt, charp, 0444);
+MODULE_PARM_DESC(ignore_interrupt,
+                "controller@pin combos on which to ignore interrupt "
+                "ignore_interrupt=controller@pin[,controller@pin[,...]]");
+
+/*
+ * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init
+ * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a
+ * late_initcall_sync() handler, so that other builtin drivers can register their
+ * OpRegions before the event handlers can run. This list contains GPIO chips
+ * for which the acpi_gpiochip_request_irqs() call has been deferred.
+ */
+static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock);
+static LIST_HEAD(acpi_gpio_deferred_req_irqs_list);
+static bool acpi_gpio_deferred_req_irqs_done;
+
+bool acpi_gpio_add_to_deferred_list(struct list_head *list)
+{
+       bool defer;
+
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       defer = !acpi_gpio_deferred_req_irqs_done;
+       if (defer)
+               list_add(list, &acpi_gpio_deferred_req_irqs_list);
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
+
+       return defer;
+}
+
+void acpi_gpio_remove_from_deferred_list(struct list_head *list)
+{
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       if (!list_empty(list))
+               list_del_init(list);
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
+}
+
+int acpi_gpio_need_run_edge_events_on_boot(void)
+{
+       return run_edge_events_on_boot;
+}
+
+bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list,
+                             const char *controller_in, unsigned int pin_in)
+{
+       const char *ignore_list, *controller, *pin_str;
+       unsigned int pin;
+       char *endp;
+       int len;
+
+       switch (list) {
+       case ACPI_GPIO_IGNORE_WAKE:
+               ignore_list = ignore_wake;
+               break;
+       case ACPI_GPIO_IGNORE_INTERRUPT:
+               ignore_list = ignore_interrupt;
+               break;
+       default:
+               return false;
+       }
+
+       controller = ignore_list;
+       while (controller) {
+               pin_str = strchr(controller, '@');
+               if (!pin_str)
+                       goto err;
+
+               len = pin_str - controller;
+               if (len == strlen(controller_in) &&
+                   strncmp(controller, controller_in, len) == 0) {
+                       pin = simple_strtoul(pin_str + 1, &endp, 10);
+                       if (*endp != 0 && *endp != ',')
+                               goto err;
+
+                       if (pin == pin_in)
+                               return true;
+               }
+
+               controller = strchr(controller, ',');
+               if (controller)
+                       controller++;
+       }
+
+       return false;
+err:
+       pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list);
+       return false;
+}
+
+/* Run deferred acpi_gpiochip_request_irqs() */
+static int __init acpi_gpio_handle_deferred_request_irqs(void)
+{
+       mutex_lock(&acpi_gpio_deferred_req_irqs_lock);
+       acpi_gpio_process_deferred_list(&acpi_gpio_deferred_req_irqs_list);
+       acpi_gpio_deferred_req_irqs_done = true;
+       mutex_unlock(&acpi_gpio_deferred_req_irqs_lock);
+
+       return 0;
+}
+/* We must use _sync so that this runs after the first deferred_probe run */
+late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
+
+struct acpi_gpiolib_dmi_quirk {
+       bool no_edge_events_on_boot;
+       char *ignore_wake;
+       char *ignore_interrupt;
+};
+
+static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
+       {
+               /*
+                * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for
+                * a non existing micro-USB-B connector which puts the HDMI
+                * DDC pins in GPIO mode, breaking HDMI support.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .no_edge_events_on_boot = true,
+               },
+       },
+       {
+               /*
+                * The Terra Pad 1061 has a micro-USB-B id-pin handler, which
+                * instead of controlling the actual micro-USB-B turns the 5V
+                * boost for its USB-A connector off. The actual micro-USB-B
+                * connector is wired for charging only.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .no_edge_events_on_boot = true,
+               },
+       },
+       {
+               /*
+                * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an
+                * external embedded-controller connected via I2C + an ACPI GPIO
+                * event handler on INT33FFC:02 pin 12, causing spurious wakeups.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "INT33FC:02@12",
+               },
+       },
+       {
+               /*
+                * HP X2 10 models with Cherry Trail SoC + TI PMIC use an
+                * external embedded-controller connected via I2C + an ACPI GPIO
+                * event handler on INT33FF:01 pin 0, causing spurious wakeups.
+                * When suspending by closing the LID, the power to the USB
+                * keyboard is turned off, causing INT0002 ACPI events to
+                * trigger once the XHCI controller notices the keyboard is
+                * gone. So INT0002 events cause spurious wakeups too. Ignoring
+                * EC wakes 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 = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "INT33FF:01@0,INT0002:00@2",
+               },
+       },
+       {
+               /*
+                * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an
+                * external embedded-controller connected via I2C + an ACPI GPIO
+                * event handler on INT33FC:02 pin 28, causing spurious wakeups.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
+                       DMI_MATCH(DMI_BOARD_NAME, "815D"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "INT33FC:02@28",
+               },
+       },
+       {
+               /*
+                * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an
+                * external embedded-controller connected via I2C + an ACPI GPIO
+                * event handler on INT33FF:01 pin 0, causing spurious wakeups.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
+                       DMI_MATCH(DMI_BOARD_NAME, "813E"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "INT33FF:01@0",
+               },
+       },
+       {
+               /*
+                * Interrupt storm caused from edge triggered floating pin
+                * Found in BIOS UX325UAZ.300
+                * https://bugzilla.kernel.org/show_bug.cgi?id=216208
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_interrupt = "AMDI0030:00@18",
+               },
+       },
+       {
+               /*
+                * Spurious wakeups from TP_ATTN# pin
+                * Found in BIOS 1.7.8
+                * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "ELAN0415:00@9",
+               },
+       },
+       {
+               /*
+                * Spurious wakeups from TP_ATTN# pin
+                * Found in BIOS 1.7.8
+                * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "ELAN0415:00@9",
+               },
+       },
+       {
+               /*
+                * Spurious wakeups from TP_ATTN# pin
+                * Found in BIOS 1.7.7
+                */
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "SYNA1202:00@16",
+               },
+       },
+       {
+               /*
+                * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to
+                * a "dolby" button. At the ACPI level an _AEI event-handler
+                * is connected which sets an ACPI variable to 1 on both
+                * edges. This variable can be polled + cleared to 0 using
+                * WMI. But since the variable is set on both edges the WMI
+                * interface is pretty useless even when polling.
+                * So instead the x86-android-tablets code instantiates
+                * a gpio-keys platform device for it.
+                * Ignore the _AEI handler for the pin, so that it is not busy.
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_interrupt = "INT33FC:00@3",
+               },
+       },
+       {
+               /*
+                * Spurious wakeups from TP_ATTN# pin
+                * Found in BIOS 0.35
+                * https://gitlab.freedesktop.org/drm/amd/-/issues/3073
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "GPD"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_wake = "PNP0C50:00@8",
+               },
+       },
+       {
+               /*
+                * Spurious wakeups from GPIO 11
+                * Found in BIOS 1.04
+                * https://gitlab.freedesktop.org/drm/amd/-/issues/3954
+                */
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                       DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"),
+               },
+               .driver_data = &(struct acpi_gpiolib_dmi_quirk) {
+                       .ignore_interrupt = "AMDI0030:00@11",
+               },
+       },
+       {} /* Terminating entry */
+};
+
+static int __init acpi_gpio_setup_params(void)
+{
+       const struct acpi_gpiolib_dmi_quirk *quirk = NULL;
+       const struct dmi_system_id *id;
+
+       id = dmi_first_match(gpiolib_acpi_quirks);
+       if (id)
+               quirk = id->driver_data;
+
+       if (run_edge_events_on_boot < 0) {
+               if (quirk && quirk->no_edge_events_on_boot)
+                       run_edge_events_on_boot = 0;
+               else
+                       run_edge_events_on_boot = 1;
+       }
+
+       if (ignore_wake == NULL && quirk && quirk->ignore_wake)
+               ignore_wake = quirk->ignore_wake;
+
+       if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt)
+               ignore_interrupt = quirk->ignore_interrupt;
+
+       return 0;
+}
+
+/* Directly after dmi_setup() which runs as core_initcall() */
+postcore_initcall(acpi_gpio_setup_params);