aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/dock.c103
1 files changed, 45 insertions, 58 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index cfcd8eeb3b2a..d4c3d82bef3f 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -238,6 +238,7 @@ static int is_battery(acpi_handle handle)
238static int is_ejectable_bay(acpi_handle handle) 238static int is_ejectable_bay(acpi_handle handle)
239{ 239{
240 acpi_handle phandle; 240 acpi_handle phandle;
241
241 if (!is_ejectable(handle)) 242 if (!is_ejectable(handle))
242 return 0; 243 return 0;
243 if (is_battery(handle) || is_ata(handle)) 244 if (is_battery(handle) || is_ata(handle))
@@ -264,14 +265,13 @@ int is_dock_device(acpi_handle handle)
264 265
265 if (is_dock(handle)) 266 if (is_dock(handle))
266 return 1; 267 return 1;
267 list_for_each_entry(dock_station, &dock_stations, sibling) { 268
269 list_for_each_entry(dock_station, &dock_stations, sibling)
268 if (find_dock_dependent_device(dock_station, handle)) 270 if (find_dock_dependent_device(dock_station, handle))
269 return 1; 271 return 1;
270 }
271 272
272 return 0; 273 return 0;
273} 274}
274
275EXPORT_SYMBOL_GPL(is_dock_device); 275EXPORT_SYMBOL_GPL(is_dock_device);
276 276
277/** 277/**
@@ -294,8 +294,6 @@ static int dock_present(struct dock_station *ds)
294 return 0; 294 return 0;
295} 295}
296 296
297
298
299/** 297/**
300 * dock_create_acpi_device - add new devices to acpi 298 * dock_create_acpi_device - add new devices to acpi
301 * @handle - handle of the device to add 299 * @handle - handle of the device to add
@@ -309,7 +307,7 @@ static int dock_present(struct dock_station *ds)
309 */ 307 */
310static struct acpi_device * dock_create_acpi_device(acpi_handle handle) 308static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
311{ 309{
312 struct acpi_device *device = NULL; 310 struct acpi_device *device;
313 struct acpi_device *parent_device; 311 struct acpi_device *parent_device;
314 acpi_handle parent; 312 acpi_handle parent;
315 int ret; 313 int ret;
@@ -326,8 +324,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
326 ret = acpi_bus_add(&device, parent_device, handle, 324 ret = acpi_bus_add(&device, parent_device, handle,
327 ACPI_BUS_TYPE_DEVICE); 325 ACPI_BUS_TYPE_DEVICE);
328 if (ret) { 326 if (ret) {
329 pr_debug("error adding bus, %x\n", 327 pr_debug("error adding bus, %x\n", -ret);
330 -ret);
331 return NULL; 328 return NULL;
332 } 329 }
333 } 330 }
@@ -353,7 +350,6 @@ static void dock_remove_acpi_device(acpi_handle handle)
353 } 350 }
354} 351}
355 352
356
357/** 353/**
358 * hotplug_dock_devices - insert or remove devices on the dock station 354 * hotplug_dock_devices - insert or remove devices on the dock station
359 * @ds: the dock station 355 * @ds: the dock station
@@ -373,10 +369,9 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
373 /* 369 /*
374 * First call driver specific hotplug functions 370 * First call driver specific hotplug functions
375 */ 371 */
376 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { 372 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
377 if (dd->ops && dd->ops->handler) 373 if (dd->ops && dd->ops->handler)
378 dd->ops->handler(dd->handle, event, dd->context); 374 dd->ops->handler(dd->handle, event, dd->context);
379 }
380 375
381 /* 376 /*
382 * Now make sure that an acpi_device is created for each 377 * Now make sure that an acpi_device is created for each
@@ -415,6 +410,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
415 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) 410 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
416 if (dd->ops && dd->ops->uevent) 411 if (dd->ops && dd->ops->uevent)
417 dd->ops->uevent(dd->handle, event, dd->context); 412 dd->ops->uevent(dd->handle, event, dd->context);
413
418 if (num != DOCK_EVENT) 414 if (num != DOCK_EVENT)
419 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 415 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
420} 416}
@@ -445,8 +441,8 @@ static void eject_dock(struct dock_station *ds)
445 arg.type = ACPI_TYPE_INTEGER; 441 arg.type = ACPI_TYPE_INTEGER;
446 arg.integer.value = 1; 442 arg.integer.value = 1;
447 443
448 if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0", 444 status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL);
449 &arg_list, NULL))) 445 if (ACPI_FAILURE(status))
450 pr_debug("Failed to evaluate _EJ0!\n"); 446 pr_debug("Failed to evaluate _EJ0!\n");
451} 447}
452 448
@@ -566,7 +562,6 @@ int register_dock_notifier(struct notifier_block *nb)
566 562
567 return atomic_notifier_chain_register(&dock_notifier_list, nb); 563 return atomic_notifier_chain_register(&dock_notifier_list, nb);
568} 564}
569
570EXPORT_SYMBOL_GPL(register_dock_notifier); 565EXPORT_SYMBOL_GPL(register_dock_notifier);
571 566
572/** 567/**
@@ -580,7 +575,6 @@ void unregister_dock_notifier(struct notifier_block *nb)
580 575
581 atomic_notifier_chain_unregister(&dock_notifier_list, nb); 576 atomic_notifier_chain_unregister(&dock_notifier_list, nb);
582} 577}
583
584EXPORT_SYMBOL_GPL(unregister_dock_notifier); 578EXPORT_SYMBOL_GPL(unregister_dock_notifier);
585 579
586/** 580/**
@@ -625,7 +619,6 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
625 619
626 return ret; 620 return ret;
627} 621}
628
629EXPORT_SYMBOL_GPL(register_hotplug_dock_device); 622EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
630 623
631/** 624/**
@@ -646,7 +639,6 @@ void unregister_hotplug_dock_device(acpi_handle handle)
646 dock_del_hotplug_device(dock_station, dd); 639 dock_del_hotplug_device(dock_station, dd);
647 } 640 }
648} 641}
649
650EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); 642EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
651 643
652/** 644/**
@@ -761,7 +753,7 @@ struct dock_data {
761 753
762static void acpi_dock_deferred_cb(void *context) 754static void acpi_dock_deferred_cb(void *context)
763{ 755{
764 struct dock_data *data = (struct dock_data *)context; 756 struct dock_data *data = context;
765 757
766 dock_notify(data->handle, data->event, data->ds); 758 dock_notify(data->handle, data->event, data->ds);
767 kfree(data); 759 kfree(data);
@@ -771,23 +763,22 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
771 unsigned long event, void *data) 763 unsigned long event, void *data)
772{ 764{
773 struct dock_station *dock_station; 765 struct dock_station *dock_station;
774 acpi_handle handle = (acpi_handle)data; 766 acpi_handle handle = data;
775 767
776 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 768 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
777 && event != ACPI_NOTIFY_EJECT_REQUEST) 769 && event != ACPI_NOTIFY_EJECT_REQUEST)
778 return 0; 770 return 0;
779 list_for_each_entry(dock_station, &dock_stations, sibling) { 771 list_for_each_entry(dock_station, &dock_stations, sibling) {
780 if (dock_station->handle == handle) { 772 if (dock_station->handle == handle) {
781 struct dock_data *dock_data; 773 struct dock_data *dd;
782 774
783 dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL); 775 dd = kmalloc(sizeof(*dd), GFP_KERNEL);
784 if (!dock_data) 776 if (!dd)
785 return 0; 777 return 0;
786 dock_data->handle = handle; 778 dd->handle = handle;
787 dock_data->event = event; 779 dd->event = event;
788 dock_data->ds = dock_station; 780 dd->ds = dock_station;
789 acpi_os_hotplug_execute(acpi_dock_deferred_cb, 781 acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
790 dock_data);
791 return 0 ; 782 return 0 ;
792 } 783 }
793 } 784 }
@@ -941,28 +932,28 @@ static int dock_add(acpi_handle handle)
941{ 932{
942 int ret, id; 933 int ret, id;
943 struct dock_station ds, *dock_station; 934 struct dock_station ds, *dock_station;
944 struct platform_device *dock_device; 935 struct platform_device *dd;
945 936
946 id = dock_station_count; 937 id = dock_station_count;
947 dock_device = 938 dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
948 platform_device_register_data(NULL, "dock", 939 if (IS_ERR(dd))
949 id, &ds, sizeof(ds)); 940 return PTR_ERR(dd);
950 if (IS_ERR(dock_device)) 941
951 return PTR_ERR(dock_device); 942 dock_station = dd->dev.platform_data;
952 943
953 dock_station = dock_device->dev.platform_data;
954 dock_station->handle = handle; 944 dock_station->handle = handle;
955 dock_station->dock_device = dock_device; 945 dock_station->dock_device = dd;
956 dock_station->last_dock_time = jiffies - HZ; 946 dock_station->last_dock_time = jiffies - HZ;
957 INIT_LIST_HEAD(&dock_station->dependent_devices); 947
958 INIT_LIST_HEAD(&dock_station->hotplug_devices);
959 INIT_LIST_HEAD(&dock_station->sibling);
960 spin_lock_init(&dock_station->dd_lock);
961 mutex_init(&dock_station->hp_lock); 948 mutex_init(&dock_station->hp_lock);
949 spin_lock_init(&dock_station->dd_lock);
950 INIT_LIST_HEAD(&dock_station->sibling);
951 INIT_LIST_HEAD(&dock_station->hotplug_devices);
962 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 952 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
953 INIT_LIST_HEAD(&dock_station->dependent_devices);
963 954
964 /* we want the dock device to send uevents */ 955 /* we want the dock device to send uevents */
965 dev_set_uevent_suppress(&dock_device->dev, 0); 956 dev_set_uevent_suppress(&dd->dev, 0);
966 957
967 if (is_dock(handle)) 958 if (is_dock(handle))
968 dock_station->flags |= DOCK_IS_DOCK; 959 dock_station->flags |= DOCK_IS_DOCK;
@@ -971,14 +962,13 @@ static int dock_add(acpi_handle handle)
971 if (is_battery(handle)) 962 if (is_battery(handle))
972 dock_station->flags |= DOCK_IS_BAT; 963 dock_station->flags |= DOCK_IS_BAT;
973 964
974 ret = sysfs_create_group(&dock_device->dev.kobj, &dock_attribute_group); 965 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
975 if (ret) 966 if (ret)
976 goto err_unregister; 967 goto err_unregister;
977 968
978 /* Find dependent devices */ 969 /* Find dependent devices */
979 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 970 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX,
980 ACPI_UINT32_MAX, find_dock_devices, dock_station, 971 find_dock_devices, dock_station, NULL);
981 NULL);
982 972
983 /* add the dock station as a device dependent on itself */ 973 /* add the dock station as a device dependent on itself */
984 ret = add_dock_dependent_device(dock_station, handle); 974 ret = add_dock_dependent_device(dock_station, handle);
@@ -990,9 +980,9 @@ static int dock_add(acpi_handle handle)
990 return 0; 980 return 0;
991 981
992err_rmgroup: 982err_rmgroup:
993 sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); 983 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
994err_unregister: 984err_unregister:
995 platform_device_unregister(dock_device); 985 platform_device_unregister(dd);
996 printk(KERN_ERR "%s encountered error %d\n", __func__, ret); 986 printk(KERN_ERR "%s encountered error %d\n", __func__, ret);
997 return ret; 987 return ret;
998} 988}
@@ -1000,20 +990,19 @@ err_unregister:
1000/** 990/**
1001 * dock_remove - free up resources related to the dock station 991 * dock_remove - free up resources related to the dock station
1002 */ 992 */
1003static int dock_remove(struct dock_station *dock_station) 993static int dock_remove(struct dock_station *ds)
1004{ 994{
1005 struct dock_dependent_device *dd, *tmp; 995 struct dock_dependent_device *dd, *tmp;
1006 struct platform_device *dock_device = dock_station->dock_device; 996 struct platform_device *dock_device = ds->dock_device;
1007 997
1008 if (!dock_station_count) 998 if (!dock_station_count)
1009 return 0; 999 return 0;
1010 1000
1011 /* remove dependent devices */ 1001 /* remove dependent devices */
1012 list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices, 1002 list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list)
1013 list) 1003 kfree(dd);
1014 kfree(dd);
1015 1004
1016 list_del(&dock_station->sibling); 1005 list_del(&ds->sibling);
1017 1006
1018 /* cleanup sysfs */ 1007 /* cleanup sysfs */
1019 sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group); 1008 sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group);
@@ -1036,11 +1025,10 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
1036{ 1025{
1037 acpi_status status = AE_OK; 1026 acpi_status status = AE_OK;
1038 1027
1039 if (is_dock(handle)) { 1028 if (is_dock(handle))
1040 if (dock_add(handle) >= 0) { 1029 if (dock_add(handle) >= 0)
1041 status = AE_CTRL_TERMINATE; 1030 status = AE_CTRL_TERMINATE;
1042 } 1031
1043 }
1044 return status; 1032 return status;
1045} 1033}
1046 1034
@@ -1078,8 +1066,7 @@ static int __init dock_init(void)
1078 1066
1079static void __exit dock_exit(void) 1067static void __exit dock_exit(void)
1080{ 1068{
1081 struct dock_station *dock_station; 1069 struct dock_station *tmp, *dock_station;
1082 struct dock_station *tmp;
1083 1070
1084 unregister_acpi_bus_notifier(&dock_acpi_notifier); 1071 unregister_acpi_bus_notifier(&dock_acpi_notifier);
1085 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) 1072 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)