summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/platform/x86/wmi.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index 651693a5e0ea..fbce8765e222 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -796,7 +796,7 @@ static struct device_type wmi_type_data = {
.release = wmi_dev_release,
};
-static int wmi_create_device(struct device *wmi_bus_dev,
+static void wmi_create_device(struct device *wmi_bus_dev,
const struct guid_block *gblock,
struct wmi_block *wblock,
struct acpi_device *device)
@@ -852,7 +852,7 @@ static int wmi_create_device(struct device *wmi_bus_dev,
}
- return device_register(&wblock->dev.dev);
+ device_initialize(&wblock->dev.dev);
}
static void wmi_free_devices(struct acpi_device *device)
@@ -863,10 +863,7 @@ static void wmi_free_devices(struct acpi_device *device)
list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
if (wblock->acpi_device == device) {
list_del(&wblock->list);
- if (wblock->dev.dev.bus)
- device_unregister(&wblock->dev.dev);
- else
- kfree(wblock);
+ device_unregister(&wblock->dev.dev);
}
}
}
@@ -899,11 +896,11 @@ static bool guid_already_parsed(struct acpi_device *device,
static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
{
struct acpi_buffer out = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *obj;
const struct guid_block *gblock;
- struct wmi_block *wblock;
+ struct wmi_block *wblock, *next;
+ union acpi_object *obj;
acpi_status status;
- int retval;
+ int retval = 0;
u32 i, total;
status = acpi_evaluate_object(device->handle, "_WDG", NULL, &out);
@@ -936,19 +933,15 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
continue;
wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
- if (!wblock)
- return -ENOMEM;
+ if (!wblock) {
+ retval = -ENOMEM;
+ break;
+ }
wblock->acpi_device = device;
wblock->gblock = gblock[i];
- retval = wmi_create_device(wmi_bus_dev, &gblock[i],
- wblock, device);
- if (retval) {
- put_device(&wblock->dev.dev);
- wmi_free_devices(device);
- goto out_free_pointer;
- }
+ wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device);
list_add_tail(&wblock->list, &wmi_block_list);
@@ -958,11 +951,27 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)
}
}
- retval = 0;
+ /*
+ * Now that all of the devices are created, add them to the
+ * device tree and probe subdrivers.
+ */
+ list_for_each_entry_safe(wblock, next, &wmi_block_list, list) {
+ if (wblock->acpi_device != device)
+ continue;
+
+ retval = device_add(&wblock->dev.dev);
+ if (retval) {
+ dev_err(wmi_bus_dev, "failed to register %pULL\n",
+ wblock->gblock.guid);
+ if (debug_event)
+ wmi_method_enable(wblock, 0);
+ list_del(&wblock->list);
+ put_device(&wblock->dev.dev);
+ }
+ }
out_free_pointer:
kfree(out.pointer);
-
return retval;
}