Skip to content

Commit 42062b9

Browse files
committed
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
2 parents 0cf710f + b6c7026 commit 42062b9

File tree

6 files changed

+73
-24
lines changed

6 files changed

+73
-24
lines changed

drivers/acpi/device_sysfs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ static int create_pnp_modalias(struct acpi_device *acpi_dev, char *modalias,
146146
int count;
147147
struct acpi_hardware_id *id;
148148

149+
/* Avoid unnecessarily loading modules for non present devices. */
150+
if (!acpi_device_is_present(acpi_dev))
151+
return 0;
152+
149153
/*
150154
* Since we skip ACPI_DT_NAMESPACE_HID from the modalias below, 0 should
151155
* be returned if ACPI_DT_NAMESPACE_HID is the only ACPI/PNP ID in the

drivers/acpi/ec.c

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,32 +1597,41 @@ static int acpi_ec_add(struct acpi_device *device)
15971597
{
15981598
struct acpi_ec *ec = NULL;
15991599
int ret;
1600+
bool is_ecdt = false;
1601+
acpi_status status;
16001602

16011603
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
16021604
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
16031605

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) {
16091615
ret = -EINVAL;
16101616
goto err_alloc;
1617+
}
16111618
}
16121619

16131620
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);
16261635
} else
16271636
ret = acpi_ec_setup(ec, true);
16281637
if (ret)
@@ -1635,8 +1644,10 @@ static int acpi_ec_add(struct acpi_device *device)
16351644
ret = !!request_region(ec->command_addr, 1, "EC cmd");
16361645
WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
16371646

1638-
/* Reprobe devices depending on the EC */
1639-
acpi_walk_dep_device_list(ec->handle);
1647+
if (!is_ecdt) {
1648+
/* Reprobe devices depending on the EC */
1649+
acpi_walk_dep_device_list(ec->handle);
1650+
}
16401651
acpi_handle_debug(ec->handle, "enumerated.\n");
16411652
return 0;
16421653

@@ -1692,6 +1703,7 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
16921703

16931704
static const struct acpi_device_id ec_device_ids[] = {
16941705
{"PNP0C09", 0},
1706+
{ACPI_ECDT_HID, 0},
16951707
{"", 0},
16961708
};
16971709

@@ -1764,11 +1776,14 @@ static int __init acpi_ec_ecdt_start(void)
17641776
* Note: ec->handle can be valid if this function is called after
17651777
* acpi_ec_add(), hence the fast path.
17661778
*/
1767-
if (boot_ec->handle != ACPI_ROOT_OBJECT)
1768-
handle = boot_ec->handle;
1769-
else if (!acpi_ec_ecdt_get_handle(&handle))
1770-
return -ENODEV;
1771-
return acpi_config_boot_ec(boot_ec, handle, true, true);
1779+
if (boot_ec->handle == ACPI_ROOT_OBJECT) {
1780+
if (!acpi_ec_ecdt_get_handle(&handle))
1781+
return -ENODEV;
1782+
boot_ec->handle = handle;
1783+
}
1784+
1785+
/* Register to ACPI bus with PM ops attached */
1786+
return acpi_bus_register_early_device(ACPI_BUS_TYPE_ECDT_EC);
17721787
}
17731788

17741789
#if 0
@@ -2022,6 +2037,12 @@ int __init acpi_ec_init(void)
20222037

20232038
/* Drivers must be started after acpi_ec_query_init() */
20242039
dsdt_fail = acpi_bus_register_driver(&acpi_ec_driver);
2040+
/*
2041+
* Register ECDT to ACPI bus only when PNP0C09 probe fails. This is
2042+
* useful for platforms (confirmed on ASUS X550ZE) with valid ECDT
2043+
* settings but invalid DSDT settings.
2044+
* https://bugzilla.kernel.org/show_bug.cgi?id=196847
2045+
*/
20252046
ecdt_fail = acpi_ec_ecdt_start();
20262047
return ecdt_fail && dsdt_fail ? -ENODEV : 0;
20272048
}

drivers/acpi/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ bool acpi_device_is_present(const struct acpi_device *adev);
115115
bool acpi_device_is_battery(struct acpi_device *adev);
116116
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
117117
const struct device *dev);
118+
int acpi_bus_register_early_device(int type);
118119

119120
/* --------------------------------------------------------------------------
120121
Device Matching and Notification

drivers/acpi/scan.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,9 @@ static void acpi_device_get_busid(struct acpi_device *device)
10241024
case ACPI_BUS_TYPE_SLEEP_BUTTON:
10251025
strcpy(device->pnp.bus_id, "SLPF");
10261026
break;
1027+
case ACPI_BUS_TYPE_ECDT_EC:
1028+
strcpy(device->pnp.bus_id, "ECDT");
1029+
break;
10271030
default:
10281031
acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer);
10291032
/* Clean up trailing underscores (if any) */
@@ -1304,6 +1307,9 @@ static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
13041307
case ACPI_BUS_TYPE_SLEEP_BUTTON:
13051308
acpi_add_id(pnp, ACPI_BUTTON_HID_SLEEPF);
13061309
break;
1310+
case ACPI_BUS_TYPE_ECDT_EC:
1311+
acpi_add_id(pnp, ACPI_ECDT_HID);
1312+
break;
13071313
}
13081314
}
13091315

@@ -2046,6 +2052,21 @@ void acpi_bus_trim(struct acpi_device *adev)
20462052
}
20472053
EXPORT_SYMBOL_GPL(acpi_bus_trim);
20482054

2055+
int acpi_bus_register_early_device(int type)
2056+
{
2057+
struct acpi_device *device = NULL;
2058+
int result;
2059+
2060+
result = acpi_add_single_object(&device, NULL,
2061+
type, ACPI_STA_DEFAULT);
2062+
if (result)
2063+
return result;
2064+
2065+
device->flags.match_driver = true;
2066+
return device_attach(&device->dev);
2067+
}
2068+
EXPORT_SYMBOL_GPL(acpi_bus_register_early_device);
2069+
20492070
static int acpi_bus_scan_fixed(void)
20502071
{
20512072
int result = 0;

include/acpi/acpi_bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ enum acpi_bus_device_type {
105105
ACPI_BUS_TYPE_THERMAL,
106106
ACPI_BUS_TYPE_POWER_BUTTON,
107107
ACPI_BUS_TYPE_SLEEP_BUTTON,
108+
ACPI_BUS_TYPE_ECDT_EC,
108109
ACPI_BUS_DEVICE_TYPE_COUNT
109110
};
110111

include/acpi/acpi_drivers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#define ACPI_VIDEO_HID "LNXVIDEO"
5959
#define ACPI_BAY_HID "LNXIOBAY"
6060
#define ACPI_DOCK_HID "LNXDOCK"
61+
#define ACPI_ECDT_HID "LNXEC"
6162
/* Quirk for broken IBM BIOSes */
6263
#define ACPI_SMBUS_IBM_HID "SMBUSIBM"
6364

0 commit comments

Comments
 (0)