linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2 00/19] ACPI: cleanups for hotplug
@ 2009-08-31 22:32 Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
                   ` (18 more replies)
  0 siblings, 19 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

I'm working to make the Linux/ACPI code handle hotplug notification
events.  This should ultimately allow us to remove the existing
hotplug code scattered through the ACPI device drivers.

This is a long series of cleanups that should cause no functional
change, but will make it easier to call acpi_bus_scan() from the
notification path.

Comments and testing reports welcome.  Boot logs with
CONFIG_ACPI_DEBUG=y and "acpi.debug_layer=0x00010000" will be
helpful in debugging any issues.

Original posting: http://marc.info/?l=linux-acpi&m=124907619701194&w=2

Changes from initial post to v2:
    - refreshed to apply on current acpi-test (0beab01e5b2c448).
    - fixed memory leak in acpi_add_single_object() debug code
    - added ACPI_IS_ROOT_DEVICE() macro (Len)

---

Bjorn Helgaas (19):
      ACPI: simplify deferred execution path
      ACPI: remove null pointer checks in deferred execution path
      ACPI: don't pass handle for fixed hardware notifications
      ACPI: add debug for device addition
      ACPI: remove unused acpi_bus_scan_fixed() argument
      ACPI: remove redundant "handle" and "parent" arguments
      ACPI: save device_type in acpi_device
      ACPI: use device_type rather than comparing HID
      ACPI: remove acpi_device_set_context() "type" argument
      ACPI: remove redundant "type" arguments
      ACPI: remove unnecessary argument checking
      ACPI: add acpi_bus_get_parent() and remove "parent" arguments
      ACPI: convert acpi_bus_scan() to operate on an acpi_handle
      ACPI: enumerate namespace before adding functional fixed hardware devices
      ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE
      ACPI: use acpi_walk_namespace() to enumerate devices
      ACPI: add acpi_bus_get_status_handle()
      ACPI: factor out device type and status checking
      ACPI: handle re-enumeration, when acpi_devices might already exist


 drivers/acpi/bus.c      |   49 ++---
 drivers/acpi/osl.c      |   32 +--
 drivers/acpi/scan.c     |  431 +++++++++++++++++++++--------------------------
 include/acpi/acpi_bus.h |    6 -
 4 files changed, 224 insertions(+), 294 deletions(-)

-- 
Bjorn

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 2 01/19] ACPI: simplify deferred execution path
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-09-19  6:25   ` Len Brown
  2009-08-31 22:32 ` [PATCH 2 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

We had two functions, acpi_os_execute_deferred() and
acpi_os_execute_hp_deferred() that differed only in that the
latter did acpi_os_wait_events_complete(NULL) before executing
the deferred function.

This patch consolidates those two functions and uses a flag in
the struct acpi_os_dpc to determine whether to do the wait.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/osl.c |   23 +++++------------------
 1 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index c5b4f1e..d753206 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -58,6 +58,7 @@ struct acpi_os_dpc {
 	acpi_osd_exec_callback function;
 	void *context;
 	struct work_struct work;
+	int wait;
 };
 
 #ifdef CONFIG_ACPI_CUSTOM_DSDT
@@ -703,21 +704,8 @@ static void acpi_os_execute_deferred(struct work_struct *work)
 		return;
 	}
 
-	dpc->function(dpc->context);
-	kfree(dpc);
-
-	return;
-}
-
-static void acpi_os_execute_hp_deferred(struct work_struct *work)
-{
-	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
-	if (!dpc) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
-
-	acpi_os_wait_events_complete(NULL);
+	if (dpc->wait)
+		acpi_os_wait_events_complete(NULL);
 
 	dpc->function(dpc->context);
 	kfree(dpc);
@@ -746,7 +734,6 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
 	acpi_status status = AE_OK;
 	struct acpi_os_dpc *dpc;
 	struct workqueue_struct *queue;
-	work_func_t func;
 	int ret;
 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 			  "Scheduling function [%p(%p)] for deferred execution.\n",
@@ -779,8 +766,8 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
 	 */
 	queue = hp ? kacpi_hotplug_wq :
 		(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
-	func = hp ? acpi_os_execute_hp_deferred : acpi_os_execute_deferred;
-	INIT_WORK(&dpc->work, func);
+	dpc->wait = hp ? 1 : 0;
+	INIT_WORK(&dpc->work, acpi_os_execute_deferred);
 	ret = queue_work(queue, &dpc->work);
 
 	if (!ret) {


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 02/19] ACPI: remove null pointer checks in deferred execution path
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-09-19  6:25   ` Len Brown
  2009-08-31 22:32 ` [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Better to oops and learn about a bug than to silently cover it up.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/osl.c |    9 ---------
 1 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index d753206..56071b6 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -699,18 +699,12 @@ void acpi_os_derive_pci_id(acpi_handle rhandle,	/* upper bound  */
 static void acpi_os_execute_deferred(struct work_struct *work)
 {
 	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
-	if (!dpc) {
-		printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
-		return;
-	}
 
 	if (dpc->wait)
 		acpi_os_wait_events_complete(NULL);
 
 	dpc->function(dpc->context);
 	kfree(dpc);
-
-	return;
 }
 
 /*******************************************************************************
@@ -739,9 +733,6 @@ static acpi_status __acpi_os_execute(acpi_execute_type type,
 			  "Scheduling function [%p(%p)] for deferred execution.\n",
 			  function, context));
 
-	if (!function)
-		return AE_BAD_PARAMETER;
-
 	/*
 	 * Allocate/initialize DPC structure.  Note that this memory will be
 	 * freed by the callee.  The kernel handles the work_struct list  in a


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-09-19  6:26   ` Len Brown
  2009-08-31 22:32 ` [PATCH 2 04/19] ACPI: add debug for device addition Bjorn Helgaas
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Fixed hardware devices have no handles, so just pass an explicit
NULL rather than something that looks like it might be meaningful.
acpi_device_notify() doesn't need the handle anyway; the only
reason it takes it as an argument is because the acpi_notify_handler
typedef requires it.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3ceebfe..e680306 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -366,7 +366,8 @@ static acpi_status acpi_device_notify_fixed(void *data)
 {
 	struct acpi_device *device = data;
 
-	acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+	/* Fixed hardware devices have no handles */
+	acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
 	return AE_OK;
 }
 


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 04/19] ACPI: add debug for device addition
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument Bjorn Helgaas
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Add debug output for adding an ACPI device.  Enable this with
"acpi.debug_layer=0x00010000" (ACPI_BUS_COMPONENT).

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e680306..3c23d68 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1223,6 +1223,7 @@ acpi_add_single_object(struct acpi_device **child,
 {
 	int result = 0;
 	struct acpi_device *device = NULL;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
 
 	if (!child)
@@ -1356,9 +1357,16 @@ acpi_add_single_object(struct acpi_device **child,
 	}
 
 end:
-	if (!result)
+	if (!result) {
+		acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+			"Adding %s [%s] parent %s\n", dev_name(&device->dev),
+			 (char *) buffer.pointer,
+			 device->parent ? dev_name(&device->parent->dev) :
+					  "(null)"));
+		kfree(buffer.pointer);
 		*child = device;
-	else {
+	} else {
 		kfree(device->pnp.cid_list);
 		kfree(device);
 	}


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 04/19] ACPI: add debug for device addition Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 06/19] ACPI: remove redundant "handle" and "parent" arguments Bjorn Helgaas
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

We never use the "root" argument, so just remove it.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3c23d68..177f1b4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1583,15 +1583,12 @@ int acpi_bus_trim(struct acpi_device *start, int rmdevice)
 }
 EXPORT_SYMBOL_GPL(acpi_bus_trim);
 
-static int acpi_bus_scan_fixed(struct acpi_device *root)
+static int acpi_bus_scan_fixed(void)
 {
 	int result = 0;
 	struct acpi_device *device = NULL;
 	struct acpi_bus_ops ops;
 
-	if (!root)
-		return -ENODEV;
-
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 	ops.acpi_op_start = 1;
@@ -1642,7 +1639,7 @@ int __init acpi_scan_init(void)
 	/*
 	 * Enumerate devices in the ACPI namespace.
 	 */
-	result = acpi_bus_scan_fixed(acpi_root);
+	result = acpi_bus_scan_fixed();
 
 	if (!result)
 		result = acpi_bus_scan(acpi_root, &ops);


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 06/19] ACPI: remove redundant "handle" and "parent" arguments
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 07/19] ACPI: save device_type in acpi_device Bjorn Helgaas
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

In several cases, functions take handle and parent device pointers in
addition to acpi_device pointers.  But the acpi_device structure contains
both the handle and the parent pointer, so it's pointless and error-prone
to pass them all.  This patch removes the unnecessary "handle" and "parent"
arguments.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   28 ++++++++++++----------------
 1 files changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 177f1b4..38742d7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -470,12 +470,12 @@ struct bus_type acpi_bus_type = {
 	.uevent		= acpi_device_uevent,
 };
 
-static int acpi_device_register(struct acpi_device *device,
-				 struct acpi_device *parent)
+static int acpi_device_register(struct acpi_device *device)
 {
 	int result;
 	struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
 	int found = 0;
+
 	/*
 	 * Linkage
 	 * -------
@@ -520,7 +520,7 @@ static int acpi_device_register(struct acpi_device *device,
 	mutex_unlock(&acpi_device_lock);
 
 	if (device->parent)
-		device->dev.parent = &parent->dev;
+		device->dev.parent = &device->parent->dev;
 	device->dev.bus = &acpi_bus_type;
 	device->dev.release = &acpi_device_release;
 	result = device_register(&device->dev);
@@ -913,8 +913,7 @@ static int acpi_bus_get_flags(struct acpi_device *device)
 	return 0;
 }
 
-static void acpi_device_get_busid(struct acpi_device *device,
-				  acpi_handle handle, int type)
+static void acpi_device_get_busid(struct acpi_device *device, int type)
 {
 	char bus_id[5] = { '?', 0 };
 	struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
@@ -937,7 +936,7 @@ static void acpi_device_get_busid(struct acpi_device *device,
 		strcpy(device->pnp.bus_id, "SLPF");
 		break;
 	default:
-		acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer);
+		acpi_get_name(device->handle, ACPI_SINGLE_NAME, &buffer);
 		/* Clean up trailing underscores (if any) */
 		for (i = 3; i > 1; i--) {
 			if (bus_id[i] == '_')
@@ -1053,9 +1052,7 @@ acpi_add_cid(
 	return cid;
 }
 
-static void acpi_device_set_id(struct acpi_device *device,
-			       struct acpi_device *parent, acpi_handle handle,
-			       int type)
+static void acpi_device_set_id(struct acpi_device *device, int type)
 {
 	struct acpi_device_info *info = NULL;
 	char *hid = NULL;
@@ -1066,7 +1063,7 @@ static void acpi_device_set_id(struct acpi_device *device,
 
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
-		status = acpi_get_object_info(handle, &info);
+		status = acpi_get_object_info(device->handle, &info);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
 			return;
@@ -1121,7 +1118,8 @@ static void acpi_device_set_id(struct acpi_device *device,
 	 * ----
 	 * Fix for the system root bus device -- the only root-level device.
 	 */
-	if (((acpi_handle)parent == ACPI_ROOT_OBJECT) && (type == ACPI_BUS_TYPE_DEVICE)) {
+	if (((acpi_handle)device->parent == ACPI_ROOT_OBJECT) &&
+	     (type == ACPI_BUS_TYPE_DEVICE)) {
 		hid = ACPI_BUS_HID;
 		strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
 		strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
@@ -1239,8 +1237,7 @@ acpi_add_single_object(struct acpi_device **child,
 	device->parent = parent;
 	device->bus_ops = *ops; /* workround for not call .start */
 
-
-	acpi_device_get_busid(device, handle, type);
+	acpi_device_get_busid(device, type);
 
 	/*
 	 * Flags
@@ -1303,7 +1300,7 @@ acpi_add_single_object(struct acpi_device **child,
 	 * Hardware ID, Unique ID, & Bus Address
 	 * -------------------------------------
 	 */
-	acpi_device_set_id(device, parent, handle, type);
+	acpi_device_set_id(device, type);
 
 	/*
 	 * The ACPI device is attached to acpi handle before getting
@@ -1345,8 +1342,7 @@ acpi_add_single_object(struct acpi_device **child,
 			goto end;
 	}
 
-
-	result = acpi_device_register(device, parent);
+	result = acpi_device_register(device);
 
 	/*
 	 * Bind _ADR-Based Devices when hot add


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 07/19] ACPI: save device_type in acpi_device
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 06/19] ACPI: remove redundant "handle" and "parent" arguments Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 08/19] ACPI: use device_type rather than comparing HID Bjorn Helgaas
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Most uses of the ACPI bus device_type (ACPI_BUS_TYPE_DEVICE,
ACPI_BUS_TYPE_POWER, etc) are during device initialization, but
we do need it later for notify handler installation, since that
is different for fixed hardware devices vs. namespace devices.

This patch saves the device_type in the acpi_device structure,
so we can check that rather than comparing against the _HID string.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c     |    1 +
 include/acpi/acpi_bus.h |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 38742d7..d07b15c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1233,6 +1233,7 @@ acpi_add_single_object(struct acpi_device **child,
 		return -ENOMEM;
 	}
 
+	device->device_type = type;
 	device->handle = handle;
 	device->parent = parent;
 	device->bus_ops = *ops; /* workround for not call .start */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 08ed0e9..c652405 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -262,7 +262,8 @@ struct acpi_device_wakeup {
 /* Device */
 
 struct acpi_device {
-	acpi_handle handle;
+	int device_type;
+	acpi_handle handle;		/* no handle for fixed hardware */
 	struct acpi_device *parent;
 	struct list_head children;
 	struct list_head node;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 08/19] ACPI: use device_type rather than comparing HID
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 07/19] ACPI: save device_type in acpi_device Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 09/19] ACPI: remove acpi_device_set_context() "type" argument Bjorn Helgaas
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Check the acpi_device device_type rather than the HID.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d07b15c..06c1c06 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -374,15 +374,13 @@ static acpi_status acpi_device_notify_fixed(void *data)
 static int acpi_device_install_notify_handler(struct acpi_device *device)
 {
 	acpi_status status;
-	char *hid;
 
-	hid = acpi_device_hid(device);
-	if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
 		status =
 		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 						     acpi_device_notify_fixed,
 						     device);
-	else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
 		status =
 		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 						     acpi_device_notify_fixed,
@@ -400,10 +398,10 @@ static int acpi_device_install_notify_handler(struct acpi_device *device)
 
 static void acpi_device_remove_notify_handler(struct acpi_device *device)
 {
-	if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
 		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
 						acpi_device_notify_fixed);
-	else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
 		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
 						acpi_device_notify_fixed);
 	else


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 09/19] ACPI: remove acpi_device_set_context() "type" argument
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 08/19] ACPI: use device_type rather than comparing HID Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:32 ` [PATCH 2 10/19] ACPI: remove redundant "type" arguments Bjorn Helgaas
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

