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