ACPI: handle re-enumeration, when acpi_devices might already exist
authorBjorn Helgaas <bjorn.helgaas@hp.com>
Mon, 21 Sep 2009 19:30:11 +0000 (19:30 +0000)
committerLen Brown <len.brown@intel.com>
Fri, 25 Sep 2009 18:24:32 +0000 (14:24 -0400)
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>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/scan.c

index 954bd01f295a06d090604f19414e14e9dcd78499..2c4cac576a7e3692f132758fde83b5d13aaf8759 100644 (file)
@@ -1400,10 +1400,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);
@@ -1414,13 +1414,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)) {