We only pass the "type" to acpi_device_set_context() so we know whether
the device has a handle to which we can attach the acpi_device pointer.
But it's safer to just check for the handle directly, since it's in the
acpi_device already.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   32 +++++++++++++++-----------------
 1 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 06c1c06..42324a0 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1164,29 +1164,27 @@ static void acpi_device_set_id(struct acpi_device *device, int type)
 	kfree(info);
 }
 
-static int acpi_device_set_context(struct acpi_device *device, int type)
+static int acpi_device_set_context(struct acpi_device *device)
 {
-	acpi_status status = AE_OK;
-	int result = 0;
+	acpi_status status;
+
 	/*
 	 * Context
 	 * -------
 	 * Attach this 'struct acpi_device' to the ACPI object.  This makes
-	 * resolutions from handle->device very efficient.  Note that we need
-	 * to be careful with fixed-feature devices as they all attach to the
-	 * root object.
+	 * resolutions from handle->device very efficient.  Fixed hardware
+	 * devices have no handles, so we skip them.
 	 */
-	if (type != ACPI_BUS_TYPE_POWER_BUTTON &&
-	    type != ACPI_BUS_TYPE_SLEEP_BUTTON) {
-		status = acpi_attach_data(device->handle,
-					  acpi_bus_data_handler, device);
+	if (!device->handle)
+		return 0;
 
-		if (ACPI_FAILURE(status)) {
-			printk(KERN_ERR PREFIX "Error attaching device data\n");
-			result = -ENODEV;
-		}
-	}
-	return result;
+	status = acpi_attach_data(device->handle,
+				  acpi_bus_data_handler, device);
+	if (ACPI_SUCCESS(status))
+		return 0;
+
+	printk(KERN_ERR PREFIX "Error attaching device data\n");
+	return -ENODEV;
 }
 
 static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
