Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge patch series "gpiolib: acpi: Split quirks to its own file"

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

The GPIO ACPI helpers use a few quirks which consumes approximately 20%
of the file. Besides that the necessary bits are sparse and being directly
referred. Split them to a separate file. There is no functional change.

For the new file I used the Hans' authorship of Hans as he the author of
all those bits (expect very tiny changes made by this series).

Link: https://lore.kernel.org/r/20250513100514.2492545-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

+392 -331
+1
drivers/gpio/Makefile
··· 10 10 obj-$(CONFIG_GPIO_CDEV) += gpiolib-cdev.o 11 11 obj-$(CONFIG_GPIO_SYSFS) += gpiolib-sysfs.o 12 12 obj-$(CONFIG_GPIO_ACPI) += gpiolib-acpi.o 13 + gpiolib-acpi-y := gpiolib-acpi-core.o gpiolib-acpi-quirks.o 13 14 obj-$(CONFIG_GPIOLIB) += gpiolib-swnode.o 14 15 15 16 # Device drivers. Generally keep list sorted alphabetically
+363
drivers/gpio/gpiolib-acpi-quirks.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * ACPI quirks for GPIO ACPI helpers 4 + * 5 + * Author: Hans de Goede <hdegoede@redhat.com> 6 + */ 7 + 8 + #include <linux/dmi.h> 9 + #include <linux/kstrtox.h> 10 + #include <linux/list.h> 11 + #include <linux/module.h> 12 + #include <linux/mutex.h> 13 + #include <linux/printk.h> 14 + #include <linux/string.h> 15 + #include <linux/types.h> 16 + 17 + #include "gpiolib-acpi.h" 18 + 19 + static int run_edge_events_on_boot = -1; 20 + module_param(run_edge_events_on_boot, int, 0444); 21 + MODULE_PARM_DESC(run_edge_events_on_boot, 22 + "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); 23 + 24 + static char *ignore_wake; 25 + module_param(ignore_wake, charp, 0444); 26 + MODULE_PARM_DESC(ignore_wake, 27 + "controller@pin combos on which to ignore the ACPI wake flag " 28 + "ignore_wake=controller@pin[,controller@pin[,...]]"); 29 + 30 + static char *ignore_interrupt; 31 + module_param(ignore_interrupt, charp, 0444); 32 + MODULE_PARM_DESC(ignore_interrupt, 33 + "controller@pin combos on which to ignore interrupt " 34 + "ignore_interrupt=controller@pin[,controller@pin[,...]]"); 35 + 36 + /* 37 + * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init 38 + * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a 39 + * late_initcall_sync() handler, so that other builtin drivers can register their 40 + * OpRegions before the event handlers can run. This list contains GPIO chips 41 + * for which the acpi_gpiochip_request_irqs() call has been deferred. 42 + */ 43 + static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock); 44 + static LIST_HEAD(acpi_gpio_deferred_req_irqs_list); 45 + static bool acpi_gpio_deferred_req_irqs_done; 46 + 47 + bool acpi_gpio_add_to_deferred_list(struct list_head *list) 48 + { 49 + bool defer; 50 + 51 + mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 52 + defer = !acpi_gpio_deferred_req_irqs_done; 53 + if (defer) 54 + list_add(list, &acpi_gpio_deferred_req_irqs_list); 55 + mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 56 + 57 + return defer; 58 + } 59 + 60 + void acpi_gpio_remove_from_deferred_list(struct list_head *list) 61 + { 62 + mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 63 + if (!list_empty(list)) 64 + list_del_init(list); 65 + mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 66 + } 67 + 68 + int acpi_gpio_need_run_edge_events_on_boot(void) 69 + { 70 + return run_edge_events_on_boot; 71 + } 72 + 73 + bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list, 74 + const char *controller_in, unsigned int pin_in) 75 + { 76 + const char *ignore_list, *controller, *pin_str; 77 + unsigned int pin; 78 + char *endp; 79 + int len; 80 + 81 + switch (list) { 82 + case ACPI_GPIO_IGNORE_WAKE: 83 + ignore_list = ignore_wake; 84 + break; 85 + case ACPI_GPIO_IGNORE_INTERRUPT: 86 + ignore_list = ignore_interrupt; 87 + break; 88 + default: 89 + return false; 90 + } 91 + 92 + controller = ignore_list; 93 + while (controller) { 94 + pin_str = strchr(controller, '@'); 95 + if (!pin_str) 96 + goto err; 97 + 98 + len = pin_str - controller; 99 + if (len == strlen(controller_in) && 100 + strncmp(controller, controller_in, len) == 0) { 101 + pin = simple_strtoul(pin_str + 1, &endp, 10); 102 + if (*endp != 0 && *endp != ',') 103 + goto err; 104 + 105 + if (pin == pin_in) 106 + return true; 107 + } 108 + 109 + controller = strchr(controller, ','); 110 + if (controller) 111 + controller++; 112 + } 113 + 114 + return false; 115 + err: 116 + pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list); 117 + return false; 118 + } 119 + 120 + /* Run deferred acpi_gpiochip_request_irqs() */ 121 + static int __init acpi_gpio_handle_deferred_request_irqs(void) 122 + { 123 + mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 124 + acpi_gpio_process_deferred_list(&acpi_gpio_deferred_req_irqs_list); 125 + acpi_gpio_deferred_req_irqs_done = true; 126 + mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 127 + 128 + return 0; 129 + } 130 + /* We must use _sync so that this runs after the first deferred_probe run */ 131 + late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); 132 + 133 + struct acpi_gpiolib_dmi_quirk { 134 + bool no_edge_events_on_boot; 135 + char *ignore_wake; 136 + char *ignore_interrupt; 137 + }; 138 + 139 + static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { 140 + { 141 + /* 142 + * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for 143 + * a non existing micro-USB-B connector which puts the HDMI 144 + * DDC pins in GPIO mode, breaking HDMI support. 145 + */ 146 + .matches = { 147 + DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), 148 + DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), 149 + }, 150 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 151 + .no_edge_events_on_boot = true, 152 + }, 153 + }, 154 + { 155 + /* 156 + * The Terra Pad 1061 has a micro-USB-B id-pin handler, which 157 + * instead of controlling the actual micro-USB-B turns the 5V 158 + * boost for its USB-A connector off. The actual micro-USB-B 159 + * connector is wired for charging only. 160 + */ 161 + .matches = { 162 + DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), 163 + DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), 164 + }, 165 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 166 + .no_edge_events_on_boot = true, 167 + }, 168 + }, 169 + { 170 + /* 171 + * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an 172 + * external embedded-controller connected via I2C + an ACPI GPIO 173 + * event handler on INT33FFC:02 pin 12, causing spurious wakeups. 174 + */ 175 + .matches = { 176 + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 177 + DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"), 178 + }, 179 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 180 + .ignore_wake = "INT33FC:02@12", 181 + }, 182 + }, 183 + { 184 + /* 185 + * HP X2 10 models with Cherry Trail SoC + TI PMIC use an 186 + * external embedded-controller connected via I2C + an ACPI GPIO 187 + * event handler on INT33FF:01 pin 0, causing spurious wakeups. 188 + * When suspending by closing the LID, the power to the USB 189 + * keyboard is turned off, causing INT0002 ACPI events to 190 + * trigger once the XHCI controller notices the keyboard is 191 + * gone. So INT0002 events cause spurious wakeups too. Ignoring 192 + * EC wakes breaks wakeup when opening the lid, the user needs 193 + * to press the power-button to wakeup the system. The 194 + * alternative is suspend simply not working, which is worse. 195 + */ 196 + .matches = { 197 + DMI_MATCH(DMI_SYS_VENDOR, "HP"), 198 + DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), 199 + }, 200 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 201 + .ignore_wake = "INT33FF:01@0,INT0002:00@2", 202 + }, 203 + }, 204 + { 205 + /* 206 + * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an 207 + * external embedded-controller connected via I2C + an ACPI GPIO 208 + * event handler on INT33FC:02 pin 28, causing spurious wakeups. 209 + */ 210 + .matches = { 211 + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 212 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), 213 + DMI_MATCH(DMI_BOARD_NAME, "815D"), 214 + }, 215 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 216 + .ignore_wake = "INT33FC:02@28", 217 + }, 218 + }, 219 + { 220 + /* 221 + * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an 222 + * external embedded-controller connected via I2C + an ACPI GPIO 223 + * event handler on INT33FF:01 pin 0, causing spurious wakeups. 224 + */ 225 + .matches = { 226 + DMI_MATCH(DMI_SYS_VENDOR, "HP"), 227 + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), 228 + DMI_MATCH(DMI_BOARD_NAME, "813E"), 229 + }, 230 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 231 + .ignore_wake = "INT33FF:01@0", 232 + }, 233 + }, 234 + { 235 + /* 236 + * Interrupt storm caused from edge triggered floating pin 237 + * Found in BIOS UX325UAZ.300 238 + * https://bugzilla.kernel.org/show_bug.cgi?id=216208 239 + */ 240 + .matches = { 241 + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 242 + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"), 243 + }, 244 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 245 + .ignore_interrupt = "AMDI0030:00@18", 246 + }, 247 + }, 248 + { 249 + /* 250 + * Spurious wakeups from TP_ATTN# pin 251 + * Found in BIOS 1.7.8 252 + * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 253 + */ 254 + .matches = { 255 + DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 256 + }, 257 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 258 + .ignore_wake = "ELAN0415:00@9", 259 + }, 260 + }, 261 + { 262 + /* 263 + * Spurious wakeups from TP_ATTN# pin 264 + * Found in BIOS 1.7.8 265 + * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 266 + */ 267 + .matches = { 268 + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 269 + }, 270 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 271 + .ignore_wake = "ELAN0415:00@9", 272 + }, 273 + }, 274 + { 275 + /* 276 + * Spurious wakeups from TP_ATTN# pin 277 + * Found in BIOS 1.7.7 278 + */ 279 + .matches = { 280 + DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), 281 + }, 282 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 283 + .ignore_wake = "SYNA1202:00@16", 284 + }, 285 + }, 286 + { 287 + /* 288 + * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to 289 + * a "dolby" button. At the ACPI level an _AEI event-handler 290 + * is connected which sets an ACPI variable to 1 on both 291 + * edges. This variable can be polled + cleared to 0 using 292 + * WMI. But since the variable is set on both edges the WMI 293 + * interface is pretty useless even when polling. 294 + * So instead the x86-android-tablets code instantiates 295 + * a gpio-keys platform device for it. 296 + * Ignore the _AEI handler for the pin, so that it is not busy. 297 + */ 298 + .matches = { 299 + DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), 300 + DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), 301 + }, 302 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 303 + .ignore_interrupt = "INT33FC:00@3", 304 + }, 305 + }, 306 + { 307 + /* 308 + * Spurious wakeups from TP_ATTN# pin 309 + * Found in BIOS 0.35 310 + * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 311 + */ 312 + .matches = { 313 + DMI_MATCH(DMI_SYS_VENDOR, "GPD"), 314 + DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), 315 + }, 316 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 317 + .ignore_wake = "PNP0C50:00@8", 318 + }, 319 + }, 320 + { 321 + /* 322 + * Spurious wakeups from GPIO 11 323 + * Found in BIOS 1.04 324 + * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 325 + */ 326 + .matches = { 327 + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 328 + DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), 329 + }, 330 + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 331 + .ignore_interrupt = "AMDI0030:00@11", 332 + }, 333 + }, 334 + {} /* Terminating entry */ 335 + }; 336 + 337 + static int __init acpi_gpio_setup_params(void) 338 + { 339 + const struct acpi_gpiolib_dmi_quirk *quirk = NULL; 340 + const struct dmi_system_id *id; 341 + 342 + id = dmi_first_match(gpiolib_acpi_quirks); 343 + if (id) 344 + quirk = id->driver_data; 345 + 346 + if (run_edge_events_on_boot < 0) { 347 + if (quirk && quirk->no_edge_events_on_boot) 348 + run_edge_events_on_boot = 0; 349 + else 350 + run_edge_events_on_boot = 1; 351 + } 352 + 353 + if (ignore_wake == NULL && quirk && quirk->ignore_wake) 354 + ignore_wake = quirk->ignore_wake; 355 + 356 + if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt) 357 + ignore_interrupt = quirk->ignore_interrupt; 358 + 359 + return 0; 360 + } 361 + 362 + /* Directly after dmi_setup() which runs as core_initcall() */ 363 + postcore_initcall(acpi_gpio_setup_params);
+13 -331
drivers/gpio/gpiolib-acpi.c drivers/gpio/gpiolib-acpi-core.c
··· 23 23 #include "gpiolib.h" 24 24 #include "gpiolib-acpi.h" 25 25 26 - static int run_edge_events_on_boot = -1; 27 - module_param(run_edge_events_on_boot, int, 0444); 28 - MODULE_PARM_DESC(run_edge_events_on_boot, 29 - "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); 30 - 31 - static char *ignore_wake; 32 - module_param(ignore_wake, charp, 0444); 33 - MODULE_PARM_DESC(ignore_wake, 34 - "controller@pin combos on which to ignore the ACPI wake flag " 35 - "ignore_wake=controller@pin[,controller@pin[,...]]"); 36 - 37 - static char *ignore_interrupt; 38 - module_param(ignore_interrupt, charp, 0444); 39 - MODULE_PARM_DESC(ignore_interrupt, 40 - "controller@pin combos on which to ignore interrupt " 41 - "ignore_interrupt=controller@pin[,controller@pin[,...]]"); 42 - 43 - struct acpi_gpiolib_dmi_quirk { 44 - bool no_edge_events_on_boot; 45 - char *ignore_wake; 46 - char *ignore_interrupt; 47 - }; 48 - 49 26 /** 50 27 * struct acpi_gpio_event - ACPI GPIO event handler data 51 28 * ··· 91 114 unsigned int debounce; 92 115 unsigned int quirks; 93 116 }; 94 - 95 - /* 96 - * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init 97 - * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a 98 - * late_initcall_sync() handler, so that other builtin drivers can register their 99 - * OpRegions before the event handlers can run. This list contains GPIO chips 100 - * for which the acpi_gpiochip_request_irqs() call has been deferred. 101 - */ 102 - static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock); 103 - static LIST_HEAD(acpi_gpio_deferred_req_irqs_list); 104 - static bool acpi_gpio_deferred_req_irqs_done; 105 117 106 118 static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) 107 119 { ··· 234 268 event->irq_requested = true; 235 269 236 270 /* Make sure we trigger the initial state of edge-triggered IRQs */ 237 - if (run_edge_events_on_boot && 271 + if (acpi_gpio_need_run_edge_events_on_boot() && 238 272 (event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) { 239 273 value = gpiod_get_raw_value_cansleep(event->desc); 240 274 if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) || ··· 316 350 return desc; 317 351 } 318 352 319 - static bool acpi_gpio_in_ignore_list(const char *ignore_list, const char *controller_in, 320 - unsigned int pin_in) 321 - { 322 - const char *controller, *pin_str; 323 - unsigned int pin; 324 - char *endp; 325 - int len; 326 - 327 - controller = ignore_list; 328 - while (controller) { 329 - pin_str = strchr(controller, '@'); 330 - if (!pin_str) 331 - goto err; 332 - 333 - len = pin_str - controller; 334 - if (len == strlen(controller_in) && 335 - strncmp(controller, controller_in, len) == 0) { 336 - pin = simple_strtoul(pin_str + 1, &endp, 10); 337 - if (*endp != 0 && *endp != ',') 338 - goto err; 339 - 340 - if (pin == pin_in) 341 - return true; 342 - } 343 - 344 - controller = strchr(controller, ','); 345 - if (controller) 346 - controller++; 347 - } 348 - 349 - return false; 350 - err: 351 - pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list); 352 - return false; 353 - } 354 - 355 353 static bool acpi_gpio_irq_is_wake(struct device *parent, 356 354 const struct acpi_resource_gpio *agpio) 357 355 { ··· 324 394 if (agpio->wake_capable != ACPI_WAKE_CAPABLE) 325 395 return false; 326 396 327 - if (acpi_gpio_in_ignore_list(ignore_wake, dev_name(parent), pin)) { 397 + if (acpi_gpio_in_ignore_list(ACPI_GPIO_IGNORE_WAKE, dev_name(parent), pin)) { 328 398 dev_info(parent, "Ignoring wakeup on pin %u\n", pin); 329 399 return false; 330 400 } ··· 367 437 if (!handler) 368 438 return AE_OK; 369 439 370 - if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) { 440 + if (acpi_gpio_in_ignore_list(ACPI_GPIO_IGNORE_INTERRUPT, dev_name(chip->parent), pin)) { 371 441 dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin); 372 442 return AE_OK; 373 443 } ··· 455 525 struct acpi_gpio_chip *acpi_gpio; 456 526 acpi_handle handle; 457 527 acpi_status status; 458 - bool defer; 459 528 460 529 if (!chip->parent || !chip->to_irq) 461 530 return; ··· 473 544 acpi_walk_resources(handle, METHOD_NAME__AEI, 474 545 acpi_gpiochip_alloc_event, acpi_gpio); 475 546 476 - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 477 - defer = !acpi_gpio_deferred_req_irqs_done; 478 - if (defer) 479 - list_add(&acpi_gpio->deferred_req_irqs_list_entry, 480 - &acpi_gpio_deferred_req_irqs_list); 481 - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 482 - 483 - if (defer) 547 + if (acpi_gpio_add_to_deferred_list(&acpi_gpio->deferred_req_irqs_list_entry)) 484 548 return; 485 549 486 550 acpi_gpiochip_request_irqs(acpi_gpio); ··· 505 583 if (ACPI_FAILURE(status)) 506 584 return; 507 585 508 - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 509 - if (!list_empty(&acpi_gpio->deferred_req_irqs_list_entry)) 510 - list_del_init(&acpi_gpio->deferred_req_irqs_list_entry); 511 - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 586 + acpi_gpio_remove_from_deferred_list(&acpi_gpio->deferred_req_irqs_list_entry); 512 587 513 588 list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) { 514 589 if (event->irq_requested) { ··· 522 603 } 523 604 } 524 605 EXPORT_SYMBOL_GPL(acpi_gpiochip_free_interrupts); 606 + 607 + void __init acpi_gpio_process_deferred_list(struct list_head *list) 608 + { 609 + struct acpi_gpio_chip *acpi_gpio, *tmp; 610 + 611 + list_for_each_entry_safe(acpi_gpio, tmp, list, deferred_req_irqs_list_entry) 612 + acpi_gpiochip_request_irqs(acpi_gpio); 613 + } 525 614 526 615 int acpi_dev_add_driver_gpios(struct acpi_device *adev, 527 616 const struct acpi_gpio_mapping *gpios) ··· 1415 1488 } 1416 1489 return count ? count : -ENOENT; 1417 1490 } 1418 - 1419 - /* Run deferred acpi_gpiochip_request_irqs() */ 1420 - static int __init acpi_gpio_handle_deferred_request_irqs(void) 1421 - { 1422 - struct acpi_gpio_chip *acpi_gpio, *tmp; 1423 - 1424 - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); 1425 - list_for_each_entry_safe(acpi_gpio, tmp, 1426 - &acpi_gpio_deferred_req_irqs_list, 1427 - deferred_req_irqs_list_entry) 1428 - acpi_gpiochip_request_irqs(acpi_gpio); 1429 - 1430 - acpi_gpio_deferred_req_irqs_done = true; 1431 - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); 1432 - 1433 - return 0; 1434 - } 1435 - /* We must use _sync so that this runs after the first deferred_probe run */ 1436 - late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); 1437 - 1438 - static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { 1439 - { 1440 - /* 1441 - * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for 1442 - * a non existing micro-USB-B connector which puts the HDMI 1443 - * DDC pins in GPIO mode, breaking HDMI support. 1444 - */ 1445 - .matches = { 1446 - DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), 1447 - DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), 1448 - }, 1449 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1450 - .no_edge_events_on_boot = true, 1451 - }, 1452 - }, 1453 - { 1454 - /* 1455 - * The Terra Pad 1061 has a micro-USB-B id-pin handler, which 1456 - * instead of controlling the actual micro-USB-B turns the 5V 1457 - * boost for its USB-A connector off. The actual micro-USB-B 1458 - * connector is wired for charging only. 1459 - */ 1460 - .matches = { 1461 - DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), 1462 - DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), 1463 - }, 1464 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1465 - .no_edge_events_on_boot = true, 1466 - }, 1467 - }, 1468 - { 1469 - /* 1470 - * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an 1471 - * external embedded-controller connected via I2C + an ACPI GPIO 1472 - * event handler on INT33FFC:02 pin 12, causing spurious wakeups. 1473 - */ 1474 - .matches = { 1475 - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1476 - DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"), 1477 - }, 1478 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1479 - .ignore_wake = "INT33FC:02@12", 1480 - }, 1481 - }, 1482 - { 1483 - /* 1484 - * HP X2 10 models with Cherry Trail SoC + TI PMIC use an 1485 - * external embedded-controller connected via I2C + an ACPI GPIO 1486 - * event handler on INT33FF:01 pin 0, causing spurious wakeups. 1487 - * When suspending by closing the LID, the power to the USB 1488 - * keyboard is turned off, causing INT0002 ACPI events to 1489 - * trigger once the XHCI controller notices the keyboard is 1490 - * gone. So INT0002 events cause spurious wakeups too. Ignoring 1491 - * EC wakes breaks wakeup when opening the lid, the user needs 1492 - * to press the power-button to wakeup the system. The 1493 - * alternative is suspend simply not working, which is worse. 1494 - */ 1495 - .matches = { 1496 - DMI_MATCH(DMI_SYS_VENDOR, "HP"), 1497 - DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), 1498 - }, 1499 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1500 - .ignore_wake = "INT33FF:01@0,INT0002:00@2", 1501 - }, 1502 - }, 1503 - { 1504 - /* 1505 - * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an 1506 - * external embedded-controller connected via I2C + an ACPI GPIO 1507 - * event handler on INT33FC:02 pin 28, causing spurious wakeups. 1508 - */ 1509 - .matches = { 1510 - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 1511 - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), 1512 - DMI_MATCH(DMI_BOARD_NAME, "815D"), 1513 - }, 1514 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1515 - .ignore_wake = "INT33FC:02@28", 1516 - }, 1517 - }, 1518 - { 1519 - /* 1520 - * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an 1521 - * external embedded-controller connected via I2C + an ACPI GPIO 1522 - * event handler on INT33FF:01 pin 0, causing spurious wakeups. 1523 - */ 1524 - .matches = { 1525 - DMI_MATCH(DMI_SYS_VENDOR, "HP"), 1526 - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), 1527 - DMI_MATCH(DMI_BOARD_NAME, "813E"), 1528 - }, 1529 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1530 - .ignore_wake = "INT33FF:01@0", 1531 - }, 1532 - }, 1533 - { 1534 - /* 1535 - * Interrupt storm caused from edge triggered floating pin 1536 - * Found in BIOS UX325UAZ.300 1537 - * https://bugzilla.kernel.org/show_bug.cgi?id=216208 1538 - */ 1539 - .matches = { 1540 - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), 1541 - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"), 1542 - }, 1543 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1544 - .ignore_interrupt = "AMDI0030:00@18", 1545 - }, 1546 - }, 1547 - { 1548 - /* 1549 - * Spurious wakeups from TP_ATTN# pin 1550 - * Found in BIOS 1.7.8 1551 - * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 1552 - */ 1553 - .matches = { 1554 - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), 1555 - }, 1556 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1557 - .ignore_wake = "ELAN0415:00@9", 1558 - }, 1559 - }, 1560 - { 1561 - /* 1562 - * Spurious wakeups from TP_ATTN# pin 1563 - * Found in BIOS 1.7.8 1564 - * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 1565 - */ 1566 - .matches = { 1567 - DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), 1568 - }, 1569 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1570 - .ignore_wake = "ELAN0415:00@9", 1571 - }, 1572 - }, 1573 - { 1574 - /* 1575 - * Spurious wakeups from TP_ATTN# pin 1576 - * Found in BIOS 1.7.7 1577 - */ 1578 - .matches = { 1579 - DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), 1580 - }, 1581 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1582 - .ignore_wake = "SYNA1202:00@16", 1583 - }, 1584 - }, 1585 - { 1586 - /* 1587 - * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to 1588 - * a "dolby" button. At the ACPI level an _AEI event-handler 1589 - * is connected which sets an ACPI variable to 1 on both 1590 - * edges. This variable can be polled + cleared to 0 using 1591 - * WMI. But since the variable is set on both edges the WMI 1592 - * interface is pretty useless even when polling. 1593 - * So instead the x86-android-tablets code instantiates 1594 - * a gpio-keys platform device for it. 1595 - * Ignore the _AEI handler for the pin, so that it is not busy. 1596 - */ 1597 - .matches = { 1598 - DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), 1599 - DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), 1600 - }, 1601 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1602 - .ignore_interrupt = "INT33FC:00@3", 1603 - }, 1604 - }, 1605 - { 1606 - /* 1607 - * Spurious wakeups from TP_ATTN# pin 1608 - * Found in BIOS 0.35 1609 - * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 1610 - */ 1611 - .matches = { 1612 - DMI_MATCH(DMI_SYS_VENDOR, "GPD"), 1613 - DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), 1614 - }, 1615 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1616 - .ignore_wake = "PNP0C50:00@8", 1617 - }, 1618 - }, 1619 - { 1620 - /* 1621 - * Spurious wakeups from GPIO 11 1622 - * Found in BIOS 1.04 1623 - * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 1624 - */ 1625 - .matches = { 1626 - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 1627 - DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), 1628 - }, 1629 - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { 1630 - .ignore_interrupt = "AMDI0030:00@11", 1631 - }, 1632 - }, 1633 - {} /* Terminating entry */ 1634 - }; 1635 - 1636 - static int __init acpi_gpio_setup_params(void) 1637 - { 1638 - const struct acpi_gpiolib_dmi_quirk *quirk = NULL; 1639 - const struct dmi_system_id *id; 1640 - 1641 - id = dmi_first_match(gpiolib_acpi_quirks); 1642 - if (id) 1643 - quirk = id->driver_data; 1644 - 1645 - if (run_edge_events_on_boot < 0) { 1646 - if (quirk && quirk->no_edge_events_on_boot) 1647 - run_edge_events_on_boot = 0; 1648 - else 1649 - run_edge_events_on_boot = 1; 1650 - } 1651 - 1652 - if (ignore_wake == NULL && quirk && quirk->ignore_wake) 1653 - ignore_wake = quirk->ignore_wake; 1654 - 1655 - if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt) 1656 - ignore_interrupt = quirk->ignore_interrupt; 1657 - 1658 - return 0; 1659 - } 1660 - 1661 - /* Directly after dmi_setup() which runs as core_initcall() */ 1662 - postcore_initcall(acpi_gpio_setup_params);
+15
drivers/gpio/gpiolib-acpi.h
··· 58 58 } 59 59 #endif 60 60 61 + void acpi_gpio_process_deferred_list(struct list_head *list); 62 + 63 + bool acpi_gpio_add_to_deferred_list(struct list_head *list); 64 + void acpi_gpio_remove_from_deferred_list(struct list_head *list); 65 + 66 + int acpi_gpio_need_run_edge_events_on_boot(void); 67 + 68 + enum acpi_gpio_ignore_list { 69 + ACPI_GPIO_IGNORE_WAKE, 70 + ACPI_GPIO_IGNORE_INTERRUPT, 71 + }; 72 + 73 + bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list, 74 + const char *controller_in, unsigned int pin_in); 75 + 61 76 #endif /* GPIOLIB_ACPI_H */