diff options
Diffstat (limited to 'drivers/acpi/dock.c')
-rw-r--r-- | drivers/acpi/dock.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index f32bd47b35e0..4fdea381ef21 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -310,8 +310,6 @@ static int dock_present(struct dock_station *ds) | |||
310 | static struct acpi_device * dock_create_acpi_device(acpi_handle handle) | 310 | static struct acpi_device * dock_create_acpi_device(acpi_handle handle) |
311 | { | 311 | { |
312 | struct acpi_device *device; | 312 | struct acpi_device *device; |
313 | struct acpi_device *parent_device; | ||
314 | acpi_handle parent; | ||
315 | int ret; | 313 | int ret; |
316 | 314 | ||
317 | if (acpi_bus_get_device(handle, &device)) { | 315 | if (acpi_bus_get_device(handle, &device)) { |
@@ -319,16 +317,11 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) | |||
319 | * no device created for this object, | 317 | * no device created for this object, |
320 | * so we should create one. | 318 | * so we should create one. |
321 | */ | 319 | */ |
322 | acpi_get_parent(handle, &parent); | 320 | ret = acpi_bus_scan(handle); |
323 | if (acpi_bus_get_device(parent, &parent_device)) | 321 | if (ret) |
324 | parent_device = NULL; | ||
325 | |||
326 | ret = acpi_bus_add(&device, parent_device, handle, | ||
327 | ACPI_BUS_TYPE_DEVICE); | ||
328 | if (ret) { | ||
329 | pr_debug("error adding bus, %x\n", -ret); | 322 | pr_debug("error adding bus, %x\n", -ret); |
330 | return NULL; | 323 | |
331 | } | 324 | acpi_bus_get_device(handle, &device); |
332 | } | 325 | } |
333 | return device; | 326 | return device; |
334 | } | 327 | } |
@@ -343,13 +336,9 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle) | |||
343 | static void dock_remove_acpi_device(acpi_handle handle) | 336 | static void dock_remove_acpi_device(acpi_handle handle) |
344 | { | 337 | { |
345 | struct acpi_device *device; | 338 | struct acpi_device *device; |
346 | int ret; | ||
347 | 339 | ||
348 | if (!acpi_bus_get_device(handle, &device)) { | 340 | if (!acpi_bus_get_device(handle, &device)) |
349 | ret = acpi_bus_trim(device, 1); | 341 | acpi_bus_trim(device); |
350 | if (ret) | ||
351 | pr_debug("error removing bus, %x\n", -ret); | ||
352 | } | ||
353 | } | 342 | } |
354 | 343 | ||
355 | /** | 344 | /** |
@@ -755,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context) | |||
755 | { | 744 | { |
756 | struct dock_data *data = context; | 745 | struct dock_data *data = context; |
757 | 746 | ||
747 | acpi_scan_lock_acquire(); | ||
758 | dock_notify(data->handle, data->event, data->ds); | 748 | dock_notify(data->handle, data->event, data->ds); |
749 | acpi_scan_lock_release(); | ||
759 | kfree(data); | 750 | kfree(data); |
760 | } | 751 | } |
761 | 752 | ||
@@ -768,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this, | |||
768 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK | 759 | if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK |
769 | && event != ACPI_NOTIFY_EJECT_REQUEST) | 760 | && event != ACPI_NOTIFY_EJECT_REQUEST) |
770 | return 0; | 761 | return 0; |
762 | |||
763 | acpi_scan_lock_acquire(); | ||
764 | |||
771 | list_for_each_entry(dock_station, &dock_stations, sibling) { | 765 | list_for_each_entry(dock_station, &dock_stations, sibling) { |
772 | if (dock_station->handle == handle) { | 766 | if (dock_station->handle == handle) { |
773 | struct dock_data *dd; | 767 | struct dock_data *dd; |
768 | acpi_status status; | ||
774 | 769 | ||
775 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); | 770 | dd = kmalloc(sizeof(*dd), GFP_KERNEL); |
776 | if (!dd) | 771 | if (!dd) |
777 | return 0; | 772 | break; |
773 | |||
778 | dd->handle = handle; | 774 | dd->handle = handle; |
779 | dd->event = event; | 775 | dd->event = event; |
780 | dd->ds = dock_station; | 776 | dd->ds = dock_station; |
781 | acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); | 777 | status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, |
782 | return 0 ; | 778 | dd); |
779 | if (ACPI_FAILURE(status)) | ||
780 | kfree(dd); | ||
781 | |||
782 | break; | ||
783 | } | 783 | } |
784 | } | 784 | } |
785 | |||
786 | acpi_scan_lock_release(); | ||
785 | return 0; | 787 | return 0; |
786 | } | 788 | } |
787 | 789 | ||
@@ -836,7 +838,7 @@ static ssize_t show_docked(struct device *dev, | |||
836 | 838 | ||
837 | struct dock_station *dock_station = dev->platform_data; | 839 | struct dock_station *dock_station = dev->platform_data; |
838 | 840 | ||
839 | if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) | 841 | if (!acpi_bus_get_device(dock_station->handle, &tmp)) |
840 | return snprintf(buf, PAGE_SIZE, "1\n"); | 842 | return snprintf(buf, PAGE_SIZE, "1\n"); |
841 | return snprintf(buf, PAGE_SIZE, "0\n"); | 843 | return snprintf(buf, PAGE_SIZE, "0\n"); |
842 | } | 844 | } |