@@ -1307,7 +1305,7 @@ acpi_add_single_object(struct acpi_device **child,
 	 * the corresponding ACPI device by the acpi handle in the course
 	 * of getting the power/wakeup/performance flags.
 	 */
-	result = acpi_device_set_context(device, type);
+	result = acpi_device_set_context(device);
 	if (result)
 		goto end;
 


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 10/19] ACPI: remove redundant "type" arguments
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (8 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 09/19] ACPI: remove acpi_device_set_context() "type" argument Bjorn Helgaas
@ 2009-08-31 22:32 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 11/19] ACPI: remove unnecessary argument checking Bjorn Helgaas
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:32 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

We now save the ACPI bus "device_type" in the acpi_device structure, so
we don't need to pass it around explicitly anymore.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 42324a0..f86dee8 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -911,7 +911,7 @@ static int acpi_bus_get_flags(struct acpi_device *device)
 	return 0;
 }
 
-static void acpi_device_get_busid(struct acpi_device *device, int type)
+static void acpi_device_get_busid(struct acpi_device *device)
 {
 	char bus_id[5] = { '?', 0 };
 	struct acpi_buffer buffer = { sizeof(bus_id), bus_id };
@@ -923,7 +923,7 @@ static void acpi_device_get_busid(struct acpi_device *device, int type)
 	 * The device's Bus ID is simply the object name.
 	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
 	 */
-	switch (type) {
+	switch (device->device_type) {
 	case ACPI_BUS_TYPE_SYSTEM:
 		strcpy(device->pnp.bus_id, "ACPI");
 		break;
@@ -1050,7 +1050,7 @@ acpi_add_cid(
 	return cid;
 }
 
-static void acpi_device_set_id(struct acpi_device *device, int type)
+static void acpi_device_set_id(struct acpi_device *device)
 {
 	struct acpi_device_info *info = NULL;
 	char *hid = NULL;
@@ -1059,7 +1059,7 @@ static void acpi_device_set_id(struct acpi_device *device, int type)
 	char *cid_add = NULL;
 	acpi_status status;
 
-	switch (type) {
+	switch (device->device_type) {
 	case ACPI_BUS_TYPE_DEVICE:
 		status = acpi_get_object_info(device->handle, &info);
 		if (ACPI_FAILURE(status)) {
@@ -1117,7 +1117,7 @@ static void acpi_device_set_id(struct acpi_device *device, int type)
 	 * Fix for the system root bus device -- the only root-level device.
 	 */
 	if (((acpi_handle)device->parent == ACPI_ROOT_OBJECT) &&
-	     (type == ACPI_BUS_TYPE_DEVICE)) {
+	     (device->device_type == ACPI_BUS_TYPE_DEVICE)) {
 		hid = ACPI_BUS_HID;
 		strcpy(device->pnp.device_name, ACPI_BUS_DEVICE_NAME);
 		strcpy(device->pnp.device_class, ACPI_BUS_CLASS);
@@ -1234,7 +1234,7 @@ acpi_add_single_object(struct acpi_device **child,
 	device->parent = parent;
 	device->bus_ops = *ops; /* workround for not call .start */
 
-	acpi_device_get_busid(device, type);
+	acpi_device_get_busid(device);
 
 	/*
 	 * Flags
@@ -1297,7 +1297,7 @@ acpi_add_single_object(struct acpi_device **child,
 	 * Hardware ID, Unique ID, & Bus Address
 	 * -------------------------------------
 	 */
-	acpi_device_set_id(device, type);
+	acpi_device_set_id(device);
 
 	/*
 	 * The ACPI device is attached to acpi handle before getting


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 11/19] ACPI: remove unnecessary argument checking
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (9 preceding siblings ...)
  2009-08-31 22:32 ` [PATCH 2 10/19] ACPI: remove redundant "type" arguments Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments Bjorn Helgaas
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

acpi_add_single_object() is static, and all callers supply a valid "child"
argument, so we don't need to check it.  This patch also remove some
unnecessary initializations.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |    8 ++------
 1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f86dee8..f54632c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1215,14 +1215,10 @@ acpi_add_single_object(struct acpi_device **child,
 		       struct acpi_device *parent, acpi_handle handle, int type,
 			struct acpi_bus_ops *ops)
 {
-	int result = 0;
-	struct acpi_device *device = NULL;
+	int result;
+	struct acpi_device *device;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
-
-	if (!child)
-		return -EINVAL;
-
 	device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
 	if (!device) {
 		printk(KERN_ERR PREFIX "Memory allocation error\n");


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (10 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 11/19] ACPI: remove unnecessary argument checking Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle Bjorn Helgaas
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

This patch adds acpi_bus_get_parent(), which ascends the namespace until
it finds a parent with an acpi_device.

Then we use acpi_bus_get_parent() in acpi_add_single_object(), so callers
don't have to figure out or keep track of the parent acpi_device.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   50 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f54632c..a58b115 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -658,6 +658,33 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver);
 /* --------------------------------------------------------------------------
                                  Device Enumeration
    -------------------------------------------------------------------------- */
+static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
+{
+	acpi_status status;
+	int ret;
+	struct acpi_device *device;
+
+	/*
+	 * Fixed hardware devices do not appear in the namespace and do not
+	 * have handles, but we fabricate acpi_devices for them, so we have
+	 * to deal with them specially.
+	 */
+	if (handle == NULL)
+		return acpi_root;
+
+	do {
+		status = acpi_get_parent(handle, &handle);
+		if (status == AE_NULL_ENTRY)
+			return NULL;
+		if (ACPI_FAILURE(status))
+			return acpi_root;
+
+		ret = acpi_bus_get_device(handle, &device);
+		if (ret == 0)
+			return device;
+	} while (1);
+}
+
 acpi_status
 acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
 {
@@ -1210,10 +1237,9 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 	return 0;
 }
 
-static int
-acpi_add_single_object(struct acpi_device **child,
-		       struct acpi_device *parent, acpi_handle handle, int type,
-			struct acpi_bus_ops *ops)
+static int acpi_add_single_object(struct acpi_device **child,
+				  acpi_handle handle, int type,
+				  struct acpi_bus_ops *ops)
 {
 	int result;
 	struct acpi_device *device;
@@ -1227,7 +1253,7 @@ acpi_add_single_object(struct acpi_device **child,
 
 	device->device_type = type;
 	device->handle = handle;
-	device->parent = parent;
+	device->parent = acpi_bus_get_parent(handle);
 	device->bus_ops = *ops; /* workround for not call .start */
 
 	acpi_device_get_busid(device);
@@ -1436,8 +1462,8 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
 		}
 
 		if (ops->acpi_op_add)
-			status = acpi_add_single_object(&child, parent,
-				chandle, type, ops);
+			status = acpi_add_single_object(&child, chandle, type,
+							ops);
 		else
 			status = acpi_bus_get_device(chandle, &child);
 
@@ -1490,7 +1516,7 @@ acpi_bus_add(struct acpi_device **child,
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 
-	result = acpi_add_single_object(child, parent, handle, type, &ops);
+	result = acpi_add_single_object(child, handle, type, &ops);
 	if (!result)
 		result = acpi_bus_scan(*child, &ops);
 
@@ -1586,15 +1612,13 @@ static int acpi_bus_scan_fixed(void)
 	 * Enumerate all fixed-feature devices.
 	 */
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
-		result = acpi_add_single_object(&device, acpi_root,
-						NULL,
+		result = acpi_add_single_object(&device, NULL,
 						ACPI_BUS_TYPE_POWER_BUTTON,
 						&ops);
 	}
 
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
-		result = acpi_add_single_object(&device, acpi_root,
-						NULL,
+		result = acpi_add_single_object(&device, NULL,
 						ACPI_BUS_TYPE_SLEEP_BUTTON,
 						&ops);
 	}
@@ -1620,7 +1644,7 @@ int __init acpi_scan_init(void)
 	/*
 	 * Create the root device in the bus's device tree
 	 */
-	result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
+	result = acpi_add_single_object(&acpi_root, ACPI_ROOT_OBJECT,
 					ACPI_BUS_TYPE_SYSTEM, &ops);
 	if (result)
 		goto Done;


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (11 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices Bjorn Helgaas
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

This patch changes acpi_bus_scan() to take an acpi_handle rather than an
acpi_device pointer.  I plan to use acpi_bus_scan() in the hotplug path,
and I'd rather not assume that notifications only go to nodes that already
have acpi_devices.

This will also help remove the special case for adding the root node.  We
currently add the root by hand before acpi_bus_scan(), but using a handle
here means we can start the acpi_bus_scan() directly with the root even
though it doesn't have an acpi_device yet.

Note that acpi_bus_scan() currently adds and/or starts the *children* of
its device argument.  It doesn't do anything with the device itself.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a58b115..07e097e 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1389,7 +1389,7 @@ end:
 	return result;
 }
 
-static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
+static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops)
 {
 	acpi_status status = AE_OK;
 	struct acpi_device *parent = NULL;
@@ -1398,13 +1398,16 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
 	acpi_handle chandle = NULL;
 	acpi_object_type type = 0;
 	u32 level = 1;
+	int ret;
 
-
-	if (!start)
-		return -EINVAL;
-
-	parent = start;
-	phandle = start->handle;
+	/*
+	 * We must have an acpi_device for the starting node already, and
+	 * we scan its children.
+	 */
+	phandle = handle;
+	ret = acpi_bus_get_device(phandle, &parent);
+	if (ret)
+		return ret;
 
 	/*
 	 * Parse through the ACPI namespace, identify all 'devices', and
@@ -1518,7 +1521,7 @@ acpi_bus_add(struct acpi_device **child,
 
 	result = acpi_add_single_object(child, handle, type, &ops);
 	if (!result)
-		result = acpi_bus_scan(*child, &ops);
+		result = acpi_bus_scan((*child)->handle, &ops);
 
 	return result;
 }
@@ -1529,16 +1532,13 @@ int acpi_bus_start(struct acpi_device *device)
 	int result;
 	struct acpi_bus_ops ops;
 
-
-	if (!device)
-		return -EINVAL;
+	memset(&ops, 0, sizeof(ops));
+	ops.acpi_op_start = 1;
 
 	result = acpi_start_single_object(device);
-	if (!result) {
-		memset(&ops, 0, sizeof(ops));
-		ops.acpi_op_start = 1;
-		result = acpi_bus_scan(device, &ops);
-	}
+	if (!result)
+		result = acpi_bus_scan(device->handle, &ops);
+
 	return result;
 }
 EXPORT_SYMBOL(acpi_bus_start);
@@ -1655,7 +1655,7 @@ int __init acpi_scan_init(void)
 	result = acpi_bus_scan_fixed();
 
 	if (!result)
-		result = acpi_bus_scan(acpi_root, &ops);
+		result = acpi_bus_scan(acpi_root->handle, &ops);
 
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (12 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

This patch changes the order so we enumerate in the "root, namespace,
functional fixed" order instead of the "root, functional fixed, namespace"
order.  When I change acpi_bus_scan() to use acpi_walk_namespace(), it
will use the former order, so this patch isolates the order change for
bisectability.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 07e097e..3e4228f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1652,10 +1652,10 @@ int __init acpi_scan_init(void)
 	/*
 	 * Enumerate devices in the ACPI namespace.
 	 */
-	result = acpi_bus_scan_fixed();
+	result = acpi_bus_scan(acpi_root->handle, &ops);
 
 	if (!result)
-		result = acpi_bus_scan(acpi_root->handle, &ops);
+		result = acpi_bus_scan_fixed();
 
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (13 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 16/19] ACPI: use acpi_walk_namespace() to enumerate devices Bjorn Helgaas
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

We can identify the root of the ACPI device tree by the fact that it
has no parent.  This is simpler than passing around ACPI_BUS_TYPE_SYSTEM
and will help remove special treatment of the device tree root.

Currently, we add the root by hand with ACPI_BUS_TYPE_SYSTEM.  If we
traverse the tree treating the root as just another device and use
acpi_get_type(), the root shows up as ACPI_TYPE_DEVICE.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c     |   20 +++++++++++++-------
 include/acpi/acpi_bus.h |    1 -
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3e4228f..5565b34 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -22,6 +22,8 @@ extern struct acpi_device *acpi_root;
 #define ACPI_BUS_HID			"LNXSYBUS"
 #define ACPI_BUS_DEVICE_NAME		"System Bus"
 
+#define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
+
 static LIST_HEAD(acpi_device_list);
 static LIST_HEAD(acpi_bus_id_list);
 DEFINE_MUTEX(acpi_device_lock);
@@ -950,10 +952,12 @@ static void acpi_device_get_busid(struct acpi_device *device)
 	 * The device's Bus ID is simply the object name.
 	 * TBD: Shouldn't this value be unique (within the ACPI namespace)?
 	 */
-	switch (device->device_type) {
-	case ACPI_BUS_TYPE_SYSTEM:
+	if (ACPI_IS_ROOT_DEVICE(device)) {
 		strcpy(device->pnp.bus_id, "ACPI");
-		break;
+		return;
+	}
+
+	switch (device->device_type) {
 	case ACPI_BUS_TYPE_POWER_BUTTON:
 		strcpy(device->pnp.bus_id, "PWRF");
 		break;
@@ -1088,6 +1092,11 @@ static void acpi_device_set_id(struct acpi_device *device)
 
 	switch (device->device_type) {
 	case ACPI_BUS_TYPE_DEVICE:
+		if (ACPI_IS_ROOT_DEVICE(device)) {
+			hid = ACPI_SYSTEM_HID;
+			break;
+		}
+
 		status = acpi_get_object_info(device->handle, &info);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
@@ -1124,9 +1133,6 @@ static void acpi_device_set_id(struct acpi_device *device)
 	case ACPI_BUS_TYPE_PROCESSOR:
 		hid = ACPI_PROCESSOR_OBJECT_HID;
 		break;
-	case ACPI_BUS_TYPE_SYSTEM:
-		hid = ACPI_SYSTEM_HID;
-		break;
 	case ACPI_BUS_TYPE_THERMAL:
 		hid = ACPI_THERMAL_HID;
 		break;
@@ -1645,7 +1651,7 @@ int __init acpi_scan_init(void)
 	 * Create the root device in the bus's device tree
 	 */
 	result = acpi_add_single_object(&acpi_root, ACPI_ROOT_OBJECT,
-					ACPI_BUS_TYPE_SYSTEM, &ops);
+					ACPI_BUS_TYPE_DEVICE, &ops);
 	if (result)
 		goto Done;
 
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c652405..0ce840b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -70,7 +70,6 @@ enum acpi_bus_device_type {
 	ACPI_BUS_TYPE_POWER,
 	ACPI_BUS_TYPE_PROCESSOR,
 	ACPI_BUS_TYPE_THERMAL,
-	ACPI_BUS_TYPE_SYSTEM,
 	ACPI_BUS_TYPE_POWER_BUTTON,
 	ACPI_BUS_TYPE_SLEEP_BUTTON,
 	ACPI_BUS_DEVICE_TYPE_COUNT


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 16/19] ACPI: use acpi_walk_namespace() to enumerate devices
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (14 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 17/19] ACPI: add acpi_bus_get_status_handle() Bjorn Helgaas
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

acpi_bus_scan() currently walks the namespace manually.  This patch changes
it to use acpi_walk_namespace() instead.

Besides removing some complicated code, this means we take advantage of the
namespace locking done by acpi_walk_namespace().  The locking isn't so
important at boot-time, but I hope to eventually use this same path to
handle hot-addition of devices, when it will be important.

Note that acpi_walk_namespace() does not actually visit the starting node
first, so we need to do that by hand first.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |  196 +++++++++++++++++++--------------------------------
 1 files changed, 74 insertions(+), 122 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5565b34..ad62cd9 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1395,123 +1395,92 @@ end:
 	return result;
 }
 
-static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops)
+static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
+				      void *context, void **return_value)
 {
 	acpi_status status = AE_OK;
-	struct acpi_device *parent = NULL;
-	struct acpi_device *child = NULL;
-	acpi_handle phandle = NULL;
-	acpi_handle chandle = NULL;
+	struct acpi_device *device = NULL;
 	acpi_object_type type = 0;
-	u32 level = 1;
-	int ret;
+	struct acpi_bus_ops *ops = context;
 
-	/*
-	 * We must have an acpi_device for the starting node already, and
-	 * we scan its children.
-	 */
-	phandle = handle;
-	ret = acpi_bus_get_device(phandle, &parent);
-	if (ret)
-		return ret;
+	status = acpi_get_type(handle, &type);
+	if (ACPI_FAILURE(status))
+		return AE_OK;
 
 	/*
-	 * Parse through the ACPI namespace, identify all 'devices', and
-	 * create a new 'struct acpi_device' for each.
+	 * We're only interested in objects that we consider 'devices'.
 	 */
-	while ((level > 0) && parent) {
+	switch (type) {
+	case ACPI_TYPE_ANY:		/* for ACPI_ROOT_OBJECT */
+	case ACPI_TYPE_DEVICE:
+		type = ACPI_BUS_TYPE_DEVICE;
+		break;
+	case ACPI_TYPE_PROCESSOR:
+		type = ACPI_BUS_TYPE_PROCESSOR;
+		break;
+	case ACPI_TYPE_THERMAL:
+		type = ACPI_BUS_TYPE_THERMAL;
+		break;
+	case ACPI_TYPE_POWER:
+		type = ACPI_BUS_TYPE_POWER;
+		break;
+	default:
+		return AE_OK;
+	}
 
-		status = acpi_get_next_object(ACPI_TYPE_ANY, phandle,
-					      chandle, &chandle);
+	if (ops->acpi_op_add)
+		status = acpi_add_single_object(&device, handle, type, ops);
+	else
+		status = acpi_bus_get_device(handle, &device);
 
-		/*
-		 * If this scope is exhausted then move our way back up.
-		 */
-		if (ACPI_FAILURE(status)) {
-			level--;
-			chandle = phandle;
-			acpi_get_parent(phandle, &phandle);
-			if (parent->parent)
-				parent = parent->parent;
-			continue;
-		}
+	if (ACPI_FAILURE(status))
+		return AE_CTRL_DEPTH;
 
-		status = acpi_get_type(chandle, &type);
+	if (ops->acpi_op_start && !(ops->acpi_op_add)) {
+		status = acpi_start_single_object(device);
 		if (ACPI_FAILURE(status))
-			continue;
-
-		/*
-		 * If this is a scope object then parse it (depth-first).
-		 */
-		if (type == ACPI_TYPE_LOCAL_SCOPE) {
-			level++;
-			phandle = chandle;
-			chandle = NULL;
-			continue;
-		}
+			return AE_CTRL_DEPTH;
+	}
 
-		/*
-		 * We're only interested in objects that we consider 'devices'.
-		 */
-		switch (type) {
-		case ACPI_TYPE_DEVICE:
-			type = ACPI_BUS_TYPE_DEVICE;
-			break;
-		case ACPI_TYPE_PROCESSOR:
-			type = ACPI_BUS_TYPE_PROCESSOR;
-			break;
-		case ACPI_TYPE_THERMAL:
-			type = ACPI_BUS_TYPE_THERMAL;
-			break;
-		case ACPI_TYPE_POWER:
-			type = ACPI_BUS_TYPE_POWER;
-			break;
-		default:
-			continue;
-		}
+	/*
+	 * If the device is present, enabled, and functioning then
+	 * parse its scope (depth-first).  Note that we need to
+	 * represent absent devices to facilitate PnP notifications
+	 * -- but only the subtree head (not all of its children,
+	 * which will be enumerated when the parent is inserted).
+	 *
+	 * TBD: Need notifications and other detection mechanisms
+	 *      in place before we can fully implement this.
+	 *
+	 * When the device is not present but functional, it is also
+	 * necessary to scan the children of this device.
+	 */
+	if (!device->status.present && !device->status.functional)
+		return AE_CTRL_DEPTH;
 
-		if (ops->acpi_op_add)
-			status = acpi_add_single_object(&child, chandle, type,
-							ops);
-		else
-			status = acpi_bus_get_device(chandle, &child);
+	if (!*return_value)
+		*return_value = device;
+	return AE_OK;
+}
 
-		if (ACPI_FAILURE(status))
-			continue;
+static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
+			 struct acpi_device **child)
+{
+	acpi_status status;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	void *device = NULL;
 
-		if (ops->acpi_op_start && !(ops->acpi_op_add)) {
-			status = acpi_start_single_object(child);
-			if (ACPI_FAILURE(status))
-				continue;
-		}
+	acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
+	printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n",
+	       (char *) buffer.pointer);
 
-		/*
-		 * If the device is present, enabled, and functioning then
-		 * parse its scope (depth-first).  Note that we need to
-		 * represent absent devices to facilitate PnP notifications
-		 * -- but only the subtree head (not all of its children,
-		 * which will be enumerated when the parent is inserted).
-		 *
-		 * TBD: Need notifications and other detection mechanisms
-		 *      in place before we can fully implement this.
-		 */
-		 /*
-		 * When the device is not present but functional, it is also
-		 * necessary to scan the children of this device.
-		 */
-		if (child->status.present || (!child->status.present &&
-					child->status.functional)) {
-			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
-						      NULL, NULL);
-			if (ACPI_SUCCESS(status)) {
-				level++;
-				phandle = chandle;
-				chandle = NULL;
-				parent = child;
-			}
-		}
-	}
+	status = acpi_bus_check_add(handle, 0, ops, &device);
+	if (ACPI_SUCCESS(status))
+		acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+				    acpi_bus_check_add, ops, &device);
 
+	if (child)
+		*child = device;
 	return 0;
 }
 
@@ -1519,33 +1488,25 @@ int
 acpi_bus_add(struct acpi_device **child,
 	     struct acpi_device *parent, acpi_handle handle, int type)
 {
-	int result;
 	struct acpi_bus_ops ops;
 
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_add = 1;
 
-	result = acpi_add_single_object(child, handle, type, &ops);
-	if (!result)
-		result = acpi_bus_scan((*child)->handle, &ops);
-
-	return result;
+	acpi_bus_scan(handle, &ops, child);
+	return 0;
 }
 EXPORT_SYMBOL(acpi_bus_add);
 
 int acpi_bus_start(struct acpi_device *device)
 {
-	int result;
 	struct acpi_bus_ops ops;
 
 	memset(&ops, 0, sizeof(ops));
 	ops.acpi_op_start = 1;
 
-	result = acpi_start_single_object(device);
-	if (!result)
-		result = acpi_bus_scan(device->handle, &ops);
-
-	return result;
+	acpi_bus_scan(device->handle, &ops, NULL);
+	return 0;
 }
 EXPORT_SYMBOL(acpi_bus_start);
 
@@ -1648,17 +1609,9 @@ int __init acpi_scan_init(void)
 	}
 
 	/*
-	 * Create the root device in the bus's device tree
-	 */
-	result = acpi_add_single_object(&acpi_root, ACPI_ROOT_OBJECT,
-					ACPI_BUS_TYPE_DEVICE, &ops);
-	if (result)
-		goto Done;
-
-	/*
 	 * Enumerate devices in the ACPI namespace.
 	 */
-	result = acpi_bus_scan(acpi_root->handle, &ops);
+	result = acpi_bus_scan(ACPI_ROOT_OBJECT, &ops, &acpi_root);
 
 	if (!result)
 		result = acpi_bus_scan_fixed();
@@ -1666,6 +1619,5 @@ int __init acpi_scan_init(void)
 	if (result)
 		acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
 
-Done:
 	return result;
 }


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 17/19] ACPI: add acpi_bus_get_status_handle()
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (15 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 16/19] ACPI: use acpi_walk_namespace() to enumerate devices Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 18/19] ACPI: factor out device type and status checking Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist Bjorn Helgaas
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

Add acpi_bus_get_status_handle() so we can get the status of a namespace
object before building a struct acpi_device.

This removes a use of "device->flags.dynamic_status", a cached indicator of
whether _STA exists.  It seems simpler and more reliable to just evaluate
_STA and catch AE_NOT_FOUND errors.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/bus.c      |   49 +++++++++++++++++++++--------------------------
 include/acpi/acpi_bus.h |    2 ++
 2 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 135fbfe..7411915 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -94,36 +94,33 @@ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
 
 EXPORT_SYMBOL(acpi_bus_get_device);
 
-int acpi_bus_get_status(struct acpi_device *device)
+acpi_status acpi_bus_get_status_handle(acpi_handle handle,
+				       unsigned long long *sta)
 {
-	acpi_status status = AE_OK;
-	unsigned long long sta = 0;
-
+	acpi_status status;
 
-	if (!device)
-		return -EINVAL;
+	status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
+	if (ACPI_SUCCESS(status))
+		return AE_OK;
 
-	/*
-	 * Evaluate _STA if present.
-	 */
-	if (device->flags.dynamic_status) {
-		status =
-		    acpi_evaluate_integer(device->handle, "_STA", NULL, &sta);
-		if (ACPI_FAILURE(status))
-			return -ENODEV;
-		STRUCT_TO_INT(device->status) = (int)sta;
+	if (status == AE_NOT_FOUND) {
+		*sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+		       ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
+		return AE_OK;
 	}
+	return status;
+}
 
-	/*
-	 * According to ACPI spec some device can be present and functional
-	 * even if the parent is not present but functional.
-	 * In such conditions the child device should not inherit the status
-	 * from the parent.
-	 */
-	else
-		STRUCT_TO_INT(device->status) =
-		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
-		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
+int acpi_bus_get_status(struct acpi_device *device)
+{
+	acpi_status status;
+	unsigned long long sta;
+
+	status = acpi_bus_get_status_handle(device->handle, &sta);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	STRUCT_TO_INT(device->status) = (int) sta;
 
 	if (device->status.functional && !device->status.present) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
@@ -135,10 +132,8 @@ int acpi_bus_get_status(struct acpi_device *device)
 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
 			  device->pnp.bus_id,
 			  (u32) STRUCT_TO_INT(device->status)));
-
 	return 0;
 }
-
 EXPORT_SYMBOL(acpi_bus_get_status);
 
 void acpi_bus_private_data_handler(acpi_handle handle,
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 0ce840b..a273cdf 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -322,6 +322,8 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb);
 
 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device);
 void acpi_bus_data_handler(acpi_handle handle, void *context);
