From 6d2781310036a8d3fa2b590a6f83a298010fd64a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas <bjorn.helgaas@hp.com> Date: Thu, 30 Apr 2009 09:35:37 -0600 Subject: ACPI: allow drivers to request both device and system notify events System notify events (0x00-0x7f) are common across all device types and should be handled in Linux/ACPI, not in drivers. However, some BIOSes use system notify events in device-specific ways that require the driver to be involved. This patch adds a ACPI_DRIVER_ALL_NOTIFY_EVENTS driver flag. When a driver sets this flag and supplies a .notify method, Linux/ACPI calls the .notify method for ALL notify events on the device, not just the device-specific (0x80-0xff) events. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/bus.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index ae862f1798d..cdfecc0a2ac 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -549,6 +549,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) { int result = 0; struct acpi_device *device = NULL; + struct acpi_driver *driver; blocking_notifier_call_chain(&acpi_bus_notify_list, type, (void *)handle); @@ -629,7 +630,10 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; } - return; + driver = device->driver; + if (driver && driver->ops.notify && + (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) + driver->ops.notify(device, type); } /* -------------------------------------------------------------------------- -- cgit v1.2.3-70-g09d2 From 02c37bd8d0737c31caaed9a65bd7cb80aefb4c9a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas <bjorn.helgaas@hp.com> Date: Fri, 22 May 2009 11:43:41 -0600 Subject: ACPI: simplify notification debug messages This replaces several messages that depend on the acpi_device struct with a single message that uses just the acpi_handle. We should be able to deal with notifications to objects that do not yet have an acpi_device struct. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/bus.c | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index cdfecc0a2ac..eb986385c57 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -551,6 +551,9 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) struct acpi_device *device = NULL; struct acpi_driver *driver; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", + type, handle)); + blocking_notifier_call_chain(&acpi_bus_notify_list, type, (void *)handle); @@ -560,9 +563,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) switch (type) { case ACPI_NOTIFY_BUS_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received BUS CHECK notification for device [%s]\n", - device->pnp.bus_id)); result = acpi_bus_check_scope(device); /* * TBD: We'll need to outsource certain events to non-ACPI @@ -571,9 +571,6 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_CHECK: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received DEVICE CHECK notification for device [%s]\n", - device->pnp.bus_id)); result = acpi_bus_check_device(device, NULL); /* * TBD: We'll need to outsource certain events to non-ACPI @@ -582,44 +579,26 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_WAKE: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received DEVICE WAKE notification for device [%s]\n", - device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_EJECT_REQUEST: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received EJECT REQUEST notification for device [%s]\n", - device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received DEVICE CHECK LIGHT notification for device [%s]\n", - device->pnp.bus_id)); /* TBD: Exactly what does 'light' mean? */ break; case ACPI_NOTIFY_FREQUENCY_MISMATCH: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received FREQUENCY MISMATCH notification for device [%s]\n", - device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_BUS_MODE_MISMATCH: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received BUS MODE MISMATCH notification for device [%s]\n", - device->pnp.bus_id)); /* TBD */ break; case ACPI_NOTIFY_POWER_FAULT: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Received POWER FAULT notification for device [%s]\n", - device->pnp.bus_id)); /* TBD */ break; -- cgit v1.2.3-70-g09d2 From aa8a149c0cc822e3886eb85b95cb2f7d67e5b7e6 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas <bjorn.helgaas@hp.com> Date: Fri, 22 May 2009 11:43:46 -0600 Subject: ACPI: remove unused "status_changed" return value from Check Device handling Remove "status_changed" return from acpi_bus_check_device(). Nobody does anything useful based on its value. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/bus.c | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index eb986385c57..19e78fb0a8d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -450,8 +450,7 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) Notification Handling -------------------------------------------------------------------------- */ -static int -acpi_bus_check_device(struct acpi_device *device, int *status_changed) +static int acpi_bus_check_device(struct acpi_device *device) { acpi_status status = 0; struct acpi_device_status old_status; @@ -460,9 +459,6 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) if (!device) return -EINVAL; - if (status_changed) - *status_changed = 0; - old_status = device->status; /* @@ -471,10 +467,6 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) */ if (device->parent && !device->parent->status.present) { device->status = device->parent->status; - if (STRUCT_TO_INT(old_status) != STRUCT_TO_INT(device->status)) { - if (status_changed) - *status_changed = 1; - } return 0; } @@ -485,9 +477,6 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) return 0; - if (status_changed) - *status_changed = 1; - /* * Device Insertion/Removal */ @@ -505,20 +494,15 @@ acpi_bus_check_device(struct acpi_device *device, int *status_changed) static int acpi_bus_check_scope(struct acpi_device *device) { int result = 0; - int status_changed = 0; - if (!device) return -EINVAL; /* Status Change? */ - result = acpi_bus_check_device(device, &status_changed); + result = acpi_bus_check_device(device); if (result) return result; - if (!status_changed) - return 0; - /* * TBD: Enumerate child devices within this device's scope and * run acpi_bus_check_device()'s on them. @@ -571,7 +555,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_CHECK: - result = acpi_bus_check_device(device, NULL); + result = acpi_bus_check_device(device); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). -- cgit v1.2.3-70-g09d2 From cdd5b8ca122cc4239375dee7fcdc658315c119e4 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas <bjorn.helgaas@hp.com> Date: Fri, 22 May 2009 11:43:51 -0600 Subject: ACPI: remove unused return values from Bus Check & Device Check handling Remove return values from acpi_bus_check_device() and acpi_bus_check_scope() since nobody looks at them. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/bus.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 19e78fb0a8d..2b08c3dc79d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -450,14 +450,13 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) Notification Handling -------------------------------------------------------------------------- */ -static int acpi_bus_check_device(struct acpi_device *device) +static void acpi_bus_check_device(struct acpi_device *device) { - acpi_status status = 0; + acpi_status status; struct acpi_device_status old_status; - if (!device) - return -EINVAL; + return; old_status = device->status; @@ -467,15 +466,15 @@ static int acpi_bus_check_device(struct acpi_device *device) */ if (device->parent && !device->parent->status.present) { device->status = device->parent->status; - return 0; + return; } status = acpi_bus_get_status(device); if (ACPI_FAILURE(status)) - return -ENODEV; + return; if (STRUCT_TO_INT(old_status) == STRUCT_TO_INT(device->status)) - return 0; + return; /* * Device Insertion/Removal @@ -487,28 +486,20 @@ static int acpi_bus_check_device(struct acpi_device *device) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device removal detected\n")); /* TBD: Handle device removal */ } - - return 0; } -static int acpi_bus_check_scope(struct acpi_device *device) +static void acpi_bus_check_scope(struct acpi_device *device) { - int result = 0; - if (!device) - return -EINVAL; + return; /* Status Change? */ - result = acpi_bus_check_device(device); - if (result) - return result; + acpi_bus_check_device(device); /* * TBD: Enumerate child devices within this device's scope and * run acpi_bus_check_device()'s on them. */ - - return 0; } static BLOCKING_NOTIFIER_HEAD(acpi_bus_notify_list); @@ -531,7 +522,6 @@ EXPORT_SYMBOL_GPL(unregister_acpi_bus_notifier); */ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) { - int result = 0; struct acpi_device *device = NULL; struct acpi_driver *driver; @@ -547,7 +537,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) switch (type) { case ACPI_NOTIFY_BUS_CHECK: - result = acpi_bus_check_scope(device); + acpi_bus_check_scope(device); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). @@ -555,7 +545,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_CHECK: - result = acpi_bus_check_device(device); + acpi_bus_check_device(device); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). -- cgit v1.2.3-70-g09d2 From ff754e2e85557ed7244385f0f2053c80e8ac9948 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas <bjorn.helgaas@hp.com> Date: Fri, 22 May 2009 11:43:56 -0600 Subject: ACPI: use handle, not device, in system notification path This patch changes the global system notification path so it uses the acpi_handle, not the acpi_device. System notifications often deal with device presence and status change. In these cases, we may not have an acpi_device. For example, we may get a Device Check notification on an object that previously was not present. Since the object was not present, we would not have had an acpi_device for it. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Len Brown <len.brown@intel.com> --- drivers/acpi/bus.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 2b08c3dc79d..2876fc70c3a 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -450,11 +450,14 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) Notification Handling -------------------------------------------------------------------------- */ -static void acpi_bus_check_device(struct acpi_device *device) +static void acpi_bus_check_device(acpi_handle handle) { + struct acpi_device *device; acpi_status status; struct acpi_device_status old_status; + if (acpi_bus_get_device(handle, &device)) + return; if (!device) return; @@ -488,13 +491,10 @@ static void acpi_bus_check_device(struct acpi_device *device) } } -static void acpi_bus_check_scope(struct acpi_device *device) +static void acpi_bus_check_scope(acpi_handle handle) { - if (!device) - return; - /* Status Change? */ - acpi_bus_check_device(device); + acpi_bus_check_device(handle); /* * TBD: Enumerate child devices within this device's scope and @@ -531,13 +531,10 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) blocking_notifier_call_chain(&acpi_bus_notify_list, type, (void *)handle); - if (acpi_bus_get_device(handle, &device)) - return; - switch (type) { case ACPI_NOTIFY_BUS_CHECK: - acpi_bus_check_scope(device); + acpi_bus_check_scope(handle); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). @@ -545,7 +542,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; case ACPI_NOTIFY_DEVICE_CHECK: - acpi_bus_check_device(device); + acpi_bus_check_device(handle); /* * TBD: We'll need to outsource certain events to non-ACPI * drivers via the device manager (device.c). @@ -583,10 +580,13 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; } - driver = device->driver; - if (driver && driver->ops.notify && - (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) - driver->ops.notify(device, type); + acpi_bus_get_device(handle, &device); + if (device) { + driver = device->driver; + if (driver && driver->ops.notify && + (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) + driver->ops.notify(device, type); + } } /* -------------------------------------------------------------------------- -- cgit v1.2.3-70-g09d2