summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-17 08:47:14 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-17 08:47:14 -0400
commit6621c5a69a1dac50852ef09d5cf33154a174805a (patch)
tree88f4ff7d73006abcef64f9793daadda9d5034a32 /drivers
parentd983f93328041f85e884a586810a67528ae59945 (diff)
parentd901188f002104905a7845298e1a7dc94189007a (diff)
Merge branch 'acpi-hotplug'
* acpi-hotplug: ACPI / hotplug: Rework deferred execution of acpi_device_hotplug() ACPI / dock: Update copyright notice ACPI / dock: Drop remove_dock_dependent_devices() ACPI / dock: Drop struct acpi_dock_ops and all code related to it ACPI / ATA: Add hotplug contexts to ACPI companions of SATA devices ACPI / dock: Add .uevent() callback to struct acpi_hotplug_context ACPI / dock: Use callback pointers from devices' ACPI hotplug contexts ACPI / dock: Use ACPI device object pointers instead of ACPI handles ACPI / hotplug: Add .fixup() callback to struct acpi_hotplug_context ACPI / hotplug / PCI: Do not clear event callback pointer for docks ACPI / dock: Associate dock platform devices with ACPI device objects ACPI / dock: Pass ACPI device pointer to acpi_device_is_battery() ACPI / dock: Dispatch dock notifications from the global notify handler
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/container.c3
-rw-r--r--drivers/acpi/dock.c452
-rw-r--r--drivers/acpi/internal.h14
-rw-r--r--drivers/acpi/osl.c14
-rw-r--r--drivers/acpi/scan.c59
-rw-r--r--drivers/ata/libata-acpi.c72
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c134
8 files changed, 277 insertions, 473 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e61e7b8a2eaf..afe6f9a919c1 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -400,7 +400,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
400 case ACPI_NOTIFY_BUS_CHECK: 400 case ACPI_NOTIFY_BUS_CHECK:
401 case ACPI_NOTIFY_DEVICE_CHECK: 401 case ACPI_NOTIFY_DEVICE_CHECK:
402 case ACPI_NOTIFY_EJECT_REQUEST: 402 case ACPI_NOTIFY_EJECT_REQUEST:
403 status = acpi_hotplug_execute(acpi_device_hotplug, adev, type); 403 status = acpi_hotplug_schedule(adev, type);
404 if (ACPI_SUCCESS(status)) 404 if (ACPI_SUCCESS(status))
405 return; 405 return;
406 default: 406 default:
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 368f9ddb8480..a55cccbc7356 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -68,6 +68,9 @@ static int container_device_attach(struct acpi_device *adev,
68 struct device *dev; 68 struct device *dev;
69 int ret; 69 int ret;
70 70
71 if (adev->flags.is_dock_station)
72 return 0;
73
71 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 74 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
72 if (!cdev) 75 if (!cdev)
73 return -ENOMEM; 76 return -ENOMEM;
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 5bfd769fc91f..a7bd3002dbbc 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 *
@@ -68,15 +70,10 @@ struct dock_station {
68}; 70};
69static LIST_HEAD(dock_stations); 71static LIST_HEAD(dock_stations);
70static int dock_station_count; 72static int dock_station_count;
71static DEFINE_MUTEX(hotplug_lock);
72 73
73struct dock_dependent_device { 74struct dock_dependent_device {
74 struct list_head list; 75 struct list_head list;
75 acpi_handle handle; 76 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}; 77};
81 78
82#define DOCK_DOCKING 0x00000001 79#define DOCK_DOCKING 0x00000001
@@ -98,13 +95,13 @@ enum dock_callback_type {
98 *****************************************************************************/ 95 *****************************************************************************/
99/** 96/**
100 * add_dock_dependent_device - associate a device with the dock station 97 * add_dock_dependent_device - associate a device with the dock station
101 * @ds: The dock station 98 * @ds: Dock station.
102 * @handle: handle of the dependent device 99 * @adev: Dependent ACPI device object.
103 * 100 *
104 * Add the dependent device to the dock's dependent device list. 101 * Add the dependent device to the dock's dependent device list.
105 */ 102 */
106static int __init 103static int add_dock_dependent_device(struct dock_station *ds,
107add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 104 struct acpi_device *adev)
108{ 105{
109 struct dock_dependent_device *dd; 106 struct dock_dependent_device *dd;
110 107
@@ -112,180 +109,120 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
112 if (!dd) 109 if (!dd)
113 return -ENOMEM; 110 return -ENOMEM;
114 111
115 dd->handle = handle; 112 dd->adev = adev;
116 INIT_LIST_HEAD(&dd->list); 113 INIT_LIST_HEAD(&dd->list);
117 list_add_tail(&dd->list, &ds->dependent_devices); 114 list_add_tail(&dd->list, &ds->dependent_devices);
118 115
119 return 0; 116 return 0;
120} 117}
121 118
122static void remove_dock_dependent_devices(struct dock_station *ds) 119static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
120 enum dock_callback_type cb_type)
123{ 121{
124 struct dock_dependent_device *dd, *aux; 122 struct acpi_device *adev = dd->adev;
125 123
126 list_for_each_entry_safe(dd, aux, &ds->dependent_devices, list) { 124 acpi_lock_hp_context();
127 list_del(&dd->list);
128 kfree(dd);
129 }
130}
131 125
132/** 126 if (!adev->hp)
133 * dock_init_hotplug - Initialize a hotplug device on a docking station. 127 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 128
146 mutex_lock(&hotplug_lock); 129 if (cb_type == DOCK_CALL_FIXUP) {
147 if (WARN_ON(dd->hp_context)) { 130 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 131
161/** 132 fixup = adev->hp->fixup;
162 * dock_release_hotplug - Decrement hotplug reference counter of dock device. 133 if (fixup) {
163 * @dd: Dock-dependent device. 134 acpi_unlock_hp_context();
164 * 135 fixup(adev);
165 * Decrement the reference counter of @dd and if 0, detach its hotplug 136 return;
166 * operations from it, reset its context pointer and run the optional release 137 }
167 * routine if present. 138 } else if (cb_type == DOCK_CALL_UEVENT) {
168 */ 139 void (*uevent)(struct acpi_device *, u32);
169static void dock_release_hotplug(struct dock_dependent_device *dd) 140
170{ 141 uevent = adev->hp->uevent;
171 mutex_lock(&hotplug_lock); 142 if (uevent) {
172 if (dd->hp_context && !--dd->hp_refcount) { 143 acpi_unlock_hp_context();
173 void (*release)(void *) = dd->hp_release; 144 uevent(adev, event);
174 void *context = dd->hp_context; 145 return;
175 146 }
176 dd->hp_ops = NULL; 147 } else {
177 dd->hp_context = NULL; 148 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 149
185static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event, 150 notify = adev->hp->notify;
186 enum dock_callback_type cb_type) 151 if (notify) {
187{ 152 acpi_unlock_hp_context();
188 acpi_notify_handler cb = NULL; 153 notify(adev, event);
189 bool run = false; 154 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 } 155 }
208 } 156 }
209 157
210 mutex_unlock(&hotplug_lock); 158 out:
159 acpi_unlock_hp_context();
160}
211 161
212 if (!run) 162static struct dock_station *find_dock_station(acpi_handle handle)
213 return; 163{
164 struct dock_station *ds;
214 165
215 if (cb) 166 list_for_each_entry(ds, &dock_stations, sibling)
216 cb(dd->handle, event, dd->hp_context); 167 if (ds->handle == handle)
168 return ds;
217 169
218 dock_release_hotplug(dd); 170 return NULL;
219} 171}
220 172
221/** 173/**
222 * find_dock_dependent_device - get a device dependent on this dock 174 * find_dock_dependent_device - get a device dependent on this dock
223 * @ds: the dock station 175 * @ds: the dock station
224 * @handle: the acpi_handle of the device we want 176 * @adev: ACPI device object to find.
225 * 177 *
226 * iterate over the dependent device list for this dock. If the 178 * iterate over the dependent device list for this dock. If the
227 * dependent device matches the handle, return. 179 * dependent device matches the handle, return.
228 */ 180 */
229static struct dock_dependent_device * 181static struct dock_dependent_device *
230find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) 182find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev)
231{ 183{
232 struct dock_dependent_device *dd; 184 struct dock_dependent_device *dd;
233 185
234 list_for_each_entry(dd, &ds->dependent_devices, list) 186 list_for_each_entry(dd, &ds->dependent_devices, list)
235 if (handle == dd->handle) 187 if (adev == dd->adev)
236 return dd; 188 return dd;
237 189
238 return NULL; 190 return NULL;
239} 191}
240 192
241/***************************************************************************** 193void register_dock_dependent_device(struct acpi_device *adev,
242 * Dock functions * 194 acpi_handle dshandle)
243 *****************************************************************************/
244static int __init is_battery(acpi_handle handle)
245{ 195{
246 struct acpi_device_info *info; 196 struct dock_station *ds = find_dock_station(dshandle);
247 int ret = 1;
248 197
249 if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) 198 if (ds && !find_dock_dependent_device(ds, adev))
250 return 0; 199 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} 200}
259 201
260/* Check whether ACPI object is an ejectable battery or disk bay */ 202/*****************************************************************************
261static bool __init is_ejectable_bay(acpi_handle handle) 203 * Dock functions *
262{ 204 *****************************************************************************/
263 if (acpi_has_method(handle, "_EJ0") && is_battery(handle))
264 return true;
265
266 return acpi_bay_match(handle);
267}
268 205
269/** 206/**
270 * is_dock_device - see if a device is on a dock station 207 * is_dock_device - see if a device is on a dock station
271 * @handle: acpi handle of the device 208 * @adev: ACPI device object to check.
272 * 209 *
273 * If this device is either the dock station itself, 210 * If this device is either the dock station itself,
274 * or is a device dependent on the dock station, then it 211 * or is a device dependent on the dock station, then it
275 * is a dock device 212 * is a dock device
276 */ 213 */
277int is_dock_device(acpi_handle handle) 214int is_dock_device(struct acpi_device *adev)
278{ 215{
279 struct dock_station *dock_station; 216 struct dock_station *dock_station;
280 217
281 if (!dock_station_count) 218 if (!dock_station_count)
282 return 0; 219 return 0;
283 220
284 if (acpi_dock_match(handle)) 221 if (acpi_dock_match(adev->handle))
285 return 1; 222 return 1;
286 223
287 list_for_each_entry(dock_station, &dock_stations, sibling) 224 list_for_each_entry(dock_station, &dock_stations, sibling)
288 if (find_dock_dependent_device(dock_station, handle)) 225 if (find_dock_dependent_device(dock_station, adev))
289 return 1; 226 return 1;
290 227
291 return 0; 228 return 0;
@@ -313,43 +250,6 @@ static int dock_present(struct dock_station *ds)
313} 250}
314 251
315/** 252/**
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. 253 * hot_remove_dock_devices - Remove dock station devices.
354 * @ds: Dock station. 254 * @ds: Dock station.
355 */ 255 */
@@ -366,7 +266,7 @@ static void hot_remove_dock_devices(struct dock_station *ds)
366 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); 266 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false);
367 267
368 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) 268 list_for_each_entry_reverse(dd, &ds->dependent_devices, list)
369 dock_remove_acpi_device(dd->handle); 269 acpi_bus_trim(dd->adev);
370} 270}
371 271
372/** 272/**
@@ -392,12 +292,20 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
392 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); 292 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER);
393 293
394 /* 294 /*
395 * Now make sure that an acpi_device is created for each dependent 295 * Check if all devices have been enumerated already. If not, run
396 * device. That will cause scan handlers to be attached to device 296 * 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. 297 * attached to device objects or acpi_drivers to be stopped/started if
298 * they are present.
398 */ 299 */
399 list_for_each_entry(dd, &ds->dependent_devices, list) 300 list_for_each_entry(dd, &ds->dependent_devices, list) {
400 dock_create_acpi_device(dd->handle); 301 struct acpi_device *adev = dd->adev;
302
303 if (!acpi_device_enumerated(adev)) {
304 int ret = acpi_bus_scan(adev->handle);
305 if (ret)
306 dev_dbg(&adev->dev, "scan error %d\n", -ret);
307 }
308 }
401} 309}
402 310
403static void dock_event(struct dock_station *ds, u32 event, int num) 311static void dock_event(struct dock_station *ds, u32 event, int num)
@@ -501,71 +409,6 @@ static int dock_in_progress(struct dock_station *ds)
501} 409}
502 410
503/** 411/**
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 412 * handle_eject_request - handle an undock request checking for error conditions
570 * 413 *
571 * Check to make sure the dock device is still present, then undock and 414 * Check to make sure the dock device is still present, then undock and
@@ -598,20 +441,23 @@ static int handle_eject_request(struct dock_station *ds, u32 event)
598} 441}
599 442
600/** 443/**
601 * dock_notify - act upon an acpi dock notification 444 * dock_notify - Handle ACPI dock notification.
602 * @ds: dock station 445 * @adev: Dock station's ACPI device object.
603 * @event: the acpi event 446 * @event: Event code.
604 * 447 *
605 * If we are notified to dock, then check to see if the dock is 448 * 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, 449 * present and then dock. Notify all drivers of the dock event,
607 * and then hotplug and devices that may need hotplugging. 450 * and then hotplug and devices that may need hotplugging.
608 */ 451 */
609static void dock_notify(struct dock_station *ds, u32 event) 452int dock_notify(struct acpi_device *adev, u32 event)
610{ 453{
611 acpi_handle handle = ds->handle; 454 acpi_handle handle = adev->handle;
612 struct acpi_device *adev = NULL; 455 struct dock_station *ds = find_dock_station(handle);
613 int surprise_removal = 0; 456 int surprise_removal = 0;
614 457
458 if (!ds)
459 return -ENODEV;
460
615 /* 461 /*
616 * According to acpi spec 3.0a, if a DEVICE_CHECK notification 462 * 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 463 * is sent and _DCK is present, it is assumed to mean an undock
@@ -632,7 +478,6 @@ static void dock_notify(struct dock_station *ds, u32 event)
632 switch (event) { 478 switch (event) {
633 case ACPI_NOTIFY_BUS_CHECK: 479 case ACPI_NOTIFY_BUS_CHECK:
634 case ACPI_NOTIFY_DEVICE_CHECK: 480 case ACPI_NOTIFY_DEVICE_CHECK:
635 acpi_bus_get_device(handle, &adev);
636 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) { 481 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) {
637 begin_dock(ds); 482 begin_dock(ds);
638 dock(ds); 483 dock(ds);
@@ -662,49 +507,8 @@ static void dock_notify(struct dock_station *ds, u32 event)
662 else 507 else
663 dock_event(ds, event, UNDOCK_EVENT); 508 dock_event(ds, event, UNDOCK_EVENT);
664 break; 509 break;
665 default:
666 acpi_handle_err(handle, "Unknown dock event %d\n", event);
667 } 510 }
668} 511 return 0;
669
670static void acpi_dock_deferred_cb(void *data, u32 event)
671{
672 acpi_scan_lock_acquire();
673 dock_notify(data, event);
674 acpi_scan_lock_release();
675}
676
677static void dock_notify_handler(acpi_handle handle, u32 event, void *data)
678{
679 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
680 && event != ACPI_NOTIFY_EJECT_REQUEST)
681 return;
682
683 acpi_hotplug_execute(acpi_dock_deferred_cb, data, event);
684}
685
686/**
687 * find_dock_devices - find devices on the dock station
688 * @handle: the handle of the device we are examining
689 * @lvl: unused
690 * @context: the dock station private data
691 * @rv: unused
692 *
693 * This function is called by acpi_walk_namespace. It will
694 * check to see if an object has an _EJD method. If it does, then it
695 * will see if it is dependent on the dock station.
696 */
697static acpi_status __init find_dock_devices(acpi_handle handle, u32 lvl,
698 void *context, void **rv)
699{
700 struct dock_station *ds = context;
701 acpi_handle ejd = NULL;
702
703 acpi_bus_get_ejd(handle, &ejd);
704 if (ejd == ds->handle)
705 add_dock_dependent_device(ds, handle);
706
707 return AE_OK;
708} 512}
709 513
710/* 514/*
@@ -803,23 +607,28 @@ static struct attribute_group dock_attribute_group = {
803}; 607};
804 608
805/** 609/**
806 * dock_add - add a new dock station 610 * acpi_dock_add - Add a new dock station
807 * @handle: the dock station handle 611 * @adev: Dock station ACPI device object.
808 * 612 *
809 * allocated and initialize a new dock station device. Find all devices 613 * allocated and initialize a new dock station device.
810 * that are on the dock station, and register for dock event notifications.
811 */ 614 */
812static int __init dock_add(acpi_handle handle) 615void acpi_dock_add(struct acpi_device *adev)
813{ 616{
814 struct dock_station *dock_station, ds = { NULL, }; 617 struct dock_station *dock_station, ds = { NULL, };
618 struct platform_device_info pdevinfo;
619 acpi_handle handle = adev->handle;
815 struct platform_device *dd; 620 struct platform_device *dd;
816 acpi_status status;
817 int ret; 621 int ret;
818 622
819 dd = platform_device_register_data(NULL, "dock", dock_station_count, 623 memset(&pdevinfo, 0, sizeof(pdevinfo));
820 &ds, sizeof(ds)); 624 pdevinfo.name = "dock";
625 pdevinfo.id = dock_station_count;
626 pdevinfo.acpi_node.companion = adev;
627 pdevinfo.data = &ds;
628 pdevinfo.size_data = sizeof(ds);
629 dd = platform_device_register_full(&pdevinfo);
821 if (IS_ERR(dd)) 630 if (IS_ERR(dd))
822 return PTR_ERR(dd); 631 return;
823 632
824 dock_station = dd->dev.platform_data; 633 dock_station = dd->dev.platform_data;
825 634
@@ -837,72 +646,29 @@ static int __init dock_add(acpi_handle handle)
837 dock_station->flags |= DOCK_IS_DOCK; 646 dock_station->flags |= DOCK_IS_DOCK;
838 if (acpi_ata_match(handle)) 647 if (acpi_ata_match(handle))
839 dock_station->flags |= DOCK_IS_ATA; 648 dock_station->flags |= DOCK_IS_ATA;
840 if (is_battery(handle)) 649 if (acpi_device_is_battery(adev))
841 dock_station->flags |= DOCK_IS_BAT; 650 dock_station->flags |= DOCK_IS_BAT;
842 651
843 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); 652 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group);
844 if (ret) 653 if (ret)
845 goto err_unregister; 654 goto err_unregister;
846 655
847 /* Find dependent devices */
848 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
849 ACPI_UINT32_MAX, find_dock_devices, NULL,
850 dock_station, NULL);
851
852 /* add the dock station as a device dependent on itself */ 656 /* add the dock station as a device dependent on itself */
853 ret = add_dock_dependent_device(dock_station, handle); 657 ret = add_dock_dependent_device(dock_station, adev);
854 if (ret) 658 if (ret)
855 goto err_rmgroup; 659 goto err_rmgroup;
856 660
857 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
858 dock_notify_handler, dock_station);
859 if (ACPI_FAILURE(status)) {
860 ret = -ENODEV;
861 goto err_rmgroup;
862 }
863
864 dock_station_count++; 661 dock_station_count++;
865 list_add(&dock_station->sibling, &dock_stations); 662 list_add(&dock_station->sibling, &dock_stations);
866 return 0; 663 adev->flags.is_dock_station = true;
664 dev_info(&adev->dev, "ACPI dock station (docks/bays count: %d)\n",
665 dock_station_count);
666 return;
867 667
868err_rmgroup: 668err_rmgroup:
869 remove_dock_dependent_devices(dock_station);
870 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); 669 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group);
670
871err_unregister: 671err_unregister:
872 platform_device_unregister(dd); 672 platform_device_unregister(dd);
873 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); 673 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret);
874 return ret;
875}
876
877/**
878 * find_dock_and_bay - look for dock stations and bays
879 * @handle: acpi handle of a device
880 * @lvl: unused
881 * @context: unused
882 * @rv: unused
883 *
884 * This is called by acpi_walk_namespace to look for dock stations and bays.
885 */
886static acpi_status __init
887find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
888{
889 if (acpi_dock_match(handle) || is_ejectable_bay(handle))
890 dock_add(handle);
891
892 return AE_OK;
893}
894
895void __init acpi_dock_init(void)
896{
897 /* look for dock stations and bays */
898 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
899 ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL);
900
901 if (!dock_station_count) {
902 pr_info(PREFIX "No dock devices found.\n");
903 return;
904 }
905
906 pr_info(PREFIX "%s: %d docks/bays found\n",
907 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
908} 674}
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
index 143d5df5ec32..957391306cbf 100644
--- a/drivers/acpi/internal.h
+++ b/drivers/acpi/internal.h
@@ -37,9 +37,15 @@ void acpi_container_init(void);
37static inline void acpi_container_init(void) {} 37static inline void acpi_container_init(void) {}
38#endif 38#endif
39#ifdef CONFIG_ACPI_DOCK 39#ifdef CONFIG_ACPI_DOCK
40void acpi_dock_init(void); 40void register_dock_dependent_device(struct acpi_device *adev,
41 acpi_handle dshandle);
42int dock_notify(struct acpi_device *adev, u32 event);
43void acpi_dock_add(struct acpi_device *adev);
41#else 44#else
42static inline void acpi_dock_init(void) {} 45static inline void register_dock_dependent_device(struct acpi_device *adev,
46 acpi_handle dshandle) {}
47static inline int dock_notify(struct acpi_device *adev, u32 event) { return -ENODEV; }
48static inline void acpi_dock_add(struct acpi_device *adev) {}
43#endif 49#endif
44#ifdef CONFIG_ACPI_HOTPLUG_MEMORY 50#ifdef CONFIG_ACPI_HOTPLUG_MEMORY
45void acpi_memory_hotplug_init(void); 51void acpi_memory_hotplug_init(void);
@@ -72,8 +78,9 @@ void acpi_lpss_init(void);
72static inline void acpi_lpss_init(void) {} 78static inline void acpi_lpss_init(void) {}
73#endif 79#endif
74 80
81acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src);
75bool acpi_queue_hotplug_work(struct work_struct *work); 82bool acpi_queue_hotplug_work(struct work_struct *work);
76void acpi_device_hotplug(void *data, u32 src); 83void acpi_device_hotplug(struct acpi_device *adev, u32 src);
77bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent); 84bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
78 85
79/* -------------------------------------------------------------------------- 86/* --------------------------------------------------------------------------
@@ -91,6 +98,7 @@ void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
91int acpi_bind_one(struct device *dev, struct acpi_device *adev); 98int acpi_bind_one(struct device *dev, struct acpi_device *adev);
92int acpi_unbind_one(struct device *dev); 99int acpi_unbind_one(struct device *dev);
93bool acpi_device_is_present(struct acpi_device *adev); 100bool acpi_device_is_present(struct acpi_device *adev);
101bool acpi_device_is_battery(struct acpi_device *adev);
94 102
95/* -------------------------------------------------------------------------- 103/* --------------------------------------------------------------------------
96 Power Resource 104 Power Resource
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fc1aa7909690..afb4be566940 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1168,8 +1168,7 @@ void acpi_os_wait_events_complete(void)
1168 1168
1169struct acpi_hp_work { 1169struct acpi_hp_work {
1170 struct work_struct work; 1170 struct work_struct work;
1171 acpi_hp_callback func; 1171 struct acpi_device *adev;
1172 void *data;
1173 u32 src; 1172 u32 src;
1174}; 1173};
1175 1174
@@ -1178,25 +1177,24 @@ static void acpi_hotplug_work_fn(struct work_struct *work)
1178 struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work); 1177 struct acpi_hp_work *hpw = container_of(work, struct acpi_hp_work, work);
1179 1178
1180 acpi_os_wait_events_complete(); 1179 acpi_os_wait_events_complete();
1181 hpw->func(hpw->data, hpw->src); 1180 acpi_device_hotplug(hpw->adev, hpw->src);
1182 kfree(hpw); 1181 kfree(hpw);
1183} 1182}
1184 1183
1185acpi_status acpi_hotplug_execute(acpi_hp_callback func, void *data, u32 src) 1184acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src)
1186{ 1185{
1187 struct acpi_hp_work *hpw; 1186 struct acpi_hp_work *hpw;
1188 1187
1189 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 1188 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
1190 "Scheduling function [%p(%p, %u)] for deferred execution.\n", 1189 "Scheduling hotplug event (%p, %u) for deferred execution.\n",
1191 func, data, src)); 1190 adev, src));
1192 1191
1193 hpw = kmalloc(sizeof(*hpw), GFP_KERNEL); 1192 hpw = kmalloc(sizeof(*hpw), GFP_KERNEL);
1194 if (!hpw) 1193 if (!hpw)
1195 return AE_NO_MEMORY; 1194 return AE_NO_MEMORY;
1196 1195
1197 INIT_WORK(&hpw->work, acpi_hotplug_work_fn); 1196 INIT_WORK(&hpw->work, acpi_hotplug_work_fn);
1198 hpw->func = func; 1197 hpw->adev = adev;
1199 hpw->data = data;
1200 hpw->src = src; 1198 hpw->src = src;
1201 /* 1199 /*
1202 * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because 1200 * We can't run hotplug code in kacpid_wq/kacpid_notify_wq etc., because
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 8bb48bfab1df..eb7a1ff224e7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -71,6 +71,17 @@ void acpi_unlock_hp_context(void)
71 mutex_unlock(&acpi_hp_context_lock); 71 mutex_unlock(&acpi_hp_context_lock);
72} 72}
73 73
74void acpi_initialize_hp_context(struct acpi_device *adev,
75 struct acpi_hotplug_context *hp,
76 int (*notify)(struct acpi_device *, u32),
77 void (*uevent)(struct acpi_device *, u32))
78{
79 acpi_lock_hp_context();
80 acpi_set_hp_context(adev, hp, notify, uevent, NULL);
81 acpi_unlock_hp_context();
82}
83EXPORT_SYMBOL_GPL(acpi_initialize_hp_context);
84
74int acpi_scan_add_handler(struct acpi_scan_handler *handler) 85int acpi_scan_add_handler(struct acpi_scan_handler *handler)
75{ 86{
76 if (!handler || !handler->attach) 87 if (!handler || !handler->attach)
@@ -470,10 +481,9 @@ static int acpi_generic_hotplug_event(struct acpi_device *adev, u32 type)
470 return -EINVAL; 481 return -EINVAL;
471} 482}
472 483
473void acpi_device_hotplug(void *data, u32 src) 484void acpi_device_hotplug(struct acpi_device *adev, u32 src)
474{ 485{
475 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; 486 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
476 struct acpi_device *adev = data;
477 int error = -ENODEV; 487 int error = -ENODEV;
478 488
479 lock_device_hotplug(); 489 lock_device_hotplug();
@@ -487,24 +497,26 @@ void acpi_device_hotplug(void *data, u32 src)
487 if (adev->handle == INVALID_ACPI_HANDLE) 497 if (adev->handle == INVALID_ACPI_HANDLE)
488 goto err_out; 498 goto err_out;
489 499
490 if (adev->flags.hotplug_notify) { 500 if (adev->flags.is_dock_station) {
501 error = dock_notify(adev, src);
502 } else if (adev->flags.hotplug_notify) {
491 error = acpi_generic_hotplug_event(adev, src); 503 error = acpi_generic_hotplug_event(adev, src);
492 if (error == -EPERM) { 504 if (error == -EPERM) {
493 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; 505 ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED;
494 goto err_out; 506 goto err_out;
495 } 507 }
496 } else { 508 } else {
497 int (*event)(struct acpi_device *, u32); 509 int (*notify)(struct acpi_device *, u32);
498 510
499 acpi_lock_hp_context(); 511 acpi_lock_hp_context();
500 event = adev->hp ? adev->hp->event : NULL; 512 notify = adev->hp ? adev->hp->notify : NULL;
501 acpi_unlock_hp_context(); 513 acpi_unlock_hp_context();
502 /* 514 /*
503 * There may be additional notify handlers for device objects 515 * There may be additional notify handlers for device objects
504 * without the .event() callback, so ignore them here. 516 * without the .event() callback, so ignore them here.
505 */ 517 */
506 if (event) 518 if (notify)
507 error = event(adev, src); 519 error = notify(adev, src);
508 else 520 else
509 goto out; 521 goto out;
510 } 522 }
@@ -566,8 +578,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
566 return -ENODEV; 578 return -ENODEV;
567 579
568 get_device(&acpi_device->dev); 580 get_device(&acpi_device->dev);
569 status = acpi_hotplug_execute(acpi_device_hotplug, acpi_device, 581 status = acpi_hotplug_schedule(acpi_device, ACPI_OST_EC_OSPM_EJECT);
570 ACPI_OST_EC_OSPM_EJECT);
571 if (ACPI_SUCCESS(status)) 582 if (ACPI_SUCCESS(status))
572 return count; 583 return count;
573 584
@@ -1660,6 +1671,27 @@ bool acpi_bay_match(acpi_handle handle)
1660 return acpi_ata_match(phandle); 1671 return acpi_ata_match(phandle);
1661} 1672}
1662 1673
1674bool acpi_device_is_battery(struct acpi_device *adev)
1675{
1676 struct acpi_hardware_id *hwid;
1677
1678 list_for_each_entry(hwid, &adev->pnp.ids, list)
1679 if (!strcmp("PNP0C0A", hwid->id))
1680 return true;
1681
1682 return false;
1683}
1684
1685static bool is_ejectable_bay(struct acpi_device *adev)
1686{
1687 acpi_handle handle = adev->handle;
1688
1689 if (acpi_has_method(handle, "_EJ0") && acpi_device_is_battery(adev))
1690 return true;
1691
1692 return acpi_bay_match(handle);
1693}
1694
1663/* 1695/*
1664 * acpi_dock_match - see if an acpi object has a _DCK method 1696 * acpi_dock_match - see if an acpi object has a _DCK method
1665 */ 1697 */
@@ -1964,6 +1996,10 @@ static void acpi_scan_init_hotplug(struct acpi_device *adev)
1964{ 1996{
1965 struct acpi_hardware_id *hwid; 1997 struct acpi_hardware_id *hwid;
1966 1998
1999 if (acpi_dock_match(adev->handle) || is_ejectable_bay(adev)) {
2000 acpi_dock_add(adev);
2001 return;
2002 }
1967 list_for_each_entry(hwid, &adev->pnp.ids, list) { 2003 list_for_each_entry(hwid, &adev->pnp.ids, list) {
1968 struct acpi_scan_handler *handler; 2004 struct acpi_scan_handler *handler;
1969 2005
@@ -2035,8 +2071,12 @@ static int acpi_scan_attach_handler(struct acpi_device *device)
2035static void acpi_bus_attach(struct acpi_device *device) 2071static void acpi_bus_attach(struct acpi_device *device)
2036{ 2072{
2037 struct acpi_device *child; 2073 struct acpi_device *child;
2074 acpi_handle ejd;
2038 int ret; 2075 int ret;
2039 2076
2077 if (ACPI_SUCCESS(acpi_bus_get_ejd(device->handle, &ejd)))
2078 register_dock_dependent_device(device, ejd);
2079
2040 acpi_bus_get_status(device); 2080 acpi_bus_get_status(device);
2041 /* Skip devices that are not present. */ 2081 /* Skip devices that are not present. */
2042 if (!acpi_device_is_present(device)) { 2082 if (!acpi_device_is_present(device)) {
@@ -2189,7 +2229,6 @@ int __init acpi_scan_init(void)
2189 acpi_cmos_rtc_init(); 2229 acpi_cmos_rtc_init();
2190 acpi_container_init(); 2230 acpi_container_init();
2191 acpi_memory_hotplug_init(); 2231 acpi_memory_hotplug_init();
2192 acpi_dock_init();
2193 2232
2194 mutex_lock(&acpi_scan_lock); 2233 mutex_lock(&acpi_scan_lock);
2195 /* 2234 /*
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 9e69a5308693..acb95dffdb6a 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -38,6 +38,16 @@ static void ata_acpi_clear_gtf(struct ata_device *dev)
38 dev->gtf_cache = NULL; 38 dev->gtf_cache = NULL;
39} 39}
40 40
41struct ata_acpi_hotplug_context {
42 struct acpi_hotplug_context hp;
43 union {
44 struct ata_port *ap;
45 struct ata_device *dev;
46 } data;
47};
48
49#define ata_hotplug_data(context) (container_of((context), struct ata_acpi_hotplug_context, hp)->data)
50
41/** 51/**
42 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device 52 * ata_dev_acpi_handle - provide the acpi_handle for an ata_device
43 * @dev: the acpi_handle returned will correspond to this device 53 * @dev: the acpi_handle returned will correspond to this device
@@ -121,18 +131,17 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
121 ata_port_wait_eh(ap); 131 ata_port_wait_eh(ap);
122} 132}
123 133
124static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) 134static int ata_acpi_dev_notify_dock(struct acpi_device *adev, u32 event)
125{ 135{
126 struct ata_device *dev = data; 136 struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
127
128 ata_acpi_handle_hotplug(dev->link->ap, dev, event); 137 ata_acpi_handle_hotplug(dev->link->ap, dev, event);
138 return 0;
129} 139}
130 140
131static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) 141static int ata_acpi_ap_notify_dock(struct acpi_device *adev, u32 event)
132{ 142{
133 struct ata_port *ap = data; 143 ata_acpi_handle_hotplug(ata_hotplug_data(adev->hp).ap, NULL, event);
134 144 return 0;
135 ata_acpi_handle_hotplug(ap, NULL, event);
136} 145}
137 146
138static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev, 147static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
@@ -154,31 +163,23 @@ static void ata_acpi_uevent(struct ata_port *ap, struct ata_device *dev,
154 } 163 }
155} 164}
156 165
157static void ata_acpi_ap_uevent(acpi_handle handle, u32 event, void *data) 166static void ata_acpi_ap_uevent(struct acpi_device *adev, u32 event)
158{ 167{
159 ata_acpi_uevent(data, NULL, event); 168 ata_acpi_uevent(ata_hotplug_data(adev->hp).ap, NULL, event);
160} 169}
161 170
162static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data) 171static void ata_acpi_dev_uevent(struct acpi_device *adev, u32 event)
163{ 172{
164 struct ata_device *dev = data; 173 struct ata_device *dev = ata_hotplug_data(adev->hp).dev;
165 ata_acpi_uevent(dev->link->ap, dev, event); 174 ata_acpi_uevent(dev->link->ap, dev, event);
166} 175}
167 176
168static const struct acpi_dock_ops ata_acpi_dev_dock_ops = {
169 .handler = ata_acpi_dev_notify_dock,
170 .uevent = ata_acpi_dev_uevent,
171};
172
173static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
174 .handler = ata_acpi_ap_notify_dock,
175 .uevent = ata_acpi_ap_uevent,
176};
177
178/* bind acpi handle to pata port */ 177/* bind acpi handle to pata port */
179void ata_acpi_bind_port(struct ata_port *ap) 178void ata_acpi_bind_port(struct ata_port *ap)
180{ 179{
181 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); 180 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
181 struct acpi_device *adev;
182 struct ata_acpi_hotplug_context *context;
182 183
183 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion) 184 if (libata_noacpi || ap->flags & ATA_FLAG_ACPI_SATA || !host_companion)
184 return; 185 return;
@@ -188,9 +189,17 @@ void ata_acpi_bind_port(struct ata_port *ap)
188 if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0) 189 if (ata_acpi_gtm(ap, &ap->__acpi_init_gtm) == 0)
189 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; 190 ap->pflags |= ATA_PFLAG_INIT_GTM_VALID;
190 191
191 /* we might be on a docking station */ 192 adev = ACPI_COMPANION(&ap->tdev);
192 register_hotplug_dock_device(ACPI_HANDLE(&ap->tdev), 193 if (!adev || adev->hp)
193 &ata_acpi_ap_dock_ops, ap, NULL, NULL); 194 return;
195
196 context = kzalloc(sizeof(*context), GFP_KERNEL);
197 if (!context)
198 return;
199
200 context->data.ap = ap;
201 acpi_initialize_hp_context(adev, &context->hp, ata_acpi_ap_notify_dock,
202 ata_acpi_ap_uevent);
194} 203}
195 204
196void ata_acpi_bind_dev(struct ata_device *dev) 205void ata_acpi_bind_dev(struct ata_device *dev)
@@ -198,7 +207,8 @@ void ata_acpi_bind_dev(struct ata_device *dev)
198 struct ata_port *ap = dev->link->ap; 207 struct ata_port *ap = dev->link->ap;
199 struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev); 208 struct acpi_device *port_companion = ACPI_COMPANION(&ap->tdev);
200 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev); 209 struct acpi_device *host_companion = ACPI_COMPANION(ap->host->dev);
201 struct acpi_device *parent; 210 struct acpi_device *parent, *adev;
211 struct ata_acpi_hotplug_context *context;
202 u64 adr; 212 u64 adr;
203 213
204 /* 214 /*
@@ -221,9 +231,17 @@ void ata_acpi_bind_dev(struct ata_device *dev)
221 } 231 }
222 232
223 acpi_preset_companion(&dev->tdev, parent, adr); 233 acpi_preset_companion(&dev->tdev, parent, adr);
234 adev = ACPI_COMPANION(&dev->tdev);
235 if (!adev || adev->hp)
236 return;
237
238 context = kzalloc(sizeof(*context), GFP_KERNEL);
239 if (!context)
240 return;
224 241
225 register_hotplug_dock_device(ata_dev_acpi_handle(dev), 242 context->data.dev = dev;
226 &ata_acpi_dev_dock_ops, dev, NULL, NULL); 243 acpi_initialize_hp_context(adev, &context->hp, ata_acpi_dev_notify_dock,
244 ata_acpi_dev_uevent);
227} 245}
228 246
229/** 247/**
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 2d51bf7e9fe0..828acf422c17 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -59,7 +59,8 @@
59static LIST_HEAD(bridge_list); 59static LIST_HEAD(bridge_list);
60static DEFINE_MUTEX(bridge_mutex); 60static DEFINE_MUTEX(bridge_mutex);
61 61
62static int acpiphp_hotplug_event(struct acpi_device *adev, u32 type); 62static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type);
63static void acpiphp_post_dock_fixup(struct acpi_device *adev);
63static void acpiphp_sanitize_bus(struct pci_bus *bus); 64static void acpiphp_sanitize_bus(struct pci_bus *bus);
64static void acpiphp_set_hpp_values(struct pci_bus *bus); 65static void acpiphp_set_hpp_values(struct pci_bus *bus);
65static void hotplug_event(u32 type, struct acpiphp_context *context); 66static void hotplug_event(u32 type, struct acpiphp_context *context);
@@ -80,7 +81,8 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
80 return NULL; 81 return NULL;
81 82
82 context->refcount = 1; 83 context->refcount = 1;
83 acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_event); 84 acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL,
85 acpiphp_post_dock_fixup);
84 return context; 86 return context;
85} 87}
86 88
@@ -130,6 +132,27 @@ static inline void put_bridge(struct acpiphp_bridge *bridge)
130 kref_put(&bridge->ref, free_bridge); 132 kref_put(&bridge->ref, free_bridge);
131} 133}
132 134
135static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev)
136{
137 struct acpiphp_context *context;
138
139 acpi_lock_hp_context();
140 context = acpiphp_get_context(adev);
141 if (!context || context->func.parent->is_going_away) {
142 acpi_unlock_hp_context();
143 return NULL;
144 }
145 get_bridge(context->func.parent);
146 acpiphp_put_context(context);
147 acpi_unlock_hp_context();
148 return context;
149}
150
151static void acpiphp_let_context_go(struct acpiphp_context *context)
152{
153 put_bridge(context->func.parent);
154}
155
133static void free_bridge(struct kref *kref) 156static void free_bridge(struct kref *kref)
134{ 157{
135 struct acpiphp_context *context; 158 struct acpiphp_context *context;
@@ -164,28 +187,29 @@ static void free_bridge(struct kref *kref)
164 acpi_unlock_hp_context(); 187 acpi_unlock_hp_context();
165} 188}
166 189
167/* 190/**
168 * the _DCK method can do funny things... and sometimes not 191 * acpiphp_post_dock_fixup - Post-dock fixups for PCI devices.
169 * hah-hah funny. 192 * @adev: ACPI device object corresponding to a PCI device.
170 * 193 *
171 * TBD - figure out a way to only call fixups for 194 * TBD - figure out a way to only call fixups for systems that require them.
172 * systems that require them.
173 */ 195 */
174static void post_dock_fixups(acpi_handle not_used, u32 event, void *data) 196static void acpiphp_post_dock_fixup(struct acpi_device *adev)
175{ 197{
176 struct acpiphp_context *context = data; 198 struct acpiphp_context *context = acpiphp_grab_context(adev);
177 struct pci_bus *bus = context->func.slot->bus; 199 struct pci_bus *bus;
178 u32 buses; 200 u32 buses;
179 201
180 if (!bus->self) 202 if (!context)
181 return; 203 return;
182 204
205 bus = context->func.slot->bus;
206 if (!bus->self)
207 goto out;
208
183 /* fixup bad _DCK function that rewrites 209 /* fixup bad _DCK function that rewrites
184 * secondary bridge on slot 210 * secondary bridge on slot
185 */ 211 */
186 pci_read_config_dword(bus->self, 212 pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses);
187 PCI_PRIMARY_BUS,
188 &buses);
189 213
190 if (((buses >> 8) & 0xff) != bus->busn_res.start) { 214 if (((buses >> 8) & 0xff) != bus->busn_res.start) {
191 buses = (buses & 0xff000000) 215 buses = (buses & 0xff000000)
@@ -194,24 +218,11 @@ static void post_dock_fixups(acpi_handle not_used, u32 event, void *data)
194 | ((unsigned int)(bus->busn_res.end) << 16); 218 | ((unsigned int)(bus->busn_res.end) << 16);
195 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); 219 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
196 } 220 }
197}
198
199static void dock_event(acpi_handle handle, u32 type, void *data)
200{
201 struct acpi_device *adev;
202 221
203 adev = acpi_bus_get_acpi_device(handle); 222 out:
204 if (adev) { 223 acpiphp_let_context_go(context);
205 acpiphp_hotplug_event(adev, type);
206 acpi_bus_put_acpi_device(adev);
207 }
208} 224}
209 225
210static const struct acpi_dock_ops acpiphp_dock_ops = {
211 .fixup = post_dock_fixups,
212 .handler = dock_event,
213};
214
215/* Check whether the PCI device is managed by native PCIe hotplug driver */ 226/* Check whether the PCI device is managed by native PCIe hotplug driver */
216static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev) 227static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
217{ 228{
@@ -241,20 +252,6 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
241 return true; 252 return true;
242} 253}
243 254
244static void acpiphp_dock_init(void *data)
245{
246 struct acpiphp_context *context = data;
247
248 get_bridge(context->func.parent);
249}
250
251static void acpiphp_dock_release(void *data)
252{
253 struct acpiphp_context *context = data;
254
255 put_bridge(context->func.parent);
256}
257
258/** 255/**
259 * acpiphp_add_context - Add ACPIPHP context to an ACPI device object. 256 * acpiphp_add_context - Add ACPIPHP context to an ACPI device object.
260 * @handle: ACPI handle of the object to add a context to. 257 * @handle: ACPI handle of the object to add a context to.
@@ -300,22 +297,18 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
300 newfunc = &context->func; 297 newfunc = &context->func;
301 newfunc->function = function; 298 newfunc->function = function;
302 newfunc->parent = bridge; 299 newfunc->parent = bridge;
300 acpi_unlock_hp_context();
303 301
304 if (acpi_has_method(handle, "_EJ0")) 302 /*
303 * If this is a dock device, its _EJ0 should be executed by the dock
304 * notify handler after calling _DCK.
305 */
306 if (!is_dock_device(adev) && acpi_has_method(handle, "_EJ0"))
305 newfunc->flags = FUNC_HAS_EJ0; 307 newfunc->flags = FUNC_HAS_EJ0;
306 308
307 if (acpi_has_method(handle, "_STA")) 309 if (acpi_has_method(handle, "_STA"))
308 newfunc->flags |= FUNC_HAS_STA; 310 newfunc->flags |= FUNC_HAS_STA;
309 311
310 /*
311 * Dock stations' notify handler should be used for dock devices instead
312 * of the common one, so clear hp.event in their contexts.
313 */
314 if (acpi_has_method(handle, "_DCK"))
315 context->hp.event = NULL;
316
317 acpi_unlock_hp_context();
318
319 /* search for objects that share the same slot */ 312 /* search for objects that share the same slot */
320 list_for_each_entry(slot, &bridge->slots, node) 313 list_for_each_entry(slot, &bridge->slots, node)
321 if (slot->device == device) 314 if (slot->device == device)
@@ -341,7 +334,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
341 * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to 334 * by the native PCIe hotplug (PCIeHP), becuase that code is supposed to
342 * expose slots to user space in those cases. 335 * expose slots to user space in those cases.
343 */ 336 */
344 if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(handle)) 337 if ((acpi_pci_check_ejectable(pbus, handle) || is_dock_device(adev))
345 && !(pdev && device_is_managed_by_native_pciehp(pdev))) { 338 && !(pdev && device_is_managed_by_native_pciehp(pdev))) {
346 unsigned long long sun; 339 unsigned long long sun;
347 int retval; 340 int retval;
@@ -376,18 +369,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
376 &val, 60*1000)) 369 &val, 60*1000))
377 slot->flags |= SLOT_ENABLED; 370 slot->flags |= SLOT_ENABLED;
378 371
379 if (is_dock_device(handle)) {
380 /* we don't want to call this device's _EJ0
381 * because we want the dock notify handler
382 * to call it after it calls _DCK
383 */
384 newfunc->flags &= ~FUNC_HAS_EJ0;
385 if (register_hotplug_dock_device(handle,
386 &acpiphp_dock_ops, context,
387 acpiphp_dock_init, acpiphp_dock_release))
388 pr_debug("failed to register dock device\n");
389 }
390
391 return AE_OK; 372 return AE_OK;
392} 373}
393 374
@@ -418,11 +399,9 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge)
418 list_for_each_entry(func, &slot->funcs, sibling) { 399 list_for_each_entry(func, &slot->funcs, sibling) {
419 struct acpi_device *adev = func_to_acpi_device(func); 400 struct acpi_device *adev = func_to_acpi_device(func);
420 401
421 if (is_dock_device(adev->handle))
422 unregister_hotplug_dock_device(adev->handle);
423
424 acpi_lock_hp_context(); 402 acpi_lock_hp_context();
425 adev->hp->event = NULL; 403 adev->hp->notify = NULL;
404 adev->hp->fixup = NULL;
426 acpi_unlock_hp_context(); 405 acpi_unlock_hp_context();
427 } 406 }
428 slot->flags |= SLOT_IS_GOING_AWAY; 407 slot->flags |= SLOT_IS_GOING_AWAY;
@@ -851,23 +830,16 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
851 put_bridge(bridge); 830 put_bridge(bridge);
852} 831}
853 832
854static int acpiphp_hotplug_event(struct acpi_device *adev, u32 type) 833static int acpiphp_hotplug_notify(struct acpi_device *adev, u32 type)
855{ 834{
856 struct acpiphp_context *context; 835 struct acpiphp_context *context;
857 836
858 acpi_lock_hp_context(); 837 context = acpiphp_grab_context(adev);
859 context = acpiphp_get_context(adev); 838 if (!context)
860 if (!context || context->func.parent->is_going_away) {
861 acpi_unlock_hp_context();
862 return -ENODATA; 839 return -ENODATA;
863 }
864 get_bridge(context->func.parent);
865 acpiphp_put_context(context);
866 acpi_unlock_hp_context();
867 840
868 hotplug_event(type, context); 841 hotplug_event(type, context);
869 842 acpiphp_let_context_go(context);
870 put_bridge(context->func.parent);
871 return 0; 843 return 0;
872} 844}
873 845