+acpi_status acpi_bus_get_status_handle(acpi_handle handle,
+				       unsigned long long *sta);
 int acpi_bus_get_status(struct acpi_device *device);
 int acpi_bus_get_power(acpi_handle handle, int *state);
 int acpi_bus_set_power(acpi_handle handle, int state);


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 18/19] ACPI: factor out device type and status checking
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (16 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 17/19] ACPI: add acpi_bus_get_status_handle() Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  2009-08-31 22:33 ` [PATCH 2 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist Bjorn Helgaas
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

This patch adds acpi_bus_type_and_status(), which determines the type
of the object and whether we want to build an acpi_device for it.  If
it is acpi_device-worthy, it returns the type and the device's current
status.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |  129 +++++++++++++++++++++------------------------------
 1 files changed, 52 insertions(+), 77 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ad62cd9..61a7e16 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1245,6 +1245,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
 
 static int acpi_add_single_object(struct acpi_device **child,
 				  acpi_handle handle, int type,
+				  unsigned long long sta,
 				  struct acpi_bus_ops *ops)
 {
 	int result;
@@ -1261,61 +1262,21 @@ static int acpi_add_single_object(struct acpi_device **child,
 	device->handle = handle;
 	device->parent = acpi_bus_get_parent(handle);
 	device->bus_ops = *ops; /* workround for not call .start */
+	STRUCT_TO_INT(device->status) = sta;
 
 	acpi_device_get_busid(device);
 
 	/*
 	 * Flags
 	 * -----
-	 * Get prior to calling acpi_bus_get_status() so we know whether
-	 * or not _STA is present.  Note that we only look for object
-	 * handles -- cannot evaluate objects until we know the device is
-	 * present and properly initialized.
+	 * Note that we only look for object handles -- cannot evaluate objects
+	 * until we know the device is present and properly initialized.
 	 */
 	result = acpi_bus_get_flags(device);
 	if (result)
 		goto end;
 
 	/*
-	 * Status
-	 * ------
-	 * See if the device is present.  We always assume that non-Device
-	 * and non-Processor objects (e.g. thermal zones, power resources,
-	 * etc.) are present, functioning, etc. (at least when parent object
-	 * is present).  Note that _STA has a different meaning for some
-	 * objects (e.g. power resources) so we need to be careful how we use
-	 * it.
-	 */
-	switch (type) {
-	case ACPI_BUS_TYPE_PROCESSOR:
-	case ACPI_BUS_TYPE_DEVICE:
-		result = acpi_bus_get_status(device);
-		if (ACPI_FAILURE(result)) {
-			result = -ENODEV;
-			goto end;
-		}
-		/*
-		 * When the device is neither present nor functional, the
-		 * device should not be added to Linux ACPI device tree.
-		 * When the status of the device is not present but functinal,
-		 * it should be added to Linux ACPI tree. For example : bay
-		 * device , dock device.
-		 * In such conditions it is unncessary to check whether it is
-		 * bay device or dock device.
-		 */
-		if (!device->status.present && !device->status.functional) {
-			result = -ENODEV;
-			goto end;
-		}
-		break;
-	default:
-		STRUCT_TO_INT(device->status) =
-		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
-		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
-		break;
-	}
-
-	/*
 	 * Initialize Device
 	 * -----------------
 	 * TBD: Synch with Core's enumeration/initialization process.
@@ -1395,41 +1356,69 @@ end:
 	return result;
 }
 
-static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
-				      void *context, void **return_value)
+#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \
+			  ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING)
+
+static int acpi_bus_type_and_status(acpi_handle handle, int *type,
+				    unsigned long long *sta)
 {
-	acpi_status status = AE_OK;
-	struct acpi_device *device = NULL;
-	acpi_object_type type = 0;
-	struct acpi_bus_ops *ops = context;
+	acpi_status status;
+	acpi_object_type acpi_type;
 
-	status = acpi_get_type(handle, &type);
+	status = acpi_get_type(handle, &acpi_type);
 	if (ACPI_FAILURE(status))
-		return AE_OK;
+		return -ENODEV;
 
-	/*
-	 * We're only interested in objects that we consider 'devices'.
-	 */
-	switch (type) {
+	switch (acpi_type) {
 	case ACPI_TYPE_ANY:		/* for ACPI_ROOT_OBJECT */
 	case ACPI_TYPE_DEVICE:
-		type = ACPI_BUS_TYPE_DEVICE;
+		*type = ACPI_BUS_TYPE_DEVICE;
+		status = acpi_bus_get_status_handle(handle, sta);
+		if (ACPI_FAILURE(status))
+			return -ENODEV;
 		break;
 	case ACPI_TYPE_PROCESSOR:
-		type = ACPI_BUS_TYPE_PROCESSOR;
+		*type = ACPI_BUS_TYPE_PROCESSOR;
+		status = acpi_bus_get_status_handle(handle, sta);
+		if (ACPI_FAILURE(status))
+			return -ENODEV;
 		break;
 	case ACPI_TYPE_THERMAL:
-		type = ACPI_BUS_TYPE_THERMAL;
+		*type = ACPI_BUS_TYPE_THERMAL;
+		*sta = ACPI_STA_DEFAULT;
 		break;
 	case ACPI_TYPE_POWER:
-		type = ACPI_BUS_TYPE_POWER;
+		*type = ACPI_BUS_TYPE_POWER;
+		*sta = ACPI_STA_DEFAULT;
 		break;
 	default:
-		return AE_OK;
+		return -ENODEV;
 	}
 
+	return 0;
+}
+
+static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
+				      void *context, void **return_value)
+{
+	struct acpi_bus_ops *ops = context;
+	struct acpi_device *device = NULL;
+	acpi_status status;
+	int type;
+	unsigned long long sta;
+	int result;
+
+	result = acpi_bus_type_and_status(handle, &type, &sta);
+	if (result)
+		return AE_OK;
+
+	if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
+	    !(sta & ACPI_STA_DEVICE_FUNCTIONING))
+		return AE_CTRL_DEPTH;
+
 	if (ops->acpi_op_add)
-		status = acpi_add_single_object(&device, handle, type, ops);
+		status = acpi_add_single_object(&device, handle, type, sta,
+						ops);
 	else
 		status = acpi_bus_get_device(handle, &device);
 
@@ -1442,22 +1431,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
 			return AE_CTRL_DEPTH;
 	}
 
-	/*
-	 * If the device is present, enabled, and functioning then
-	 * parse its scope (depth-first).  Note that we need to
-	 * represent absent devices to facilitate PnP notifications
-	 * -- but only the subtree head (not all of its children,
-	 * which will be enumerated when the parent is inserted).
-	 *
-	 * TBD: Need notifications and other detection mechanisms
-	 *      in place before we can fully implement this.
-	 *
-	 * When the device is not present but functional, it is also
-	 * necessary to scan the children of this device.
-	 */
-	if (!device->status.present && !device->status.functional)
-		return AE_CTRL_DEPTH;
-
 	if (!*return_value)
 		*return_value = device;
 	return AE_OK;
@@ -1581,12 +1554,14 @@ static int acpi_bus_scan_fixed(void)
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, NULL,
 						ACPI_BUS_TYPE_POWER_BUTTON,
+						ACPI_STA_DEFAULT,
 						&ops);
 	}
 
 	if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) {
 		result = acpi_add_single_object(&device, NULL,
 						ACPI_BUS_TYPE_SLEEP_BUTTON,
+						ACPI_STA_DEFAULT,
 						&ops);
 	}
 


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist
  2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (17 preceding siblings ...)
  2009-08-31 22:33 ` [PATCH 2 18/19] ACPI: factor out device type and status checking Bjorn Helgaas
