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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'acpi-4.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI fixes from Rafael Wysocki:
"These fix a regression related to the ACPI EC handling during system
suspend/resume on some platforms and prevent modalias from being
exposed to user space for ACPI device object with "not functional and
not present" status.

Specifics:

- Fix an ACPI EC driver regression (from the 4.9 cycle) causing the
driver's power management operations to be omitted during system
suspend/resume on platforms where the EC instance from the ECDT
table is used instead of the one from the DSDT (Lv Zheng).

- Prevent modalias from being exposed to user space for ACPI device
objects with _STA returning 0 (not present and not functional) to
prevent driver modules from being loaded automatically for hardware
that is not actually present on some platforms (Hans de Goede)"

* tag 'acpi-4.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
ACPI / EC: Fix regression related to PM ops support in ECDT device
ACPI / bus: Leave modalias empty for devices which are not present

+73 -24
+4
drivers/acpi/device_sysfs.c
··· 146 146 int count; 147 147 struct acpi_hardware_id *id; 148 148 149 + /* Avoid unnecessarily loading modules for non present devices. */ 150 + if (!acpi_device_is_present(acpi_dev)) 151 + return 0; 152 + 149 153 /* 150 154 * Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should 151 155 * be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the
+45 -24
drivers/acpi/ec.c
··· 1597 1597 { 1598 1598 struct acpi_ec *ec = NULL; 1599 1599 int ret; 1600 + bool is_ecdt = false; 1601 + acpi_status status; 1600 1602 1601 1603 strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); 1602 1604 strcpy(acpi_device_class(device), ACPI_EC_CLASS); 1603 1605 1604 - ec = acpi_ec_alloc(); 1605 - if (!ec) 1606 - return -ENOMEM; 1607 - if (ec_parse_device(device->handle, 0, ec, NULL) != 1608 - AE_CTRL_TERMINATE) { 1606 + if (!strcmp(acpi_device_hid(device), ACPI_ECDT_HID)) { 1607 + is_ecdt = true; 1608 + ec = boot_ec; 1609 + } else { 1610 + ec = acpi_ec_alloc(); 1611 + if (!ec) 1612 + return -ENOMEM; 1613 + status = ec_parse_device(device->handle, 0, ec, NULL); 1614 + if (status != AE_CTRL_TERMINATE) { 1609 1615 ret = -EINVAL; 1610 1616 goto err_alloc; 1617 + } 1611 1618 } 1612 1619 1613 1620 if (acpi_is_boot_ec(ec)) { 1614 - boot_ec_is_ecdt = false; 1615 - /* 1616 - * Trust PNP0C09 namespace location rather than ECDT ID. 1617 - * 1618 - * But trust ECDT GPE rather than _GPE because of ASUS quirks, 1619 - * so do not change boot_ec->gpe to ec->gpe. 1620 - */ 1621 - boot_ec->handle = ec->handle; 1622 - acpi_handle_debug(ec->handle, "duplicated.\n"); 1623 - acpi_ec_free(ec); 1624 - ec = boot_ec; 1625 - ret = acpi_config_boot_ec(ec, ec->handle, true, false); 1621 + boot_ec_is_ecdt = is_ecdt; 1622 + if (!is_ecdt) { 1623 + /* 1624 + * Trust PNP0C09 namespace location rather than 1625 + * ECDT ID. But trust ECDT GPE rather than _GPE 1626 + * because of ASUS quirks, so do not change 1627 + * boot_ec->gpe to ec->gpe. 1628 + */ 1629 + boot_ec->handle = ec->handle; 1630 + acpi_handle_debug(ec->handle, "duplicated.\n"); 1631 + acpi_ec_free(ec); 1632 + ec = boot_ec; 1633 + } 1634 + ret = acpi_config_boot_ec(ec, ec->handle, true, is_ecdt); 1626 1635 } else 1627 1636 ret = acpi_ec_setup(ec, true); 1628 1637 if (ret) ··· 1644 1635 ret = !!request_region(ec->command_addr, 1, "EC cmd"); 1645 1636 WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); 1646 1637 1647 - /* Reprobe devices depending on the EC */ 1648 - acpi_walk_dep_device_list(ec->handle); 1638 + if (!is_ecdt) { 1639 + /* Reprobe devices depending on the EC */ 1640 + acpi_walk_dep_device_list(ec->handle); 1641 + } 1649 1642 acpi_handle_debug(ec->handle, "enumerated.\n"); 1650 1643 return 0; 1651 1644 ··· 1703 1692 1704 1693 static const struct acpi_device_id ec_device_ids[] = { 1705 1694 {"PNP0C09", 0}, 1695 + {ACPI_ECDT_HID, 0}, 1706 1696 {"", 0}, 1707 1697 }; 1708 1698 ··· 1776 1764 * Note: ec->handle can be valid if this function is called after 1777 1765 * acpi_ec_add(), hence the fast path. 1778 1766 */ 1779 - if (boot_ec->handle != ACPI_ROOT_OBJECT) 1780 - handle = boot_ec->handle; 1781 - else if (!acpi_ec_ecdt_get_handle(&handle)) 1782 - return -ENODEV; 1783 - return acpi_config_boot_ec(boot_ec, handle, true, true); 1767 + if (boot_ec->handle == ACPI_ROOT_OBJECT) { 1768 + if (!acpi_ec_ecdt_get_handle(&handle)) 1769 + return -ENODEV; 1770 + boot_ec->handle = handle; 1771 + } 1772 + 1773 + /* Register to ACPI bus with PM ops attached */ 1774 + return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC); 1784 1775 } 1785 1776 1786 1777 #if 0 ··· 2037 2022 2038 2023 /* Drivers must be started after acpi_ec_query_init() */ 2039 2024 dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver); 2025 + /* 2026 + * Register ECDT to ACPI bus only when PNP0C09 probe fails. This is 2027 + * useful for platforms (confirmed on ASUS X550ZE) with valid ECDT 2028 + * settings but invalid DSDT settings. 2029 + * https://bugzilla.kernel.org/show_bug.cgi?id=196847 2030 + */ 2040 2031 ecdt_fail = acpi_ec_ecdt_start(); 2041 2032 return ecdt_fail && dsdt_fail ? -ENODEV : 0; 2042 2033 }
+1
drivers/acpi/internal.h
··· 115 115 bool acpi_device_is_battery(struct acpi_device *adev); 116 116 bool acpi_device_is_first_physical_node(struct acpi_device *adev, 117 117 const struct device *dev); 118 + int acpi_bus_register_early_device(int type); 118 119 119 120 /* -------------------------------------------------------------------------- 120 121 Device Matching and Notification
+21
drivers/acpi/scan.c
··· 1024 1024 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1025 1025 strcpy(device->pnp.bus_id, "SLPF"); 1026 1026 break; 1027 + case ACPI_BUS_TYPE_ECDT_EC: 1028 + strcpy(device->pnp.bus_id, "ECDT"); 1029 + break; 1027 1030 default: 1028 1031 acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer); 1029 1032 /* Clean up trailing underscores (if any) */ ··· 1306 1303 break; 1307 1304 case ACPI_BUS_TYPE_SLEEP_BUTTON: 1308 1305 acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF); 1306 + break; 1307 + case ACPI_BUS_TYPE_ECDT_EC: 1308 + acpi_add_id(pnp, ACPI_ECDT_HID); 1309 1309 break; 1310 1310 } 1311 1311 } ··· 2051 2045 acpi_device_clear_enumerated(adev); 2052 2046 } 2053 2047 EXPORT_SYMBOL_GPL(acpi_bus_trim); 2048 + 2049 + int acpi_bus_register_early_device(int type) 2050 + { 2051 + struct acpi_device *device = NULL; 2052 + int result; 2053 + 2054 + result = acpi_add_single_object(&device, NULL, 2055 + type, ACPI_STA_DEFAULT); 2056 + if (result) 2057 + return result; 2058 + 2059 + device->flags.match_driver = true; 2060 + return device_attach(&device->dev); 2061 + } 2062 + EXPORT_SYMBOL_GPL(acpi_bus_register_early_device); 2054 2063 2055 2064 static int acpi_bus_scan_fixed(void) 2056 2065 {
+1
include/acpi/acpi_bus.h
··· 105 105 ACPI_BUS_TYPE_THERMAL, 106 106 ACPI_BUS_TYPE_POWER_BUTTON, 107 107 ACPI_BUS_TYPE_SLEEP_BUTTON, 108 + ACPI_BUS_TYPE_ECDT_EC, 108 109 ACPI_BUS_DEVICE_TYPE_COUNT 109 110 }; 110 111
+1
include/acpi/acpi_drivers.h
··· 58 58 #define ACPI_VIDEO_HID "LNXVIDEO" 59 59 #define ACPI_BAY_HID "LNXIOBAY" 60 60 #define ACPI_DOCK_HID "LNXDOCK" 61 + #define ACPI_ECDT_HID "LNXEC" 61 62 /* Quirk for broken IBM BIOSes */ 62 63 #define ACPI_SMBUS_IBM_HID "SMBUSIBM" 63 64