aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dock.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-12-16 03:33:28 -0500
committerLen Brown <len.brown@intel.com>2009-12-16 03:33:28 -0500
commitf02f465b1cdcdf7485f89ec019e6cceaf80cadd5 (patch)
tree4219772e39848f31b9554786de5a18c026dfe2e5 /drivers/acpi/dock.c
parentb6202832b43abb56b90ba8d68e2b9fc53c442fa6 (diff)
parent747479a3fb42849fe73b9b1f7545d751bde7d632 (diff)
Merge branch 'dock' into release
Conflicts: drivers/acpi/dock.c Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dock.c')
-rw-r--r--drivers/acpi/dock.c261
1 files changed, 91 insertions, 170 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 30be3c148f7e..bbc2c1315c47 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -50,7 +50,6 @@ MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
50 " before undocking"); 50 " before undocking");
51 51
52static struct atomic_notifier_head dock_notifier_list; 52static struct atomic_notifier_head dock_notifier_list;
53static char dock_device_name[] = "dock";
54 53
55static const struct acpi_device_id dock_device_ids[] = { 54static const struct acpi_device_id dock_device_ids[] = {
56 {"LNXDOCK", 0}, 55 {"LNXDOCK", 0},
@@ -93,40 +92,30 @@ struct dock_dependent_device {
93 * Dock Dependent device functions * 92 * Dock Dependent device functions *
94 *****************************************************************************/ 93 *****************************************************************************/
95/** 94/**
96 * alloc_dock_dependent_device - allocate and init a dependent device 95 * add_dock_dependent_device - associate a device with the dock station
97 * @handle: the acpi_handle of the dependent device 96 * @ds: The dock station
97 * @handle: handle of the dependent device
98 * 98 *
99 * Allocate memory for a dependent device structure for a device referenced 99 * Add the dependent device to the dock's dependent device list.
100 * by the acpi handle
101 */ 100 */
102static struct dock_dependent_device * 101static int
103alloc_dock_dependent_device(acpi_handle handle) 102add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
104{ 103{
105 struct dock_dependent_device *dd; 104 struct dock_dependent_device *dd;
106 105
107 dd = kzalloc(sizeof(*dd), GFP_KERNEL); 106 dd = kzalloc(sizeof(*dd), GFP_KERNEL);
108 if (dd) { 107 if (!dd)
109 dd->handle = handle; 108 return -ENOMEM;
110 INIT_LIST_HEAD(&dd->list); 109
111 INIT_LIST_HEAD(&dd->hotplug_list); 110 dd->handle = handle;
112 } 111 INIT_LIST_HEAD(&dd->list);
113 return dd; 112 INIT_LIST_HEAD(&dd->hotplug_list);
114}
115 113
116/**
117 * add_dock_dependent_device - associate a device with the dock station
118 * @ds: The dock station
119 * @dd: The dependent device
120 *
121 * Add the dependent device to the dock's dependent device list.
122 */
123static void
124add_dock_dependent_device(struct dock_station *ds,
125 struct dock_dependent_device *dd)
126{
127 spin_lock(&ds->dd_lock); 114 spin_lock(&ds->dd_lock);
128 list_add_tail(&dd->list, &ds->dependent_devices); 115 list_add_tail(&dd->list, &ds->dependent_devices);
129 spin_unlock(&ds->dd_lock); 116 spin_unlock(&ds->dd_lock);
117
118 return 0;
130} 119}
131 120
132/** 121/**
@@ -249,6 +238,7 @@ static int is_battery(acpi_handle handle)
249static int is_ejectable_bay(acpi_handle handle) 238static int is_ejectable_bay(acpi_handle handle)
250{ 239{
251 acpi_handle phandle; 240 acpi_handle phandle;
241
252 if (!is_ejectable(handle)) 242 if (!is_ejectable(handle))
253 return 0; 243 return 0;
254 if (is_battery(handle) || is_ata(handle)) 244 if (is_battery(handle) || is_ata(handle))
@@ -275,14 +265,13 @@ int is_dock_device(acpi_handle handle)
275 265
276 if (is_dock(handle)) 266 if (is_dock(handle))
277 return 1; 267 return 1;
278 list_for_each_entry(dock_station, &dock_stations, sibling) { 268
269 list_for_each_entry(dock_station, &dock_stations, sibling)
279 if (find_dock_dependent_device(dock_station, handle)) 270 if (find_dock_dependent_device(dock_station, handle))
280 return 1; 271 return 1;
281 }
282 272
283 return 0; 273 return 0;
284} 274}
285
286EXPORT_SYMBOL_GPL(is_dock_device); 275EXPORT_SYMBOL_GPL(is_dock_device);
287 276
288/** 277/**
@@ -305,8 +294,6 @@ static int dock_present(struct dock_station *ds)
305 return 0; 294 return 0;
306} 295}
307 296
308
309
310/** 297/**
311 * dock_create_acpi_device - add new devices to acpi 298 * dock_create_acpi_device - add new devices to acpi
312 * @handle - handle of the device to add 299 * @handle - handle of the device to add
@@ -320,7 +307,7 @@ static int dock_present(struct dock_station *ds)
320 */ 307 */
321static struct acpi_device * dock_create_acpi_device(acpi_handle handle) 308static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
322{ 309{
323 struct acpi_device *device = NULL; 310 struct acpi_device *device;
324 struct acpi_device *parent_device; 311 struct acpi_device *parent_device;
325 acpi_handle parent; 312 acpi_handle parent;
326 int ret; 313 int ret;
@@ -337,8 +324,7 @@ static struct acpi_device * dock_create_acpi_device(acpi_handle handle)
337 ret = acpi_bus_add(&device, parent_device, handle, 324 ret = acpi_bus_add(&device, parent_device, handle,
338 ACPI_BUS_TYPE_DEVICE); 325 ACPI_BUS_TYPE_DEVICE);
339 if (ret) { 326 if (ret) {
340 pr_debug("error adding bus, %x\n", 327 pr_debug("error adding bus, %x\n", -ret);
341 -ret);
342 return NULL; 328 return NULL;
343 } 329 }
344 } 330 }
@@ -364,7 +350,6 @@ static void dock_remove_acpi_device(acpi_handle handle)
364 } 350 }
365} 351}
366 352
367
368/** 353/**
369 * hotplug_dock_devices - insert or remove devices on the dock station 354 * hotplug_dock_devices - insert or remove devices on the dock station
370 * @ds: the dock station 355 * @ds: the dock station
@@ -384,10 +369,9 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
384 /* 369 /*
385 * First call driver specific hotplug functions 370 * First call driver specific hotplug functions
386 */ 371 */
387 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) { 372 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
388 if (dd->ops && dd->ops->handler) 373 if (dd->ops && dd->ops->handler)
389 dd->ops->handler(dd->handle, event, dd->context); 374 dd->ops->handler(dd->handle, event, dd->context);
390 }
391 375
392 /* 376 /*
393 * Now make sure that an acpi_device is created for each 377 * Now make sure that an acpi_device is created for each
@@ -426,6 +410,7 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
426 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list) 410 list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
427 if (dd->ops && dd->ops->uevent) 411 if (dd->ops && dd->ops->uevent)
428 dd->ops->uevent(dd->handle, event, dd->context); 412 dd->ops->uevent(dd->handle, event, dd->context);
413
429 if (num != DOCK_EVENT) 414 if (num != DOCK_EVENT)
430 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 415 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
431} 416}
@@ -456,8 +441,8 @@ static void eject_dock(struct dock_station *ds)
456 arg.type = ACPI_TYPE_INTEGER; 441 arg.type = ACPI_TYPE_INTEGER;
457 arg.integer.value = 1; 442 arg.integer.value = 1;
458 443
459 if (ACPI_FAILURE(acpi_evaluate_object(ds->handle, "_EJ0", 444 status = acpi_evaluate_object(ds->handle, "_EJ0", &arg_list, NULL);
460 &arg_list, NULL))) 445 if (ACPI_FAILURE(status))
461 pr_debug("Failed to evaluate _EJ0!\n"); 446 pr_debug("Failed to evaluate _EJ0!\n");
462} 447}
463 448
@@ -577,7 +562,6 @@ int register_dock_notifier(struct notifier_block *nb)
577 562
578 return atomic_notifier_chain_register(&dock_notifier_list, nb); 563 return atomic_notifier_chain_register(&dock_notifier_list, nb);
579} 564}
580
581EXPORT_SYMBOL_GPL(register_dock_notifier); 565EXPORT_SYMBOL_GPL(register_dock_notifier);
582 566
583/** 567/**
@@ -591,7 +575,6 @@ void unregister_dock_notifier(struct notifier_block *nb)
591 575
592 atomic_notifier_chain_unregister(&dock_notifier_list, nb); 576 atomic_notifier_chain_unregister(&dock_notifier_list, nb);
593} 577}
594
595EXPORT_SYMBOL_GPL(unregister_dock_notifier); 578EXPORT_SYMBOL_GPL(unregister_dock_notifier);
596 579
597/** 580/**
@@ -636,7 +619,6 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
636 619
637 return ret; 620 return ret;
638} 621}
639
640EXPORT_SYMBOL_GPL(register_hotplug_dock_device); 622EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
641 623
642/** 624/**
@@ -657,7 +639,6 @@ void unregister_hotplug_dock_device(acpi_handle handle)
657 dock_del_hotplug_device(dock_station, dd); 639 dock_del_hotplug_device(dock_station, dd);
658 } 640 }
659} 641}
660
661EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); 642EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
662 643
663/** 644/**
@@ -772,7 +753,7 @@ struct dock_data {
772 753
773static void acpi_dock_deferred_cb(void *context) 754static void acpi_dock_deferred_cb(void *context)
774{ 755{
775 struct dock_data *data = (struct dock_data *)context; 756 struct dock_data *data = context;
776 757
777 dock_notify(data->handle, data->event, data->ds); 758 dock_notify(data->handle, data->event, data->ds);
778 kfree(data); 759 kfree(data);
@@ -782,23 +763,22 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
782 unsigned long event, void *data) 763 unsigned long event, void *data)
783{ 764{
784 struct dock_station *dock_station; 765 struct dock_station *dock_station;
785 acpi_handle handle = (acpi_handle)data; 766 acpi_handle handle = data;
786 767
787 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 768 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
788 && event != ACPI_NOTIFY_EJECT_REQUEST) 769 && event != ACPI_NOTIFY_EJECT_REQUEST)
789 return 0; 770 return 0;
790 list_for_each_entry(dock_station, &dock_stations, sibling) { 771 list_for_each_entry(dock_station, &dock_stations, sibling) {
791 if (dock_station->handle == handle) { 772 if (dock_station->handle == handle) {
792 struct dock_data *dock_data; 773 struct dock_data *dd;
793 774
794 dock_data = kmalloc(sizeof(*dock_data), GFP_KERNEL); 775 dd = kmalloc(sizeof(*dd), GFP_KERNEL);
795 if (!dock_data) 776 if (!dd)
796 return 0; 777 return 0;
797 dock_data->handle = handle; 778 dd->handle = handle;
798 dock_data->event = event; 779 dd->event = event;
799 dock_data->ds = dock_station; 780 dd->ds = dock_station;
800 acpi_os_hotplug_execute(acpi_dock_deferred_cb, 781 acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd);
801 dock_data);
802 return 0 ; 782 return 0 ;
803 } 783 }
804 } 784 }
@@ -826,7 +806,6 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
826 acpi_status status; 806 acpi_status status;
827 acpi_handle tmp, parent; 807 acpi_handle tmp, parent;
828 struct dock_station *ds = context; 808 struct dock_station *ds = context;
829 struct dock_dependent_device *dd;
830 809
831 status = acpi_bus_get_ejd(handle, &tmp); 810 status = acpi_bus_get_ejd(handle, &tmp);
832 if (ACPI_FAILURE(status)) { 811 if (ACPI_FAILURE(status)) {
@@ -840,11 +819,9 @@ find_dock_devices(acpi_handle handle, u32 lvl, void *context, void **rv)
840 goto fdd_out; 819 goto fdd_out;
841 } 820 }
842 821
843 if (tmp == ds->handle) { 822 if (tmp == ds->handle)
844 dd = alloc_dock_dependent_device(handle); 823 add_dock_dependent_device(ds, handle);
845 if (dd) 824
846 add_dock_dependent_device(ds, dd);
847 }
848fdd_out: 825fdd_out:
849 return AE_OK; 826 return AE_OK;
850} 827}
@@ -857,8 +834,7 @@ static ssize_t show_docked(struct device *dev,
857{ 834{
858 struct acpi_device *tmp; 835 struct acpi_device *tmp;
859 836
860 struct dock_station *dock_station = *((struct dock_station **) 837 struct dock_station *dock_station = dev->platform_data;
861 dev->platform_data);
862 838
863 if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) 839 if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp)))
864 return snprintf(buf, PAGE_SIZE, "1\n"); 840 return snprintf(buf, PAGE_SIZE, "1\n");
@@ -872,8 +848,7 @@ static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
872static ssize_t show_flags(struct device *dev, 848static ssize_t show_flags(struct device *dev,
873 struct device_attribute *attr, char *buf) 849 struct device_attribute *attr, char *buf)
874{ 850{
875 struct dock_station *dock_station = *((struct dock_station **) 851 struct dock_station *dock_station = dev->platform_data;
876 dev->platform_data);
877 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); 852 return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags);
878 853
879} 854}
@@ -886,8 +861,7 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr,
886 const char *buf, size_t count) 861 const char *buf, size_t count)
887{ 862{
888 int ret; 863 int ret;
889 struct dock_station *dock_station = *((struct dock_station **) 864 struct dock_station *dock_station = dev->platform_data;
890 dev->platform_data);
891 865
892 if (!count) 866 if (!count)
893 return -EINVAL; 867 return -EINVAL;
@@ -905,8 +879,7 @@ static ssize_t show_dock_uid(struct device *dev,
905 struct device_attribute *attr, char *buf) 879 struct device_attribute *attr, char *buf)
906{ 880{
907 unsigned long long lbuf; 881 unsigned long long lbuf;
908 struct dock_station *dock_station = *((struct dock_station **) 882 struct dock_station *dock_station = dev->platform_data;
909 dev->platform_data);
910 acpi_status status = acpi_evaluate_integer(dock_station->handle, 883 acpi_status status = acpi_evaluate_integer(dock_station->handle,
911 "_UID", NULL, &lbuf); 884 "_UID", NULL, &lbuf);
912 if (ACPI_FAILURE(status)) 885 if (ACPI_FAILURE(status))
@@ -919,8 +892,7 @@ static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL);
919static ssize_t show_dock_type(struct device *dev, 892static ssize_t show_dock_type(struct device *dev,
920 struct device_attribute *attr, char *buf) 893 struct device_attribute *attr, char *buf)
921{ 894{
922 struct dock_station *dock_station = *((struct dock_station **) 895 struct dock_station *dock_station = dev->platform_data;
923 dev->platform_data);
924 char *type; 896 char *type;
925 897
926 if (dock_station->flags & DOCK_IS_DOCK) 898 if (dock_station->flags & DOCK_IS_DOCK)
@@ -936,6 +908,19 @@ static ssize_t show_dock_type(struct device *dev,
936} 908}
937static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); 909static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
938 910
911static struct attribute *dock_attributes[] = {
912 &dev_attr_docked.attr,
913 &dev_attr_flags.attr,
914 &dev_attr_undock.attr,
915 &dev_attr_uid.attr,
916 &dev_attr_type.attr,
917 NULL
918};
919
920static struct attribute_group dock_attribute_group = {
921 .attrs = dock_attributes
922};
923
939/** 924/**
940 * dock_add - add a new dock station 925 * dock_add - add a new dock station
941 * @handle: the dock station handle 926 * @handle: the dock station handle
@@ -945,39 +930,30 @@ static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL);
945 */ 930 */
946static int dock_add(acpi_handle handle) 931static int dock_add(acpi_handle handle)
947{ 932{
948 int ret; 933 int ret, id;
949 struct dock_dependent_device *dd; 934 struct dock_station ds, *dock_station;
950 struct dock_station *dock_station; 935 struct platform_device *dd;
951 struct platform_device *dock_device; 936
937 id = dock_station_count;
938 dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
939 if (IS_ERR(dd))
940 return PTR_ERR(dd);
941
942 dock_station = dd->dev.platform_data;
952 943
953 /* allocate & initialize the dock_station private data */
954 dock_station = kzalloc(sizeof(*dock_station), GFP_KERNEL);
955 if (!dock_station)
956 return -ENOMEM;
957 dock_station->handle = handle; 944 dock_station->handle = handle;
945 dock_station->dock_device = dd;
958 dock_station->last_dock_time = jiffies - HZ; 946 dock_station->last_dock_time = jiffies - HZ;
959 INIT_LIST_HEAD(&dock_station->dependent_devices); 947
960 INIT_LIST_HEAD(&dock_station->hotplug_devices);
961 INIT_LIST_HEAD(&dock_station->sibling);
962 spin_lock_init(&dock_station->dd_lock);
963 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);
964 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 952 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
965 953 INIT_LIST_HEAD(&dock_station->dependent_devices);
966 /* initialize platform device stuff */
967 dock_station->dock_device =
968 platform_device_register_simple(dock_device_name,
969 dock_station_count, NULL, 0);
970 dock_device = dock_station->dock_device;
971 if (IS_ERR(dock_device)) {
972 kfree(dock_station);
973 dock_station = NULL;
974 return PTR_ERR(dock_device);
975 }
976 platform_device_add_data(dock_device, &dock_station,
977 sizeof(struct dock_station *));
978 954
979 /* we want the dock device to send uevents */ 955 /* we want the dock device to send uevents */
980 dev_set_uevent_suppress(&dock_device->dev, 0); 956 dev_set_uevent_suppress(&dd->dev, 0);
981 957
982 if (is_dock(handle)) 958 if (is_dock(handle))
983 dock_station->flags |= DOCK_IS_DOCK; 959 dock_station->flags |= DOCK_IS_DOCK;
@@ -986,47 +962,9 @@ static int dock_add(acpi_handle handle)
986 if (is_battery(handle)) 962 if (is_battery(handle))
987 dock_station->flags |= DOCK_IS_BAT; 963 dock_station->flags |= DOCK_IS_BAT;
988 964
989 ret = device_create_file(&dock_device->dev, &dev_attr_docked); 965 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
990 if (ret) {
991 printk(KERN_ERR "Error %d adding sysfs file\n", ret);
992 platform_device_unregister(dock_device);
993 kfree(dock_station);
994 dock_station = NULL;
995 return ret;
996 }
997 ret = device_create_file(&dock_device->dev, &dev_attr_undock);
998 if (ret) {
999 printk(KERN_ERR "Error %d adding sysfs file\n", ret);
1000 device_remove_file(&dock_device->dev, &dev_attr_docked);
1001 platform_device_unregister(dock_device);
1002 kfree(dock_station);
1003 dock_station = NULL;
1004 return ret;
1005 }
1006 ret = device_create_file(&dock_device->dev, &dev_attr_uid);
1007 if (ret) {
1008 printk(KERN_ERR "Error %d adding sysfs file\n", ret);
1009 device_remove_file(&dock_device->dev, &dev_attr_docked);
1010 device_remove_file(&dock_device->dev, &dev_attr_undock);
1011 platform_device_unregister(dock_device);
1012 kfree(dock_station);
1013 dock_station = NULL;
1014 return ret;
1015 }
1016 ret = device_create_file(&dock_device->dev, &dev_attr_flags);
1017 if (ret) {
1018 printk(KERN_ERR "Error %d adding sysfs file\n", ret);
1019 device_remove_file(&dock_device->dev, &dev_attr_docked);
1020 device_remove_file(&dock_device->dev, &dev_attr_undock);
1021 device_remove_file(&dock_device->dev, &dev_attr_uid);
1022 platform_device_unregister(dock_device);
1023 kfree(dock_station);
1024 dock_station = NULL;
1025 return ret;
1026 }
1027 ret = device_create_file(&dock_device->dev, &dev_attr_type);
1028 if (ret) 966 if (ret)
1029 printk(KERN_ERR"Error %d adding sysfs file\n", ret); 967 goto err_unregister;
1030 968
1031 /* Find dependent devices */ 969 /* Find dependent devices */
1032 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 970 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
@@ -1034,58 +972,43 @@ static int dock_add(acpi_handle handle)
1034 dock_station, NULL); 972 dock_station, NULL);
1035 973
1036 /* add the dock station as a device dependent on itself */ 974 /* add the dock station as a device dependent on itself */
1037 dd = alloc_dock_dependent_device(handle); 975 ret = add_dock_dependent_device(dock_station, handle);
1038 if (!dd) { 976 if (ret)
1039 kfree(dock_station); 977 goto err_rmgroup;
1040 dock_station = NULL;
1041 ret = -ENOMEM;
1042 goto dock_add_err_unregister;
1043 }
1044 add_dock_dependent_device(dock_station, dd);
1045 978
1046 dock_station_count++; 979 dock_station_count++;
1047 list_add(&dock_station->sibling, &dock_stations); 980 list_add(&dock_station->sibling, &dock_stations);
1048 return 0; 981 return 0;
1049 982
1050dock_add_err_unregister: 983err_rmgroup:
1051 device_remove_file(&dock_device->dev, &dev_attr_type); 984 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
1052 device_remove_file(&dock_device->dev, &dev_attr_docked); 985err_unregister:
1053 device_remove_file(&dock_device->dev, &dev_attr_undock); 986 platform_device_unregister(dd);
1054 device_remove_file(&dock_device->dev, &dev_attr_uid); 987 printk(KERN_ERR "%s encountered error %d\n", __func__, ret);
1055 device_remove_file(&dock_device->dev, &dev_attr_flags);
1056 platform_device_unregister(dock_device);
1057 kfree(dock_station);
1058 dock_station = NULL;
1059 return ret; 988 return ret;
1060} 989}
1061 990
1062/** 991/**
1063 * dock_remove - free up resources related to the dock station 992 * dock_remove - free up resources related to the dock station
1064 */ 993 */
1065static int dock_remove(struct dock_station *dock_station) 994static int dock_remove(struct dock_station *ds)
1066{ 995{
1067 struct dock_dependent_device *dd, *tmp; 996 struct dock_dependent_device *dd, *tmp;
1068 struct platform_device *dock_device = dock_station->dock_device; 997 struct platform_device *dock_device = ds->dock_device;
1069 998
1070 if (!dock_station_count) 999 if (!dock_station_count)
1071 return 0; 1000 return 0;
1072 1001
1073 /* remove dependent devices */ 1002 /* remove dependent devices */
1074 list_for_each_entry_safe(dd, tmp, &dock_station->dependent_devices, 1003 list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list)
1075 list) 1004 kfree(dd);
1076 kfree(dd); 1005
1006 list_del(&ds->sibling);
1077 1007
1078 /* cleanup sysfs */ 1008 /* cleanup sysfs */
1079 device_remove_file(&dock_device->dev, &dev_attr_type); 1009 sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group);
1080 device_remove_file(&dock_device->dev, &dev_attr_docked);
1081 device_remove_file(&dock_device->dev, &dev_attr_undock);
1082 device_remove_file(&dock_device->dev, &dev_attr_uid);
1083 device_remove_file(&dock_device->dev, &dev_attr_flags);
1084 platform_device_unregister(dock_device); 1010 platform_device_unregister(dock_device);
1085 1011
1086 /* free dock station memory */
1087 kfree(dock_station);
1088 dock_station = NULL;
1089 return 0; 1012 return 0;
1090} 1013}
1091 1014
@@ -1103,11 +1026,10 @@ find_dock(acpi_handle handle, u32 lvl, void *context, void **rv)
1103{ 1026{
1104 acpi_status status = AE_OK; 1027 acpi_status status = AE_OK;
1105 1028
1106 if (is_dock(handle)) { 1029 if (is_dock(handle))
1107 if (dock_add(handle) >= 0) { 1030 if (dock_add(handle) >= 0)
1108 status = AE_CTRL_TERMINATE; 1031 status = AE_CTRL_TERMINATE;
1109 } 1032
1110 }
1111 return status; 1033 return status;
1112} 1034}
1113 1035
@@ -1145,8 +1067,7 @@ static int __init dock_init(void)
1145 1067
1146static void __exit dock_exit(void) 1068static void __exit dock_exit(void)
1147{ 1069{
1148 struct dock_station *dock_station; 1070 struct dock_station *tmp, *dock_station;
1149 struct dock_station *tmp;
1150 1071
1151 unregister_acpi_bus_notifier(&dock_acpi_notifier); 1072 unregister_acpi_bus_notifier(&dock_acpi_notifier);
1152 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling) 1073 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)