@ 2009-08-31 22:33 ` Bjorn Helgaas
  18 siblings, 0 replies; 23+ messages in thread
From: Bjorn Helgaas @ 2009-08-31 22:33 UTC (permalink / raw)
  To: Len Brown; +Cc: linux-acpi

acpi_bus_scan() traverses the namespace to enumerate devices and uses
acpi_add_single_object() to create acpi_devices.  When the platform
notifies us of a hot-plug event, we need to traverse part of the namespace
again to figure out what appeared or disappeared.  (We don't yet call
acpi_bus_scan() during hot-plug, but I plan to do that in the future.)

This patch makes acpi_add_single_object() notice when we already have
an acpi_device, so we don't need to make a new one.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
---
 drivers/acpi/scan.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 61a7e16..54f5514 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1402,10 +1402,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
 				      void *context, void **return_value)
 {
 	struct acpi_bus_ops *ops = context;
-	struct acpi_device *device = NULL;
-	acpi_status status;
 	int type;
 	unsigned long long sta;
+	struct acpi_device *device;
+	acpi_status status;
 	int result;
 
 	result = acpi_bus_type_and_status(handle, &type, &sta);
@@ -1416,13 +1416,16 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl,
 	    !(sta & ACPI_STA_DEVICE_FUNCTIONING))
 		return AE_CTRL_DEPTH;
 
-	if (ops->acpi_op_add)
-		status = acpi_add_single_object(&device, handle, type, sta,
-						ops);
-	else
-		status = acpi_bus_get_device(handle, &device);
+	/*
+	 * We may already have an acpi_device from a previous enumeration.  If
+	 * so, we needn't add it again, but we may still have to start it.
+	 */
+	device = NULL;
+	acpi_bus_get_device(handle, &device);
+	if (ops->acpi_op_add && !device)
+		acpi_add_single_object(&device, handle, type, sta, ops);
 
-	if (ACPI_FAILURE(status))
+	if (!device)
 		return AE_CTRL_DEPTH;
 
 	if (ops->acpi_op_start && !(ops->acpi_op_add)) {


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 2 01/19] ACPI: simplify deferred execution path
  2009-08-31 22:32 ` [PATCH 2 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
@ 2009-09-19  6:25   ` Len Brown
  0 siblings, 0 replies; 23+ messages in thread
From: Len Brown @ 2009-09-19  6:25 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-acpi

applied

thanks,
Len Brown, Intel Open Source Technology Center


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2 02/19] ACPI: remove null pointer checks in deferred execution path
  2009-08-31 22:32 ` [PATCH 2 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
@ 2009-09-19  6:25   ` Len Brown
  0 siblings, 0 replies; 23+ messages in thread
From: Len Brown @ 2009-09-19  6:25 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-acpi

applied

thanks,
Len Brown, Intel Open Source Technology Center


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications
  2009-08-31 22:32 ` [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
@ 2009-09-19  6:26   ` Len Brown
  0 siblings, 0 replies; 23+ messages in thread
From: Len Brown @ 2009-09-19  6:26 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-acpi

applied

thanks,
Len Brown, Intel Open Source Technology Center


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2009-09-19  6:26 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-31 22:32 [PATCH 2 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
2009-09-19  6:25   ` Len Brown
2009-08-31 22:32 ` [PATCH 2 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
2009-09-19  6:25   ` Len Brown
2009-08-31 22:32 ` [PATCH 2 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
2009-09-19  6:26   ` Len Brown
2009-08-31 22:32 ` [PATCH 2 04/19] ACPI: add debug for device addition Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 06/19] ACPI: remove redundant "handle" and "parent" arguments Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 07/19] ACPI: save device_type in acpi_device Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 08/19] ACPI: use device_type rather than comparing HID Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 09/19] ACPI: remove acpi_device_set_context() "type" argument Bjorn Helgaas
2009-08-31 22:32 ` [PATCH 2 10/19] ACPI: remove redundant "type" arguments Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 11/19] ACPI: remove unnecessary argument checking Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 16/19] ACPI: use acpi_walk_namespace() to enumerate devices Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 17/19] ACPI: add acpi_bus_get_status_handle() Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 18/19] ACPI: factor out device type and status checking Bjorn Helgaas
2009-08-31 22:33 ` [PATCH 2 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).