aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dock.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dock.c')
-rw-r--r--drivers/acpi/dock.c463
1 files changed, 113 insertions, 350 deletions
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index c431c88faaff..f0fc6260266b 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -1,7 +1,9 @@
1/* 1/*
2 * dock.c - ACPI dock station driver 2 * dock.c - ACPI dock station driver
3 * 3 *
4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> 4 * Copyright (C) 2006, 2014, Intel Corp.
5 * Author: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
6 * Rafael J. Wysocki <rafael.j.wysocki@intel.com>
5 * 7 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 * 9 *
@@ -35,8 +37,6 @@
35 37
36#include "internal.h" 38#include "internal.h"
37 39
38#define PREFIX "ACPI: "
39
40#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver" 40#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver"
41 41
42ACPI_MODULE_NAME("dock"); 42ACPI_MODULE_NAME("dock");
@@ -68,15 +68,10 @@ struct dock_station {
68}; 68};
69static LIST_HEAD(dock_stations); 69static LIST_HEAD(dock_stations);
70static int dock_station_count; 70static int dock_station_count;
71static DEFINE_MUTEX(hotplug_lock);
72 71
73struct dock_dependent_device { 72struct dock_dependent_device {
74 struct list_head list; 73 struct list_head list;
75 acpi_handle handle; 74 struct acpi_device *adev;
76 const struct acpi_dock_ops *hp_ops;
77 void *hp_context;
78 unsigned int hp_refcount;
79 void (*hp_release)(void *);
80}; 75};
81 76
82#define DOCK_DOCKING 0x00000001 77#define DOCK_DOCKING 0x00000001
@@ -98,13 +93,13 @@ enum dock_callback_type {
98 *****************************************************************************/ 93 *****************************************************************************/
99/** 94/**
100 * add_dock_dependent_device - associate a device with the dock station 95 * add_dock_dependent_device - associate a device with the dock station
101 * @ds: The dock station 96 * @ds: Dock station.
102 * @handle: handle of the dependent device 97 * @adev: Dependent ACPI device object.
103 * 98 *
104 * Add the dependent device to the dock's dependent device list. 99 * Add the dependent device to the dock's dependent device list.
105 */ 100 */
106static int __init 101static int add_dock_dependent_device(struct dock_station *ds,
107add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 102 struct acpi_device *adev)
108{ 103{
109 struct dock_dependent_device *dd; 104 struct dock_dependent_device *dd;
110 105
@@ -112,180 +107,120 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
112 if (!dd) 107 if (!dd)
113 return -ENOMEM; 108 return -ENOMEM;
114 109
115 dd->handle = handle; 110 dd->adev = adev;
116 INIT_LIST_HEAD(&dd->list); 111 INIT_LIST_HEAD(&dd->list);
117 list_add_tail(&dd->list, &ds->dependent_devices); 112 list_add_tail(&dd->list, &ds->dependent_devices);
118 113
119 return 0; 114 return 0;
120} 115}
121 116
122static void remove_dock_dependent_devices(struct dock_station *ds) 117static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
118 enum dock_callback_type cb_type)
123{ 119{
124 struct dock_dependent_device *dd, *aux; 120 struct acpi_device *adev = dd->adev;
125 121
126 list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { 122 acpi_lock_hp_context();
127 list_del(&dd->list);
128 kfree(dd);
129 }
130}
131 123
132/** 124 if (!adev->hp)
133 * dock_init_hotplug - Initialize a hotplug device on a docking station. 125 goto out;
134 * @dd: Dock-dependent device.
135 * @ops: Dock operations to attach to the dependent device.
136 * @context: Data to pass to the @ops callbacks and @release.
137 * @init: Optional initialization routine to run after setting up context.
138 * @release: Optional release routine to run on removal.
139 */
140static int dock_init_hotplug(struct dock_dependent_device *dd,
141 const struct acpi_dock_ops *ops, void *context,
142 void (*init)(void *), void (*release)(void *))
143{
144 int ret = 0;
145 126
146 mutex_lock(&hotplug_lock); 127 if (cb_type == DOCK_CALL_FIXUP) {
147 if (WARN_ON(dd->hp_context)) { 128 void (*fixup)(struct acpi_device *);
148 ret = -EEXIST;
149 } else {
150 dd->hp_refcount = 1;
151 dd->hp_ops = ops;
152 dd->hp_context = context;
153 dd->hp_release = release;
154 if (init)
155 init(context);
156 }
157 mutex_unlock(&hotplug_lock);
158 return ret;
159}
160 129
161/** 130 fixup = adev->hp->fixup;
162 * dock_release_hotplug - Decrement hotplug reference counter of dock device. 131 if (fixup) {
163 * @dd: Dock-dependent device. 132 acpi_unlock_hp_context();
164 * 133 fixup(adev);
165 * Decrement the reference counter of @dd and if 0, detach its hotplug 134 return;
166 * operations from it, reset its context pointer and run the optional release 135 }
167 * routine if present. 136 } else if (cb_type == DOCK_CALL_UEVENT) {
168 */ 137 void (*uevent)(struct acpi_device *, u32);
169static void dock_release_hotplug(struct dock_dependent_device *dd) 138
170{ 139 uevent = adev->hp->uevent;
171 mutex_lock(&hotplug_lock); 140 if (uevent) {
172 if (dd->hp_context && !--dd->hp_refcount) { 141 acpi_unlock_hp_context();
173 void (*release)(void *) = dd->hp_release; 142 uevent(adev, event);
174 void *context = dd->hp_context; 143 return;
175 144 }
176 dd->hp_ops = NULL; 145 } else {
177 dd->hp_context = NULL; 146 int (*notify)(struct acpi_device *, u32);
178 dd->hp_release = NULL;
179 if (release)
180 release(context);
181 }
182 mutex_unlock(&hotplug_lock);
183}
184 147
185static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, 148 notify = adev->hp->notify;
186 enum dock_callback_type cb_type) 149 if (notify) {
187{ 150 acpi_unlock_hp_context();
188 acpi_notify_handler cb = NULL; 151 notify(adev, event);
189 bool run = false; 152 return;
190
191 mutex_lock(&hotplug_lock);
192
193 if (dd->hp_context) {
194 run = true;
195 dd->hp_refcount++;
196 if (dd->hp_ops) {
197 switch (cb_type) {
198 case DOCK_CALL_FIXUP:
199 cb = dd->hp_ops->fixup;
200 break;
201 case DOCK_CALL_UEVENT:
202 cb = dd->hp_ops->uevent;
203 break;
204 default:
205 cb = dd->hp_ops->handler;
206 }
207 } 153 }
208 } 154 }
209 155
210 mutex_unlock(&hotplug_lock); 156 out:
157 acpi_unlock_hp_context();
158}
211 159
212 if (!run) 160static struct dock_station *find_dock_station(acpi_handle handle)
213 return; 161{
162 struct dock_station *ds;
214 163
215 if (cb) 164 list_for_each_entry(ds, &dock_stations, sibling)
216 cb(dd->handle, event, dd->hp_context); 165 if (ds->handle == handle)
166 return ds;
217 167
218 dock_release_hotplug(dd); 168 return NULL;
219} 169}
220 170
221/** 171/**
222 * find_dock_dependent_device - get a device dependent on this dock 172 * find_dock_dependent_device - get a device dependent on this dock
223 * @ds: the dock station 173 * @ds: the dock station
224 * @handle: the acpi_handle of the device we want 174 * @adev: ACPI device object to find.
225 * 175 *
226 * iterate over the dependent device list for this dock. If the 176 * iterate over the dependent device list for this dock. If the
227 * dependent device matches the handle, return. 177 * dependent device matches the handle, return.
228 */ 178 */
229static struct dock_dependent_device * 179static struct dock_dependent_device *
230find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 180find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev)
231{ 181{
232 struct dock_dependent_device *dd; 182 struct dock_dependent_device *dd;
233 183
234 list_for_each_entry(dd, &ds->dependent_devices, list) 184 list_for_each_entry(dd, &ds->dependent_devices, list)
235 if (handle == dd->handle) 185 if (adev == dd->adev)
236 return dd; 186 return dd;
237 187
238 return NULL; 188 return NULL;
239} 189}
240 190
241/***************************************************************************** 191void register_dock_dependent_device(struct acpi_device *adev,
242 * Dock functions * 192 acpi_handle dshandle)
243 *****************************************************************************/
244static int __init is_battery(acpi_handle handle)
245{ 193{
246 struct acpi_device_info *info; 194 struct dock_station *ds = find_dock_station(dshandle);
247 int ret = 1;
248 195
249 if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) 196 if (ds && !find_dock_dependent_device(ds, adev))
250 return 0; 197 add_dock_dependent_device(ds, adev);
251 if (!(info->valid & ACPI_VALID_HID))
252 ret = 0;
253 else
254 ret = !strcmp("PNP0C0A", info->hardware_id.string);
255
256 kfree(info);
257 return ret;
258} 198}
259 199
260/* Check whether ACPI object is an ejectable battery or disk bay */ 200/*****************************************************************************
261static bool __init is_ejectable_bay(acpi_handle handle) 201 * Dock functions *
262{ 202 *****************************************************************************/
263 if (acpi_has_method(handle, "_EJ0") && is_battery(handle))
264 return true;
265
266 return acpi_bay_match(handle);
267}
268 203
269/** 204/**
270 * is_dock_device - see if a device is on a dock station 205 * is_dock_device - see if a device is on a dock station
271 * @handle: acpi handle of the device 206 * @adev: ACPI device object to check.
272 * 207 *
273 * If this device is either the dock station itself, 208 * If this device is either the dock station itself,
274 * or is a device dependent on the dock station, then it 209 * or is a device dependent on the dock station, then it
275 * is a dock device 210 * is a dock device
276 */ 211 */
277int is_dock_device(acpi_handle handle) 212int is_dock_device(struct acpi_device *adev)
278{ 213{
279 struct dock_station *dock_station; 214 struct dock_station *dock_station;
280 215
281 if (!dock_station_count) 216 if (!dock_station_count)
282 return 0; 217 return 0;
283 218
284 if (acpi_dock_match(handle)) 219 if (acpi_dock_match(adev->handle))
285 return 1; 220 return 1;
286 221
287 list_for_each_entry(dock_station, &dock_stations, sibling) 222 list_for_each_entry(dock_station, &dock_stations, sibling)
288 if (find_dock_dependent_device(dock_station, handle)) 223 if (find_dock_dependent_device(dock_station, adev))
289 return 1; 224 return 1;
290 225
291 return 0; 226 return 0;
@@ -313,43 +248,6 @@ static int dock_present(struct dock_station *ds)
313} 248}
314 249
315/** 250/**
316 * dock_create_acpi_device - add new devices to acpi
317 * @handle - handle of the device to add
318 *
319 * This function will create a new acpi_device for the given
320 * handle if one does not exist already. This should cause
321 * acpi to scan for drivers for the given devices, and call
322 * matching driver's add routine.
323 */
324static void dock_create_acpi_device(acpi_handle handle)
325{
326 struct acpi_device *device = NULL;
327 int ret;
328
329 acpi_bus_get_device(handle, &device);
330 if (!acpi_device_enumerated(device)) {
331 ret = acpi_bus_scan(handle);
332 if (ret)
333 pr_debug("error adding bus, %x\n", -ret);
334 }
335}
336
337/**
338 * dock_remove_acpi_device - remove the acpi_device struct from acpi
339 * @handle - the handle of the device to remove
340 *
341 * Tell acpi to remove the acpi_device. This should cause any loaded
342 * driver to have it's remove routine called.
343 */
344static void dock_remove_acpi_device(acpi_handle handle)
345{
346 struct acpi_device *device;
347
348 if (!acpi_bus_get_device(handle, &device))
349 acpi_bus_trim(device);
350}
351
352/**
353 * hot_remove_dock_devices - Remove dock station devices. 251 * hot_remove_dock_devices - Remove dock station devices.
354 * @ds: Dock station. 252 * @ds: Dock station.
355 */ 253 */
@@ -366,7 +264,7 @@ static void hot_remove_dock_devices(struct dock_station *ds)
366 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); 264 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);
367 265
368 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) 266 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
369 dock_remove_acpi_device(dd->handle); 267 acpi_bus_trim(dd->adev);
370} 268}
371 269
372/** 270/**
@@ -392,12 +290,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
392 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); 290 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);
393 291
394 /* 292 /*
395 * Now make sure that an acpi_device is created for each dependent 293 * Check if all devices have been enumerated already. If not, run
396 * device. That will cause scan handlers to be attached to device 294 * acpi_bus_scan() for them and that will cause scan handlers to be
397 * objects or acpi_drivers to be stopped/started if they are present. 295 * attached to device objects or acpi_drivers to be stopped/started if
296 * they are present.
398 */ 297 */
399 list_for_each_entry(dd, &ds->dependent_devices, list) 298 list_for_each_entry(dd, &ds->dependent_devices, list) {
400 dock_create_acpi_device(dd->handle); 299 struct acpi_device *adev = dd->adev;
300
301 if (!acpi_device_enumerated(adev)) {
302 int ret = acpi_bus_scan(adev->handle);
303 if (ret)
304 dev_dbg(&adev->dev, "scan error %d\n", -ret);
305 }
306 }
401} 307}
402 308
403static void dock_event(struct dock_station *ds, u32 event, int num) 309static void dock_event(struct dock_station *ds, u32 event, int num)
@@ -501,71 +407,6 @@ static int dock_in_progress(struct dock_station *ds)
501} 407}
502 408
503/** 409/**
504 * register_hotplug_dock_device - register a hotplug function
505 * @handle: the handle of the device
506 * @ops: handlers to call after docking
507 * @context: device specific data
508 * @init: Optional initialization routine to run after registration
509 * @release: Optional release routine to run on unregistration
510 *
511 * If a driver would like to perform a hotplug operation after a dock
512 * event, they can register an acpi_notifiy_handler to be called by
513 * the dock driver after _DCK is executed.
514 */
515int register_hotplug_dock_device(acpi_handle handle,
516 const struct acpi_dock_ops *ops, void *context,
517 void (*init)(void *), void (*release)(void *))
518{
519 struct dock_dependent_device *dd;
520 struct dock_station *dock_station;
521 int ret = -EINVAL;
522
523 if (WARN_ON(!context))
524 return -EINVAL;
525
526 if (!dock_station_count)
527 return -ENODEV;
528
529 /*
530 * make sure this handle is for a device dependent on the dock,
531 * this would include the dock station itself
532 */
533 list_for_each_entry(dock_station, &dock_stations, sibling) {
534 /*
535 * An ATA bay can be in a dock and itself can be ejected
536 * separately, so there are two 'dock stations' which need the
537 * ops
538 */
539 dd = find_dock_dependent_device(dock_station, handle);
540 if (dd && !dock_init_hotplug(dd, ops, context, init, release))
541 ret = 0;
542 }
543
544 return ret;
545}
546EXPORT_SYMBOL_GPL(register_hotplug_dock_device);
547
548/**
549 * unregister_hotplug_dock_device - remove yourself from the hotplug list
550 * @handle: the acpi handle of the device
551 */
552void unregister_hotplug_dock_device(acpi_handle handle)
553{
554 struct dock_dependent_device *dd;
555 struct dock_station *dock_station;
556
557 if (!dock_station_count)
558 return;
559
560 list_for_each_entry(dock_station, &dock_stations, sibling) {
561 dd = find_dock_dependent_device(dock_station, handle);
562 if (dd)
563 dock_release_hotplug(dd);
564 }
565}
566EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
567
568/**
569 * handle_eject_request - handle an undock request checking for error conditions 410 * handle_eject_request - handle an undock request checking for error conditions
570 * 411 *
571 * Check to make sure the dock device is still present, then undock and 412 * Check to make sure the dock device is still present, then undock and
@@ -598,20 +439,23 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
598} 439}
599 440
600/** 441/**
601 * dock_notify - act upon an acpi dock notification 442 * dock_notify - Handle ACPI dock notification.
602 * @ds: dock station 443 * @adev: Dock station's ACPI device object.
603 * @event: the acpi event 444 * @event: Event code.
604 * 445 *
605 * If we are notified to dock, then check to see if the dock is 446 * If we are notified to dock, then check to see if the dock is
606 * present and then dock. Notify all drivers of the dock event, 447 * present and then dock. Notify all drivers of the dock event,
607 * and then hotplug and devices that may need hotplugging. 448 * and then hotplug and devices that may need hotplugging.
608 */ 449 */
609static void dock_notify(struct dock_station *ds, u32 event) 450int dock_notify(struct acpi_device *adev, u32 event)
610{ 451{
611 acpi_handle handle = ds->handle; 452 acpi_handle handle = adev->handle;
612 struct acpi_device *ad; 453 struct dock_station *ds = find_dock_station(handle);
613 int surprise_removal = 0; 454 int surprise_removal = 0;
614 455
456 if (!ds)
457 return -ENODEV;
458
615 /* 459 /*
616 * According to acpi spec 3.0a, if a DEVICE_CHECK notification 460 * According to acpi spec 3.0a, if a DEVICE_CHECK notification
617 * is sent and _DCK is present, it is assumed to mean an undock 461 * is sent and _DCK is present, it is assumed to mean an undock
@@ -632,7 +476,7 @@ static void dock_notify(struct dock_station *ds, u32 event)
632 switch (event) { 476 switch (event) {
633 case ACPI_NOTIFY_BUS_CHECK: 477 case ACPI_NOTIFY_BUS_CHECK:
634 case ACPI_NOTIFY_DEVICE_CHECK: 478 case ACPI_NOTIFY_DEVICE_CHECK:
635 if (!dock_in_progress(ds) && acpi_bus_get_device(handle, &ad)) { 479 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) {
636 begin_dock(ds); 480 begin_dock(ds);
637 dock(ds); 481 dock(ds);
638 if (!dock_present(ds)) { 482 if (!dock_present(ds)) {
@@ -661,49 +505,8 @@ static void dock_notify(struct dock_station *ds, u32 event)
661 else 505 else
662 dock_event(ds, event, UNDOCK_EVENT); 506 dock_event(ds, event, UNDOCK_EVENT);
663 break; 507 break;
664 default:
665 acpi_handle_err(handle, "Unknown dock event %d\n", event);
666 } 508 }
667} 509 return 0;
668
669static void acpi_dock_deferred_cb(void *data, u32 event)
670{
671 acpi_scan_lock_acquire();
672 dock_notify(data, event);
673 acpi_scan_lock_release();
674}
675
676static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
677{
678 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
679 && event != ACPI_NOTIFY_EJECT_REQUEST)
680 return;
681
682 acpi_hotplug_execute(acpi_dock_deferred_cb, data, event);
683}
684
685/**
686 * find_dock_devices - find devices on the dock station
687 * @handle: the handle of the device we are examining
688 * @lvl: unused
689 * @context: the dock station private data
690 * @rv: unused
691 *
692 * This function is called by acpi_walk_namespace. It will
693 * check to see if an object has an _EJD method. If it does, then it
694 * will see if it is dependent on the dock station.
695 */
696static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
697 void *context, void **rv)
698{
699 struct dock_station *ds = context;
700 acpi_handle ejd = NULL;
701
702 acpi_bus_get_ejd(handle, &ejd);
703 if (ejd == ds->handle)
704 add_dock_dependent_device(ds, handle);
705
706 return AE_OK;
707} 510}
708 511
709/* 512/*
@@ -712,13 +515,11 @@ static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
712static ssize_t show_docked(struct device *dev, 515static ssize_t show_docked(struct device *dev,
713 struct device_attribute *attr, char *buf) 516 struct device_attribute *attr, char *buf)
714{ 517{
715 struct acpi_device *tmp;
716
717 struct dock_station *dock_station = dev->platform_data; 518 struct dock_station *dock_station = dev->platform_data;
519 struct acpi_device *adev = NULL;
718 520
719 if (!acpi_bus_get_device(dock_station->handle, &tmp)) 521 acpi_bus_get_device(dock_station->handle, &adev);
720 return snprintf(buf, PAGE_SIZE, "1\n"); 522 return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev));
721 return snprintf(buf, PAGE_SIZE, "0\n");
722} 523}
723static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 524static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL);
724 525
@@ -804,23 +605,28 @@ static struct attribute_group dock_attribute_group = {
804}; 605};
805 606
806/** 607/**
807 * dock_add - add a new dock station 608 * acpi_dock_add - Add a new dock station
808 * @handle: the dock station handle 609 * @adev: Dock station ACPI device object.
809 * 610 *
810 * allocated and initialize a new dock station device. Find all devices 611 * allocated and initialize a new dock station device.
811 * that are on the dock station, and register for dock event notifications.
812 */ 612 */
813static int __init dock_add(acpi_handle handle) 613void acpi_dock_add(struct acpi_device *adev)
814{ 614{
815 struct dock_station *dock_station, ds = { NULL, }; 615 struct dock_station *dock_station, ds = { NULL, };
616 struct platform_device_info pdevinfo;
617 acpi_handle handle = adev->handle;
816 struct platform_device *dd; 618 struct platform_device *dd;
817 acpi_status status;
818 int ret; 619 int ret;
819 620
820 dd = platform_device_register_data(NULL, "dock", dock_station_count, 621 memset(&pdevinfo, 0, sizeof(pdevinfo));
821 &ds, sizeof(ds)); 622 pdevinfo.name = "dock";
623 pdevinfo.id = dock_station_count;
624 pdevinfo.acpi_node.companion = adev;
625 pdevinfo.data = &ds;
626 pdevinfo.size_data = sizeof(ds);
627 dd = platform_device_register_full(&pdevinfo);
822 if (IS_ERR(dd)) 628 if (IS_ERR(dd))
823 return PTR_ERR(dd); 629 return;
824 630
825 dock_station = dd->dev.platform_data; 631 dock_station = dd->dev.platform_data;
826 632
@@ -838,72 +644,29 @@ static int __init dock_add(acpi_handle handle)
838 dock_station->flags |= DOCK_IS_DOCK; 644 dock_station->flags |= DOCK_IS_DOCK;
839 if (acpi_ata_match(handle)) 645 if (acpi_ata_match(handle))
840 dock_station->flags |= DOCK_IS_ATA; 646 dock_station->flags |= DOCK_IS_ATA;
841 if (is_battery(handle)) 647 if (acpi_device_is_battery(adev))
842 dock_station->flags |= DOCK_IS_BAT; 648 dock_station->flags |= DOCK_IS_BAT;
843 649
844 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); 650 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
845 if (ret) 651 if (ret)
846 goto err_unregister; 652 goto err_unregister;
847 653
848 /* Find dependent devices */
849 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
850 ACPI_UINT32_MAX, find_dock_devices, NULL,
851 dock_station, NULL);
852
853 /* add the dock station as a device dependent on itself */ 654 /* add the dock station as a device dependent on itself */
854 ret = add_dock_dependent_device(dock_station, handle); 655 ret = add_dock_dependent_device(dock_station, adev);
855 if (ret) 656 if (ret)
856 goto err_rmgroup; 657 goto err_rmgroup;
857 658
858 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
859 dock_notify_handler, dock_station);
860 if (ACPI_FAILURE(status)) {
861 ret = -ENODEV;
862 goto err_rmgroup;
863 }
864
865 dock_station_count++; 659 dock_station_count++;
866 list_add(&dock_station->sibling, &dock_stations); 660 list_add(&dock_station->sibling, &dock_stations);
867 return 0; 661 adev->flags.is_dock_station = true;
662 dev_info(&adev->dev, "ACPI dock station (docks/bays count: %d)\n",
663 dock_station_count);
664 return;
868 665
869err_rmgroup: 666err_rmgroup:
870 remove_dock_dependent_devices(dock_station);
871 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); 667 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
668
872err_unregister: 669err_unregister:
873 platform_device_unregister(dd); 670 platform_device_unregister(dd);
874 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); 671 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret);
875 return ret;
876}
877
878/**
879 * find_dock_and_bay - look for dock stations and bays
880 * @handle: acpi handle of a device
881 * @lvl: unused
882 * @context: unused
883 * @rv: unused
884 *
885 * This is called by acpi_walk_namespace to look for dock stations and bays.
886 */
887static acpi_status __init
888find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
889{
890 if (acpi_dock_match(handle) || is_ejectable_bay(handle))
891 dock_add(handle);
892
893 return AE_OK;
894}
895
896void __init acpi_dock_init(void)
897{
898 /* look for dock stations and bays */
899 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
900 ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL);
901
902 if (!dock_station_count) {
903 pr_info(PREFIX "No dock devices found.\n");
904 return;
905 }
906
907 pr_info(PREFIX "%s: %d docks/bays found\n",
908 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
909} 672}