All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] ACPI: cleanups for hotplug
@ 2009-07-31 21:36 Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
                   ` (19 more replies)
  0 siblings, 20 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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.

---

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     |  428 +++++++++++++++++++++--------------------------
 include/acpi/acpi_bus.h |    6 -
 4 files changed, 221 insertions(+), 294 deletions(-)

-- 
Bjorn

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

* [PATCH 01/19] ACPI: simplify deferred execution path
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
@ 2009-07-31 21:36 ` Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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 5691f16..10df23d 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
@@ -702,21 +703,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);
@@ -745,7 +733,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",
@@ -778,8 +765,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] 22+ messages in thread

* [PATCH 02/19] ACPI: remove null pointer checks in deferred execution path
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
@ 2009-07-31 21:36 ` Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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 10df23d..fe73e28 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -698,18 +698,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;
 }
 
 /*******************************************************************************
@@ -738,9 +732,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] 22+ messages in thread

* [PATCH 03/19] ACPI: don't pass handle for fixed hardware notifications
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 01/19] ACPI: simplify deferred execution path Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 02/19] ACPI: remove null pointer checks in " Bjorn Helgaas
@ 2009-07-31 21:36 ` Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 04/19] ACPI: add debug for device addition Bjorn Helgaas
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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 4a89f08..652d104 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] 22+ messages in thread

* [PATCH 04/19] ACPI: add debug for device addition
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (2 preceding siblings ...)
  2009-07-31 21:36 ` [PATCH 03/19] ACPI: don't pass handle for fixed hardware notifications Bjorn Helgaas
@ 2009-07-31 21:36 ` Bjorn Helgaas
  2009-07-31 21:36 ` [PATCH 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument Bjorn Helgaas
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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 |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 652d104..92b4fe2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1178,6 +1178,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)
@@ -1311,9 +1312,15 @@ 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)"));
 		*child = device;
-	else {
+	} else {
 		kfree(device->pnp.cid_list);
 		kfree(device);
 	}


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

* [PATCH 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (3 preceding siblings ...)
  2009-07-31 21:36 ` [PATCH 04/19] ACPI: add debug for device addition Bjorn Helgaas
@ 2009-07-31 21:36 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 06/19] ACPI: remove redundant "handle" and "parent" arguments Bjorn Helgaas
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:36 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 92b4fe2..091d967 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1537,15 +1537,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;
@@ -1596,7 +1593,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] 22+ messages in thread

