aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2014-08-25 19:29:24 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-08-25 19:29:24 -0400
commit236105db632c6279a020f78c83e22eaef746006b (patch)
tree9d18863a173a5a2af1c0cb88a656631906be04f5 /drivers/acpi/scan.c
parentfc2e0a8326d1b21d11ef8213298e5302867fed2c (diff)
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 <bebl@mageta.org> Reported-by: Knut Petersen <Knut_Petersen@t-online.de> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> [rjw: Function names, subject and changelog.] Cc: 3.15+ <stable@vger.kernel.org> # 3.15+ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c15
1 files changed, 10 insertions, 5 deletions
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)
922 device->driver->ops.notify(device, event); 922 device->driver->ops.notify(device, event);
923} 923}
924 924
925static acpi_status acpi_device_notify_fixed(void *data) 925static void acpi_device_notify_fixed(void *data)
926{ 926{
927 struct acpi_device *device = data; 927 struct acpi_device *device = data;
928 928
929 /* Fixed hardware devices have no handles */ 929 /* Fixed hardware devices have no handles */
930 acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device); 930 acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
931}
932
933static acpi_status acpi_device_fixed_event(void *data)
934{
935 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data);
931 return AE_OK; 936 return AE_OK;
932} 937}
933 938
@@ -938,12 +943,12 @@ static int acpi_device_install_notify_handler(struct acpi_device *device)
938 if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) 943 if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
939 status = 944 status =
940 acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, 945 acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
941 acpi_device_notify_fixed, 946 acpi_device_fixed_event,
942 device); 947 device);
943 else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) 948 else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
944 status = 949 status =
945 acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, 950 acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
946 acpi_device_notify_fixed, 951 acpi_device_fixed_event,
947 device); 952 device);
948 else 953 else
949 status = acpi_install_notify_handler(device->handle, 954 status = acpi_install_notify_handler(device->handle,
@@ -960,10 +965,10 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
960{ 965{
961 if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON) 966 if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
962 acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, 967 acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
963 acpi_device_notify_fixed); 968 acpi_device_fixed_event);
964 else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON) 969 else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
965 acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON, 970 acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
966 acpi_device_notify_fixed); 971 acpi_device_fixed_event);
967 else 972 else
968 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 973 acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
969 acpi_device_notify); 974 acpi_device_notify);