|
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 | * |
@@ -115,17 +92,6 @@ struct acpi_gpio_info { |
115 | 92 | unsigned int quirks; |
116 | 93 | }; |
117 | 94 |
|
118 | | -/* |
119 | | - * For GPIO chips which call acpi_gpiochip_request_interrupts() before late_init |
120 | | - * (so builtin drivers) we register the ACPI GpioInt IRQ handlers from a |
121 | | - * late_initcall_sync() handler, so that other builtin drivers can register their |
122 | | - * OpRegions before the event handlers can run. This list contains GPIO chips |
123 | | - * for which the acpi_gpiochip_request_irqs() call has been deferred. |
124 | | - */ |
125 | | -static DEFINE_MUTEX(acpi_gpio_deferred_req_irqs_lock); |
126 | | -static LIST_HEAD(acpi_gpio_deferred_req_irqs_list); |
127 | | -static bool acpi_gpio_deferred_req_irqs_done; |
128 | | - |
129 | 95 | static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) |
130 | 96 | { |
131 | 97 | /* First check the actual GPIO device */ |
@@ -350,79 +316,6 @@ static struct gpio_desc *acpi_request_own_gpiod(struct gpio_chip *chip, |
350 | 316 | return desc; |
351 | 317 | } |
352 | 318 |
|
353 | | -bool acpi_gpio_add_to_deferred_list(struct list_head *list) |
354 | | -{ |
355 | | - bool defer; |
356 | | - |
357 | | - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); |
358 | | - defer = !acpi_gpio_deferred_req_irqs_done; |
359 | | - if (defer) |
360 | | - list_add(list, &acpi_gpio_deferred_req_irqs_list); |
361 | | - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); |
362 | | - |
363 | | - return defer; |
364 | | -} |
365 | | - |
366 | | -void acpi_gpio_remove_from_deferred_list(struct list_head *list) |
367 | | -{ |
368 | | - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); |
369 | | - if (!list_empty(list)) |
370 | | - list_del_init(list); |
371 | | - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); |
372 | | -} |
373 | | - |
374 | | -int acpi_gpio_need_run_edge_events_on_boot(void) |
375 | | -{ |
376 | | - return run_edge_events_on_boot; |
377 | | -} |
378 | | - |
379 | | -bool acpi_gpio_in_ignore_list(enum acpi_gpio_ignore_list list, const char *controller_in, |
380 | | - unsigned int pin_in) |
381 | | -{ |
382 | | - const char *ignore_list, *controller, *pin_str; |
383 | | - unsigned int pin; |
384 | | - char *endp; |
385 | | - int len; |
386 | | - |
387 | | - switch (list) { |
388 | | - case ACPI_GPIO_IGNORE_WAKE: |
389 | | - ignore_list = ignore_wake; |
390 | | - break; |
391 | | - case ACPI_GPIO_IGNORE_INTERRUPT: |
392 | | - ignore_list = ignore_interrupt; |
393 | | - break; |
394 | | - default: |
395 | | - return false; |
396 | | - } |
397 | | - |
398 | | - controller = ignore_list; |
399 | | - while (controller) { |
400 | | - pin_str = strchr(controller, '@'); |
401 | | - if (!pin_str) |
402 | | - goto err; |
403 | | - |
404 | | - len = pin_str - controller; |
405 | | - if (len == strlen(controller_in) && |
406 | | - strncmp(controller, controller_in, len) == 0) { |
407 | | - pin = simple_strtoul(pin_str + 1, &endp, 10); |
408 | | - if (*endp != 0 && *endp != ',') |
409 | | - goto err; |
410 | | - |
411 | | - if (pin == pin_in) |
412 | | - return true; |
413 | | - } |
414 | | - |
415 | | - controller = strchr(controller, ','); |
416 | | - if (controller) |
417 | | - controller++; |
418 | | - } |
419 | | - |
420 | | - return false; |
421 | | -err: |
422 | | - pr_err_once("Error: Invalid value for gpiolib_acpi.ignore_...: %s\n", ignore_list); |
423 | | - return false; |
424 | | -} |
425 | | - |
426 | 319 | static bool acpi_gpio_irq_is_wake(struct device *parent, |
427 | 320 | const struct acpi_resource_gpio *agpio) |
428 | 321 | { |
@@ -1522,242 +1415,3 @@ int acpi_gpio_count(const struct fwnode_handle *fwnode, const char *con_id) |
1522 | 1415 | } |
1523 | 1416 | return count ? count : -ENOENT; |
1524 | 1417 | } |
1525 | | - |
1526 | | -/* Run deferred acpi_gpiochip_request_irqs() */ |
1527 | | -static int __init acpi_gpio_handle_deferred_request_irqs(void) |
1528 | | -{ |
1529 | | - mutex_lock(&acpi_gpio_deferred_req_irqs_lock); |
1530 | | - acpi_gpio_process_deferred_list(&acpi_gpio_deferred_req_irqs_list); |
1531 | | - acpi_gpio_deferred_req_irqs_done = true; |
1532 | | - mutex_unlock(&acpi_gpio_deferred_req_irqs_lock); |
1533 | | - |
1534 | | - return 0; |
1535 | | -} |
1536 | | -/* We must use _sync so that this runs after the first deferred_probe run */ |
1537 | | -late_initcall_sync(acpi_gpio_handle_deferred_request_irqs); |
1538 | | - |
1539 | | -static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { |
1540 | | - { |
1541 | | - /* |
1542 | | - * The Minix Neo Z83-4 has a micro-USB-B id-pin handler for |
1543 | | - * a non existing micro-USB-B connector which puts the HDMI |
1544 | | - * DDC pins in GPIO mode, breaking HDMI support. |
1545 | | - */ |
1546 | | - .matches = { |
1547 | | - DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), |
1548 | | - DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
1549 | | - }, |
1550 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1551 | | - .no_edge_events_on_boot = true, |
1552 | | - }, |
1553 | | - }, |
1554 | | - { |
1555 | | - /* |
1556 | | - * The Terra Pad 1061 has a micro-USB-B id-pin handler, which |
1557 | | - * instead of controlling the actual micro-USB-B turns the 5V |
1558 | | - * boost for its USB-A connector off. The actual micro-USB-B |
1559 | | - * connector is wired for charging only. |
1560 | | - */ |
1561 | | - .matches = { |
1562 | | - DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), |
1563 | | - DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), |
1564 | | - }, |
1565 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1566 | | - .no_edge_events_on_boot = true, |
1567 | | - }, |
1568 | | - }, |
1569 | | - { |
1570 | | - /* |
1571 | | - * The Dell Venue 10 Pro 5055, with Bay Trail SoC + TI PMIC uses an |
1572 | | - * external embedded-controller connected via I2C + an ACPI GPIO |
1573 | | - * event handler on INT33FFC:02 pin 12, causing spurious wakeups. |
1574 | | - */ |
1575 | | - .matches = { |
1576 | | - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
1577 | | - DMI_MATCH(DMI_PRODUCT_NAME, "Venue 10 Pro 5055"), |
1578 | | - }, |
1579 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1580 | | - .ignore_wake = "INT33FC:02@12", |
1581 | | - }, |
1582 | | - }, |
1583 | | - { |
1584 | | - /* |
1585 | | - * HP X2 10 models with Cherry Trail SoC + TI PMIC use an |
1586 | | - * external embedded-controller connected via I2C + an ACPI GPIO |
1587 | | - * event handler on INT33FF:01 pin 0, causing spurious wakeups. |
1588 | | - * When suspending by closing the LID, the power to the USB |
1589 | | - * keyboard is turned off, causing INT0002 ACPI events to |
1590 | | - * trigger once the XHCI controller notices the keyboard is |
1591 | | - * gone. So INT0002 events cause spurious wakeups too. Ignoring |
1592 | | - * EC wakes breaks wakeup when opening the lid, the user needs |
1593 | | - * to press the power-button to wakeup the system. The |
1594 | | - * alternative is suspend simply not working, which is worse. |
1595 | | - */ |
1596 | | - .matches = { |
1597 | | - DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
1598 | | - DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), |
1599 | | - }, |
1600 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1601 | | - .ignore_wake = "INT33FF:01@0,INT0002:00@2", |
1602 | | - }, |
1603 | | - }, |
1604 | | - { |
1605 | | - /* |
1606 | | - * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an |
1607 | | - * external embedded-controller connected via I2C + an ACPI GPIO |
1608 | | - * event handler on INT33FC:02 pin 28, causing spurious wakeups. |
1609 | | - */ |
1610 | | - .matches = { |
1611 | | - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
1612 | | - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), |
1613 | | - DMI_MATCH(DMI_BOARD_NAME, "815D"), |
1614 | | - }, |
1615 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1616 | | - .ignore_wake = "INT33FC:02@28", |
1617 | | - }, |
1618 | | - }, |
1619 | | - { |
1620 | | - /* |
1621 | | - * HP X2 10 models with Cherry Trail SoC + AXP288 PMIC use an |
1622 | | - * external embedded-controller connected via I2C + an ACPI GPIO |
1623 | | - * event handler on INT33FF:01 pin 0, causing spurious wakeups. |
1624 | | - */ |
1625 | | - .matches = { |
1626 | | - DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
1627 | | - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), |
1628 | | - DMI_MATCH(DMI_BOARD_NAME, "813E"), |
1629 | | - }, |
1630 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1631 | | - .ignore_wake = "INT33FF:01@0", |
1632 | | - }, |
1633 | | - }, |
1634 | | - { |
1635 | | - /* |
1636 | | - * Interrupt storm caused from edge triggered floating pin |
1637 | | - * Found in BIOS UX325UAZ.300 |
1638 | | - * https://bugzilla.kernel.org/show_bug.cgi?id=216208 |
1639 | | - */ |
1640 | | - .matches = { |
1641 | | - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
1642 | | - DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UAZ_UM325UAZ"), |
1643 | | - }, |
1644 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1645 | | - .ignore_interrupt = "AMDI0030:00@18", |
1646 | | - }, |
1647 | | - }, |
1648 | | - { |
1649 | | - /* |
1650 | | - * Spurious wakeups from TP_ATTN# pin |
1651 | | - * Found in BIOS 1.7.8 |
1652 | | - * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 |
1653 | | - */ |
1654 | | - .matches = { |
1655 | | - DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"), |
1656 | | - }, |
1657 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1658 | | - .ignore_wake = "ELAN0415:00@9", |
1659 | | - }, |
1660 | | - }, |
1661 | | - { |
1662 | | - /* |
1663 | | - * Spurious wakeups from TP_ATTN# pin |
1664 | | - * Found in BIOS 1.7.8 |
1665 | | - * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 |
1666 | | - */ |
1667 | | - .matches = { |
1668 | | - DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), |
1669 | | - }, |
1670 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1671 | | - .ignore_wake = "ELAN0415:00@9", |
1672 | | - }, |
1673 | | - }, |
1674 | | - { |
1675 | | - /* |
1676 | | - * Spurious wakeups from TP_ATTN# pin |
1677 | | - * Found in BIOS 1.7.7 |
1678 | | - */ |
1679 | | - .matches = { |
1680 | | - DMI_MATCH(DMI_BOARD_NAME, "NH5xAx"), |
1681 | | - }, |
1682 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1683 | | - .ignore_wake = "SYNA1202:00@16", |
1684 | | - }, |
1685 | | - }, |
1686 | | - { |
1687 | | - /* |
1688 | | - * On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to |
1689 | | - * a "dolby" button. At the ACPI level an _AEI event-handler |
1690 | | - * is connected which sets an ACPI variable to 1 on both |
1691 | | - * edges. This variable can be polled + cleared to 0 using |
1692 | | - * WMI. But since the variable is set on both edges the WMI |
1693 | | - * interface is pretty useless even when polling. |
1694 | | - * So instead the x86-android-tablets code instantiates |
1695 | | - * a gpio-keys platform device for it. |
1696 | | - * Ignore the _AEI handler for the pin, so that it is not busy. |
1697 | | - */ |
1698 | | - .matches = { |
1699 | | - DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), |
1700 | | - DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), |
1701 | | - }, |
1702 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1703 | | - .ignore_interrupt = "INT33FC:00@3", |
1704 | | - }, |
1705 | | - }, |
1706 | | - { |
1707 | | - /* |
1708 | | - * Spurious wakeups from TP_ATTN# pin |
1709 | | - * Found in BIOS 0.35 |
1710 | | - * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 |
1711 | | - */ |
1712 | | - .matches = { |
1713 | | - DMI_MATCH(DMI_SYS_VENDOR, "GPD"), |
1714 | | - DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), |
1715 | | - }, |
1716 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1717 | | - .ignore_wake = "PNP0C50:00@8", |
1718 | | - }, |
1719 | | - }, |
1720 | | - { |
1721 | | - /* |
1722 | | - * Spurious wakeups from GPIO 11 |
1723 | | - * Found in BIOS 1.04 |
1724 | | - * https://gitlab.freedesktop.org/drm/amd/-/issues/3954 |
1725 | | - */ |
1726 | | - .matches = { |
1727 | | - DMI_MATCH(DMI_SYS_VENDOR, "Acer"), |
1728 | | - DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 14"), |
1729 | | - }, |
1730 | | - .driver_data = &(struct acpi_gpiolib_dmi_quirk) { |
1731 | | - .ignore_interrupt = "AMDI0030:00@11", |
1732 | | - }, |
1733 | | - }, |
1734 | | - {} /* Terminating entry */ |
1735 | | -}; |
1736 | | - |
1737 | | -static int __init acpi_gpio_setup_params(void) |
1738 | | -{ |
1739 | | - const struct acpi_gpiolib_dmi_quirk *quirk = NULL; |
1740 | | - const struct dmi_system_id *id; |
1741 | | - |
1742 | | - id = dmi_first_match(gpiolib_acpi_quirks); |
1743 | | - if (id) |
1744 | | - quirk = id->driver_data; |
1745 | | - |
1746 | | - if (run_edge_events_on_boot < 0) { |
1747 | | - if (quirk && quirk->no_edge_events_on_boot) |
1748 | | - run_edge_events_on_boot = 0; |
1749 | | - else |
1750 | | - run_edge_events_on_boot = 1; |
1751 | | - } |
1752 | | - |
1753 | | - if (ignore_wake == NULL && quirk && quirk->ignore_wake) |
1754 | | - ignore_wake = quirk->ignore_wake; |
1755 | | - |
1756 | | - if (ignore_interrupt == NULL && quirk && quirk->ignore_interrupt) |
1757 | | - ignore_interrupt = quirk->ignore_interrupt; |
1758 | | - |
1759 | | - return 0; |
1760 | | -} |
1761 | | - |
1762 | | -/* Directly after dmi_setup() which runs as core_initcall() */ |
1763 | | -postcore_initcall(acpi_gpio_setup_params); |
0 commit comments