* [PATCH 06/19] ACPI: remove redundant "handle" and "parent" arguments
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (4 preceding siblings ...)
  2009-07-31 21:36 ` [PATCH 05/19] ACPI: remove unused acpi_bus_scan_fixed() argument Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 07/19] ACPI: save device_type in acpi_device Bjorn Helgaas
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 091d967..aade372 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] == '_')
@@ -995,9 +994,7 @@ static int acpi_dock_match(struct acpi_device *device)
 	return acpi_get_handle(device->handle, "_DCK", &tmp);
 }
 
-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;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -1009,7 +1006,7 @@ static void acpi_device_set_id(struct acpi_device *device,
 
 	switch (type) {
 	case ACPI_BUS_TYPE_DEVICE:
-		status = acpi_get_object_info(handle, &buffer);
+		status = acpi_get_object_info(device->handle, &buffer);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
 			return;
@@ -1065,7 +1062,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);
@@ -1194,8 +1192,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
@@ -1258,7 +1255,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
@@ -1300,8 +1297,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] 22+ messages in thread

* [PATCH 07/19] ACPI: save device_type in acpi_device
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (5 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 06/19] ACPI: remove redundant "handle" and "parent" arguments Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 08/19] ACPI: use device_type rather than comparing HID Bjorn Helgaas
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 aade372..b386589 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1188,6 +1188,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 79a6c5e..b145270 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -266,7 +266,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] 22+ messages in thread

* [PATCH 08/19] ACPI: use device_type rather than comparing HID
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (6 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 07/19] ACPI: save device_type in acpi_device Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 09/19] ACPI: remove acpi_device_set_context() "type" argument Bjorn Helgaas
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 b386589..f563360 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] 22+ messages in thread

* [PATCH 09/19] ACPI: remove acpi_device_set_context() "type" argument
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (7 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 08/19] ACPI: use device_type rather than comparing HID Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 10/19] ACPI: remove redundant "type" arguments Bjorn Helgaas
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 f563360..4772b43 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1119,29 +1119,27 @@ static void acpi_device_set_id(struct acpi_device *device, int type)
 	kfree(buffer.pointer);
 }
 
-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)
@@ -1262,7 +1260,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] 22+ messages in thread

* [PATCH 10/19] ACPI: remove redundant "type" arguments
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (8 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 09/19] ACPI: remove acpi_device_set_context() "type" argument Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 11/19] ACPI: remove unnecessary argument checking Bjorn Helgaas
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 4772b43..7623a80 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;
@@ -992,7 +992,7 @@ static int acpi_dock_match(struct acpi_device *device)
 	return acpi_get_handle(device->handle, "_DCK", &tmp);
 }
 
-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;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -1002,7 +1002,7 @@ static void acpi_device_set_id(struct acpi_device *device, int type)
 	const 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, &buffer);
 		if (ACPI_FAILURE(status)) {
@@ -1061,7 +1061,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);
@@ -1189,7 +1189,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
@@ -1252,7 +1252,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] 22+ messages in thread

* [PATCH 11/19] ACPI: remove unnecessary argument checking
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (9 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 10/19] ACPI: remove redundant "type" arguments Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments Bjorn Helgaas
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 7623a80..35ea4c2 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1170,14 +1170,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] 22+ messages in thread

* [PATCH 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (10 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 11/19] ACPI: remove unnecessary argument checking Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle Bjorn Helgaas
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 35ea4c2..a57a7ae 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)
 {
@@ -1165,10 +1192,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;
@@ -1182,7 +1208,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);
@@ -1390,8 +1416,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);
 
@@ -1444,7 +1470,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);
 
@@ -1540,15 +1566,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);
 	}
@@ -1574,7 +1598,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] 22+ messages in thread

* [PATCH 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (11 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 12/19] ACPI: add acpi_bus_get_parent() and remove "parent" arguments Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices Bjorn Helgaas
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 a57a7ae..afd10b5 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1343,7 +1343,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;
@@ -1352,13 +1352,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
@@ -1472,7 +1475,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;
 }
@@ -1483,16 +1486,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);
@@ -1609,7 +1609,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] 22+ messages in thread

* [PATCH 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (12 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 13/19] ACPI: convert acpi_bus_scan() to operate on an acpi_handle Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:37 ` [PATCH 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 afd10b5..b97b2ad 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1606,10 +1606,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] 22+ messages in thread

* [PATCH 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (13 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 14/19] ACPI: enumerate namespace before adding functional fixed hardware devices Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-08-02 14:44   ` Len Brown
  2009-07-31 21:37 ` [PATCH 16/19] ACPI: use acpi_walk_namespace() to enumerate devices Bjorn Helgaas
                   ` (4 subsequent siblings)
  19 siblings, 1 reply; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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     |   18 +++++++++++-------
 include/acpi/acpi_bus.h |    1 -
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index b97b2ad..c0736f6 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -950,10 +950,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 (!device->parent) {
 		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;
@@ -1031,6 +1033,11 @@ static void acpi_device_set_id(struct acpi_device *device)
 
 	switch (device->device_type) {
 	case ACPI_BUS_TYPE_DEVICE:
+		if (!device->parent) {
+			hid = ACPI_SYSTEM_HID;
+			break;
+		}
+
 		status = acpi_get_object_info(device->handle, &buffer);
 		if (ACPI_FAILURE(status)) {
 			printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
@@ -1068,9 +1075,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;
@@ -1599,7 +1603,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 b145270..edca7d5 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -72,7 +72,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] 22+ messages in thread

* [PATCH 16/19] ACPI: use acpi_walk_namespace() to enumerate devices
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (14 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
@ 2009-07-31 21:37 ` Bjorn Helgaas
  2009-07-31 21:38 ` [PATCH 17/19] ACPI: add acpi_bus_get_status_handle() Bjorn Helgaas
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:37 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 c0736f6..4bbfde6 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1347,123 +1347,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;
 }
 
@@ -1471,33 +1440,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);
 
@@ -1600,17 +1561,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();
@@ -1618,6 +1571,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] 22+ messages in thread

* [PATCH 17/19] ACPI: add acpi_bus_get_status_handle()
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (15 preceding siblings ...)
  2009-07-31 21:37 ` [PATCH 16/19] ACPI: use acpi_walk_namespace() to enumerate devices Bjorn Helgaas
@ 2009-07-31 21:38 ` Bjorn Helgaas
  2009-07-31 21:38 ` [PATCH 18/19] ACPI: factor out device type and status checking Bjorn Helgaas
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:38 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 2876fc7..e2e922d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -93,36 +93,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]: "
@@ -134,10 +131,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 edca7d5..26be825 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -326,6 +326,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, u32 function, 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] 22+ messages in thread

