From fc2e0a8326d1b21d11ef8213298e5302867fed2c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 26 Aug 2014 01:29:21 +0200 Subject: ACPI / scan: Allow ACPI drivers to bind to PNP device objects We generally don't allow ACPI drivers to bind to ACPI device objects that companion "physical" device objects are created for to avoid situations in which two different drivers may attempt to handle one device at the same time. Recent ACPI device enumeration rework extended that approach to ACPI PNP devices by starting to use a scan handler for enumerating them. However, we previously allowed ACPI drivers to bind to ACPI device objects with existing PNP device companions and changing that led to functional regressions on some systems. For this reason, add a special check for PNP devices in acpi_device_probe() so that ACPI drivers can bind to ACPI device objects having existing PNP device companions as before. Fixes: eec15edbb0e1 (ACPI / PNP: use device ID list for PNPACPI device enumeration) Link: https://bugzilla.kernel.org/show_bug.cgi?id=81511 Link: https://bugzilla.kernel.org/show_bug.cgi?id=81971 Reported-by: Gabriele Mazzotta Reported-by: Dirk Griesbach Cc: 3.16+ # 3.16+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0a817ad24f16..fd17fe7f93f2 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -975,7 +975,7 @@ static int acpi_device_probe(struct device *dev) struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver); int ret; - if (acpi_dev->handler) + if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev)) return -EINVAL; if (!acpi_drv->ops.add) -- cgit v1.2.2 From 236105db632c6279a020f78c83e22eaef746006b Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Tue, 26 Aug 2014 01:29:24 +0200 Subject: ACPI: Run fixed event device notifications in process context Currently, notify callbacks for fixed button events are run from interrupt context. That is not necessary and after commit 0bf6368ee8f2 (ACPI / button: Add ACPI Button event via netlink routine) it causes netlink routines to be called from interrupt context which is not correct. Also, that is different from non-fixed device events (including non-fixed button events) whose notify callbacks are all executed from process context. For the above reasons, make fixed button device notify callbacks run in process context which will avoid the deadlock when using netlink to report button events to user space. Fixes: 0bf6368ee8f2 (ACPI / button: Add ACPI Button event via netlink routine) Link: https://lkml.org/lkml/2014/8/21/606 Reported-by: Benjamin Block Reported-by: Knut Petersen Signed-off-by: Lan Tianyu [rjw: Function names, subject and changelog.] Cc: 3.15+ # 3.15+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fd17fe7f93f2..9a9298994e26 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -922,12 +922,17 @@ static void acpi_device_notify(acpi_handle handle, u32 event, void *data) device->driver->ops.notify(device, event); } -static acpi_status acpi_device_notify_fixed(void *data) +static void acpi_device_notify_fixed(void *data) { struct acpi_device *device = data; /* Fixed hardware devices have no handles */ acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); +} + +static acpi_status acpi_device_fixed_event(void *data) +{ + acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data); return AE_OK; } @@ -938,12 +943,12 @@ static int acpi_device_install_notify_handler(struct acpi_device *device) if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_notify_fixed, + acpi_device_fixed_event, device); else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) status = acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_notify_fixed, + acpi_device_fixed_event, device); else status = acpi_install_notify_handler(device->handle, @@ -960,10 +965,10 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device) { if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, - acpi_device_notify_fixed); + acpi_device_fixed_event); else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, - acpi_device_notify_fixed); + acpi_device_fixed_event); else acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, acpi_device_notify); -- cgit v1.2.2 From a383b68d9fe9864c4d3b86f67ad6488f58136435 Mon Sep 17 00:00:00 2001 From: Yasuaki Ishimatsu Date: Wed, 3 Sep 2014 13:39:13 +0900 Subject: ACPI / scan: not cache _SUN value in struct acpi_device_pnp The _SUN device indentification object is not guaranteed to return the same value every time it is executed, so we should not cache its return value, but rather execute it every time as needed. If it is cached, an incorrect stale value may be used in some situations. This issue was exposed by commit 202317a573b2 (ACPI / scan: Add acpi_device objects for all device nodes in the namespace). Fix it by avoiding to cache the return value of _SUN. Fixes: 202317a573b2 (ACPI / scan: Add acpi_device objects for all device nodes in the namespace) Signed-off-by: Yasuaki Ishimatsu Cc: 3.14+ # 3.14+ [ rjw: Changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9a9298994e26..3bf7764659a4 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -667,8 +667,14 @@ static ssize_t acpi_device_sun_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); + acpi_status status; + unsigned long long sun; + + status = acpi_evaluate_integer(acpi_dev->handle, "_SUN", NULL, &sun); + if (ACPI_FAILURE(status)) + return -ENODEV; - return sprintf(buf, "%lu\n", acpi_dev->pnp.sun); + return sprintf(buf, "%llu\n", sun); } static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); @@ -690,7 +696,6 @@ static int acpi_device_setup_files(struct acpi_device *dev) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; acpi_status status; - unsigned long long sun; int result = 0; /* @@ -731,14 +736,10 @@ static int acpi_device_setup_files(struct acpi_device *dev) if (dev->pnp.unique_id) result = device_create_file(&dev->dev, &dev_attr_uid); - status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun); - if (ACPI_SUCCESS(status)) { - dev->pnp.sun = (unsigned long)sun; + if (acpi_has_method(dev->handle, "_SUN")) { result = device_create_file(&dev->dev, &dev_attr_sun); if (result) goto end; - } else { - dev->pnp.sun = (unsigned long)-1; } if (acpi_has_method(dev->handle, "_STA")) { -- cgit v1.2.2 From 8ab17fc92e49bc2b8fff9d220c19bf50ec9c1158 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 21 Sep 2014 02:58:18 +0200 Subject: ACPI / hotplug: Generate online uevents for ACPI containers Commit 46394fd01 (ACPI / hotplug: Move container-specific code out of the core) removed the generation of "online" uevents for containers, because "add" uevents are now generated for them automatically when container system devices are registered. However, there are user space tools that need to be notified when the container and all of its children have been enumerated, which doesn't happen any more. For this reason, add a mechanism allowing "online" uevents to be generated for ACPI containers after enumerating the container along with all of its children. Fixes: 46394fd01 (ACPI / hotplug: Move container-specific code out of the core) Reported-and-tested-by: Yasuaki Ishimatsu Cc: 3.14+ # 3.14+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3bf7764659a4..1c9a664c1705 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -2189,6 +2189,9 @@ static void acpi_bus_attach(struct acpi_device *device) ok: list_for_each_entry(child, &device->children, node) acpi_bus_attach(child); + + if (device->handler && device->handler->hotplug.notify_online) + device->handler->hotplug.notify_online(device); } /** -- cgit v1.2.2 From 98d28d0e59160d2d6cb3f6a9050723ac40f89669 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 12 Sep 2014 11:33:10 +0300 Subject: ACPI / scan: Correct error return value of create_modalias() There is a typo, it should be negative -errno instead. Signed-off-by: Mika Westerberg Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/acpi/scan.c') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 3bf7764659a4..d5e6ac5042d8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -130,7 +130,7 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, list_for_each_entry(id, &acpi_dev->pnp.ids, list) { count = snprintf(&modalias[len], size, "%s:", id->id); if (count < 0) - return EINVAL; + return -EINVAL; if (count >= size) return -ENOMEM; len += count; -- cgit v1.2.2