* [PATCH 18/19] ACPI: factor out device type and status checking
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (16 preceding siblings ...)
  2009-07-31 21:38 ` [PATCH 17/19] ACPI: add acpi_bus_get_status_handle() Bjorn Helgaas
@ 2009-07-31 21:38 ` Bjorn Helgaas
  2009-07-31 21:38 ` [PATCH 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist Bjorn Helgaas
  2009-08-02 15:12 ` [PATCH 00/19] ACPI: cleanups for hotplug Len Brown
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:38 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 4bbfde6..c078390 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1198,6 +1198,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;
@@ -1214,61 +1215,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.
@@ -1347,41 +1308,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);
 
@@ -1394,22 +1383,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;
@@ -1533,12 +1506,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] 22+ messages in thread

* [PATCH 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (17 preceding siblings ...)
  2009-07-31 21:38 ` [PATCH 18/19] ACPI: factor out device type and status checking Bjorn Helgaas
@ 2009-07-31 21:38 ` Bjorn Helgaas
  2009-08-02 15:12 ` [PATCH 00/19] ACPI: cleanups for hotplug Len Brown
  19 siblings, 0 replies; 22+ messages in thread
From: Bjorn Helgaas @ 2009-07-31 21:38 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 c078390..87d3df4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1354,10 +1354,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);
@@ -1368,13 +1368,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] 22+ messages in thread

* Re: [PATCH 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE
  2009-07-31 21:37 ` [PATCH 15/19] ACPI: identify device tree root by null parent pointer, not ACPI_BUS_TYPE Bjorn Helgaas
@ 2009-08-02 14:44   ` Len Brown
  0 siblings, 0 replies; 22+ messages in thread
From: Len Brown @ 2009-08-02 14:44 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-acpi

On Fri, 31 Jul 2009, Bjorn Helgaas wrote:

> 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     |   18 +++++++++++-------
>  include/acpi/acpi_bus.h |    1 -
>  2 files changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index b97b2ad..c0736f6 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -950,10 +950,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 (!device->parent) {

it is just a style thing, but i probably would
use a macro for this, such as ACPI_IS_ROOT(device)
to make the code read easier to the un-initiated.

thanks,
-Len Brown, Intel Open Source Technology Center



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

* Re: [PATCH 00/19] ACPI: cleanups for hotplug
  2009-07-31 21:36 [PATCH 00/19] ACPI: cleanups for hotplug Bjorn Helgaas
                   ` (18 preceding siblings ...)
  2009-07-31 21:38 ` [PATCH 19/19] ACPI: handle re-enumeration, when acpi_devices might already exist Bjorn Helgaas
@ 2009-08-02 15:12 ` Len Brown
  19 siblings, 0 replies; 22+ messages in thread
From: Len Brown @ 2009-08-02 15:12 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-acpi

series applied to acpi-test

thanks,
Len Brown, Intel Open Source Technology Center


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

end of thread, other threads:[~2009-08-02 15:17 UTC | newest]

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.