dock.c (d4263348f796f29546f90802177865dd4379dd0a) | dock.c (3b52b21fa1f44c8956e21dfba645eda959111b5e) |
---|---|
1/* 2 * dock.c - ACPI dock station driver 3 * 4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify --- 58 unchanged lines hidden (view full) --- 67 struct platform_device *dock_device; 68}; 69static LIST_HEAD(dock_stations); 70static int dock_station_count; 71static DEFINE_MUTEX(hotplug_lock); 72 73struct dock_dependent_device { 74 struct list_head list; | 1/* 2 * dock.c - ACPI dock station driver 3 * 4 * Copyright (C) 2006 Kristen Carlson Accardi <kristen.c.accardi@intel.com> 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify --- 58 unchanged lines hidden (view full) --- 67 struct platform_device *dock_device; 68}; 69static LIST_HEAD(dock_stations); 70static int dock_station_count; 71static DEFINE_MUTEX(hotplug_lock); 72 73struct dock_dependent_device { 74 struct list_head list; |
75 acpi_handle handle; | 75 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}; 81 82#define DOCK_DOCKING 0x00000001 83#define DOCK_UNDOCKING 0x00000002 --- 9 unchanged lines hidden (view full) --- 93 DOCK_CALL_UEVENT, 94}; 95 96/***************************************************************************** 97 * Dock Dependent device functions * 98 *****************************************************************************/ 99/** 100 * add_dock_dependent_device - associate a device with the dock station | 76 const struct acpi_dock_ops *hp_ops; 77 void *hp_context; 78 unsigned int hp_refcount; 79 void (*hp_release)(void *); 80}; 81 82#define DOCK_DOCKING 0x00000001 83#define DOCK_UNDOCKING 0x00000002 --- 9 unchanged lines hidden (view full) --- 93 DOCK_CALL_UEVENT, 94}; 95 96/***************************************************************************** 97 * Dock Dependent device functions * 98 *****************************************************************************/ 99/** 100 * add_dock_dependent_device - associate a device with the dock station |
101 * @ds: The dock station 102 * @handle: handle of the dependent device | 101 * @ds: Dock station. 102 * @adev: Dependent ACPI device object. |
103 * 104 * Add the dependent device to the dock's dependent device list. 105 */ | 103 * 104 * Add the dependent device to the dock's dependent device list. 105 */ |
106static int __init 107add_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 106static int add_dock_dependent_device(struct dock_station *ds, 107 struct acpi_device *adev) |
108{ 109 struct dock_dependent_device *dd; 110 111 dd = kzalloc(sizeof(*dd), GFP_KERNEL); 112 if (!dd) 113 return -ENOMEM; 114 | 108{ 109 struct dock_dependent_device *dd; 110 111 dd = kzalloc(sizeof(*dd), GFP_KERNEL); 112 if (!dd) 113 return -ENOMEM; 114 |
115 dd->handle = handle; | 115 dd->adev = adev; |
116 INIT_LIST_HEAD(&dd->list); 117 list_add_tail(&dd->list, &ds->dependent_devices); 118 119 return 0; 120} 121 122static void remove_dock_dependent_devices(struct dock_station *ds) 123{ --- 84 unchanged lines hidden (view full) --- 208 } 209 210 mutex_unlock(&hotplug_lock); 211 212 if (!run) 213 return; 214 215 if (cb) | 116 INIT_LIST_HEAD(&dd->list); 117 list_add_tail(&dd->list, &ds->dependent_devices); 118 119 return 0; 120} 121 122static void remove_dock_dependent_devices(struct dock_station *ds) 123{ --- 84 unchanged lines hidden (view full) --- 208 } 209 210 mutex_unlock(&hotplug_lock); 211 212 if (!run) 213 return; 214 215 if (cb) |
216 cb(dd->handle, event, dd->hp_context); | 216 cb(dd->adev->handle, event, dd->hp_context); |
217 218 dock_release_hotplug(dd); 219} 220 | 217 218 dock_release_hotplug(dd); 219} 220 |
221static struct dock_station *find_dock_station(acpi_handle handle) 222{ 223 struct dock_station *ds; 224 225 list_for_each_entry(ds, &dock_stations, sibling) 226 if (ds->handle == handle) 227 return ds; 228 229 return NULL; 230} 231 |
|
221/** 222 * find_dock_dependent_device - get a device dependent on this dock 223 * @ds: the dock station | 232/** 233 * find_dock_dependent_device - get a device dependent on this dock 234 * @ds: the dock station |
224 * @handle: the acpi_handle of the device we want | 235 * @adev: ACPI device object to find. |
225 * 226 * iterate over the dependent device list for this dock. If the 227 * dependent device matches the handle, return. 228 */ 229static struct dock_dependent_device * | 236 * 237 * iterate over the dependent device list for this dock. If the 238 * dependent device matches the handle, return. 239 */ 240static struct dock_dependent_device * |
230find_dock_dependent_device(struct dock_station *ds, acpi_handle handle) | 241find_dock_dependent_device(struct dock_station *ds, struct acpi_device *adev) |
231{ 232 struct dock_dependent_device *dd; 233 234 list_for_each_entry(dd, &ds->dependent_devices, list) | 242{ 243 struct dock_dependent_device *dd; 244 245 list_for_each_entry(dd, &ds->dependent_devices, list) |
235 if (handle == dd->handle) | 246 if (adev == dd->adev) |
236 return dd; 237 238 return NULL; 239} 240 | 247 return dd; 248 249 return NULL; 250} 251 |
241/***************************************************************************** 242 * Dock functions * 243 *****************************************************************************/ 244static int __init is_battery(acpi_handle handle) | 252void register_dock_dependent_device(struct acpi_device *adev, 253 acpi_handle dshandle) |
245{ | 254{ |
246 struct acpi_device_info *info; 247 int ret = 1; | 255 struct dock_station *ds = find_dock_station(dshandle); |
248 | 256 |
249 if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) 250 return 0; 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; | 257 if (ds && !find_dock_dependent_device(ds, adev)) 258 add_dock_dependent_device(ds, adev); |
258} 259 | 259} 260 |
260/* Check whether ACPI object is an ejectable battery or disk bay */ 261static bool __init is_ejectable_bay(acpi_handle handle) 262{ 263 if (acpi_has_method(handle, "_EJ0") && is_battery(handle)) 264 return true; | 261/***************************************************************************** 262 * Dock functions * 263 *****************************************************************************/ |
265 | 264 |
266 return acpi_bay_match(handle); 267} 268 | |
269/** 270 * is_dock_device - see if a device is on a dock station | 265/** 266 * is_dock_device - see if a device is on a dock station |
271 * @handle: acpi handle of the device | 267 * @adev: ACPI device object to check. |
272 * 273 * If this device is either the dock station itself, 274 * or is a device dependent on the dock station, then it 275 * is a dock device 276 */ | 268 * 269 * If this device is either the dock station itself, 270 * or is a device dependent on the dock station, then it 271 * is a dock device 272 */ |
277int is_dock_device(acpi_handle handle) | 273int is_dock_device(struct acpi_device *adev) |
278{ 279 struct dock_station *dock_station; 280 281 if (!dock_station_count) 282 return 0; 283 | 274{ 275 struct dock_station *dock_station; 276 277 if (!dock_station_count) 278 return 0; 279 |
284 if (acpi_dock_match(handle)) | 280 if (acpi_dock_match(adev->handle)) |
285 return 1; 286 287 list_for_each_entry(dock_station, &dock_stations, sibling) | 281 return 1; 282 283 list_for_each_entry(dock_station, &dock_stations, sibling) |
288 if (find_dock_dependent_device(dock_station, handle)) | 284 if (find_dock_dependent_device(dock_station, adev)) |
289 return 1; 290 291 return 0; 292} 293EXPORT_SYMBOL_GPL(is_dock_device); 294 295/** 296 * dock_present - see if the dock station is present. --- 11 unchanged lines hidden (view full) --- 308 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta); 309 if (ACPI_SUCCESS(status) && sta) 310 return 1; 311 } 312 return 0; 313} 314 315/** | 285 return 1; 286 287 return 0; 288} 289EXPORT_SYMBOL_GPL(is_dock_device); 290 291/** 292 * dock_present - see if the dock station is present. --- 11 unchanged lines hidden (view full) --- 304 status = acpi_evaluate_integer(ds->handle, "_STA", NULL, &sta); 305 if (ACPI_SUCCESS(status) && sta) 306 return 1; 307 } 308 return 0; 309} 310 311/** |
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. 354 * @ds: Dock station. 355 */ 356static void hot_remove_dock_devices(struct dock_station *ds) 357{ 358 struct dock_dependent_device *dd; 359 360 /* 361 * Walk the list in reverse order so that devices that have been added 362 * last are removed first (in case there are some indirect dependencies 363 * between them). 364 */ 365 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) 366 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); 367 368 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) | 312 * hot_remove_dock_devices - Remove dock station devices. 313 * @ds: Dock station. 314 */ 315static void hot_remove_dock_devices(struct dock_station *ds) 316{ 317 struct dock_dependent_device *dd; 318 319 /* 320 * Walk the list in reverse order so that devices that have been added 321 * last are removed first (in case there are some indirect dependencies 322 * between them). 323 */ 324 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) 325 dock_hotplug_event(dd, ACPI_NOTIFY_EJECT_REQUEST, false); 326 327 list_for_each_entry_reverse(dd, &ds->dependent_devices, list) |
369 dock_remove_acpi_device(dd->handle); | 328 acpi_bus_trim(dd->adev); |
370} 371 372/** 373 * hotplug_dock_devices - Insert devices on a dock station. 374 * @ds: the dock station 375 * @event: either bus check or device check request 376 * 377 * Some devices on the dock station need to have drivers called --- 9 unchanged lines hidden (view full) --- 387 list_for_each_entry(dd, &ds->dependent_devices, list) 388 dock_hotplug_event(dd, event, DOCK_CALL_FIXUP); 389 390 /* Call driver specific hotplug functions. */ 391 list_for_each_entry(dd, &ds->dependent_devices, list) 392 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); 393 394 /* | 329} 330 331/** 332 * hotplug_dock_devices - Insert devices on a dock station. 333 * @ds: the dock station 334 * @event: either bus check or device check request 335 * 336 * Some devices on the dock station need to have drivers called --- 9 unchanged lines hidden (view full) --- 346 list_for_each_entry(dd, &ds->dependent_devices, list) 347 dock_hotplug_event(dd, event, DOCK_CALL_FIXUP); 348 349 /* Call driver specific hotplug functions. */ 350 list_for_each_entry(dd, &ds->dependent_devices, list) 351 dock_hotplug_event(dd, event, DOCK_CALL_HANDLER); 352 353 /* |
395 * Now make sure that an acpi_device is created for each dependent 396 * device. That will cause scan handlers to be attached to device 397 * objects or acpi_drivers to be stopped/started if they are present. | 354 * Check if all devices have been enumerated already. If not, run 355 * acpi_bus_scan() for them and that will cause scan handlers to be 356 * attached to device objects or acpi_drivers to be stopped/started if 357 * they are present. |
398 */ | 358 */ |
399 list_for_each_entry(dd, &ds->dependent_devices, list) 400 dock_create_acpi_device(dd->handle); | 359 list_for_each_entry(dd, &ds->dependent_devices, list) { 360 struct acpi_device *adev = dd->adev; 361 362 if (!acpi_device_enumerated(adev)) { 363 int ret = acpi_bus_scan(adev->handle); 364 if (ret) 365 dev_dbg(&adev->dev, "scan error %d\n", -ret); 366 } 367 } |
401} 402 403static void dock_event(struct dock_station *ds, u32 event, int num) 404{ 405 struct device *dev = &ds->dock_device->dev; 406 char event_string[13]; 407 char *envp[] = { event_string, NULL }; 408 struct dock_dependent_device *dd; --- 104 unchanged lines hidden (view full) --- 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; | 368} 369 370static void dock_event(struct dock_station *ds, u32 event, int num) 371{ 372 struct device *dev = &ds->dock_device->dev; 373 char event_string[13]; 374 char *envp[] = { event_string, NULL }; 375 struct dock_dependent_device *dd; --- 104 unchanged lines hidden (view full) --- 480 * the dock driver after _DCK is executed. 481 */ 482int register_hotplug_dock_device(acpi_handle handle, 483 const struct acpi_dock_ops *ops, void *context, 484 void (*init)(void *), void (*release)(void *)) 485{ 486 struct dock_dependent_device *dd; 487 struct dock_station *dock_station; |
488 struct acpi_device *adev; |
|
521 int ret = -EINVAL; 522 523 if (WARN_ON(!context)) 524 return -EINVAL; 525 526 if (!dock_station_count) 527 return -ENODEV; 528 | 489 int ret = -EINVAL; 490 491 if (WARN_ON(!context)) 492 return -EINVAL; 493 494 if (!dock_station_count) 495 return -ENODEV; 496 |
497 ret = acpi_bus_get_device(handle, &adev); 498 if (ret) 499 return ret; 500 |
|
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 */ | 501 /* 502 * make sure this handle is for a device dependent on the dock, 503 * this would include the dock station itself 504 */ 505 list_for_each_entry(dock_station, &dock_stations, sibling) { 506 /* 507 * An ATA bay can be in a dock and itself can be ejected 508 * separately, so there are two 'dock stations' which need the 509 * ops 510 */ |
539 dd = find_dock_dependent_device(dock_station, handle); | 511 dd = find_dock_dependent_device(dock_station, adev); |
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; | 512 if (dd && !dock_init_hotplug(dd, ops, context, init, release)) 513 ret = 0; 514 } 515 516 return ret; 517} 518EXPORT_SYMBOL_GPL(register_hotplug_dock_device); 519 520/** 521 * unregister_hotplug_dock_device - remove yourself from the hotplug list 522 * @handle: the acpi handle of the device 523 */ 524void unregister_hotplug_dock_device(acpi_handle handle) 525{ 526 struct dock_dependent_device *dd; 527 struct dock_station *dock_station; |
528 struct acpi_device *adev; |
|
556 557 if (!dock_station_count) 558 return; 559 | 529 530 if (!dock_station_count) 531 return; 532 |
533 if (acpi_bus_get_device(handle, &adev)) 534 return; 535 |
|
560 list_for_each_entry(dock_station, &dock_stations, sibling) { | 536 list_for_each_entry(dock_station, &dock_stations, sibling) { |
561 dd = find_dock_dependent_device(dock_station, handle); | 537 dd = find_dock_dependent_device(dock_station, adev); |
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 --- 23 unchanged lines hidden (view full) --- 593 acpi_handle_err(ds->handle, "Unable to undock!\n"); 594 return -EBUSY; 595 } 596 complete_undock(ds); 597 return 0; 598} 599 600/** | 538 if (dd) 539 dock_release_hotplug(dd); 540 } 541} 542EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device); 543 544/** 545 * handle_eject_request - handle an undock request checking for error conditions --- 23 unchanged lines hidden (view full) --- 569 acpi_handle_err(ds->handle, "Unable to undock!\n"); 570 return -EBUSY; 571 } 572 complete_undock(ds); 573 return 0; 574} 575 576/** |
601 * dock_notify - act upon an acpi dock notification 602 * @ds: dock station 603 * @event: the acpi event | 577 * dock_notify - Handle ACPI dock notification. 578 * @adev: Dock station's ACPI device object. 579 * @event: Event code. |
604 * 605 * 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, 607 * and then hotplug and devices that may need hotplugging. 608 */ | 580 * 581 * If we are notified to dock, then check to see if the dock is 582 * present and then dock. Notify all drivers of the dock event, 583 * and then hotplug and devices that may need hotplugging. 584 */ |
609static void dock_notify(struct dock_station *ds, u32 event) | 585int dock_notify(struct acpi_device *adev, u32 event) |
610{ | 586{ |
611 acpi_handle handle = ds->handle; 612 struct acpi_device *adev = NULL; | 587 acpi_handle handle = adev->handle; 588 struct dock_station *ds = find_dock_station(handle); |
613 int surprise_removal = 0; 614 | 589 int surprise_removal = 0; 590 |
591 if (!ds) 592 return -ENODEV; 593 |
|
615 /* 616 * 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 618 * request. 619 */ 620 if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK) 621 event = ACPI_NOTIFY_EJECT_REQUEST; 622 --- 4 unchanged lines hidden (view full) --- 627 * 628 * To simplify event handling, dock dependent device handler always 629 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and 630 * ACPI_NOTIFY_EJECT_REQUEST for removal 631 */ 632 switch (event) { 633 case ACPI_NOTIFY_BUS_CHECK: 634 case ACPI_NOTIFY_DEVICE_CHECK: | 594 /* 595 * According to acpi spec 3.0a, if a DEVICE_CHECK notification 596 * is sent and _DCK is present, it is assumed to mean an undock 597 * request. 598 */ 599 if ((ds->flags & DOCK_IS_DOCK) && event == ACPI_NOTIFY_DEVICE_CHECK) 600 event = ACPI_NOTIFY_EJECT_REQUEST; 601 --- 4 unchanged lines hidden (view full) --- 606 * 607 * To simplify event handling, dock dependent device handler always 608 * get ACPI_NOTIFY_BUS_CHECK/ACPI_NOTIFY_DEVICE_CHECK for add and 609 * ACPI_NOTIFY_EJECT_REQUEST for removal 610 */ 611 switch (event) { 612 case ACPI_NOTIFY_BUS_CHECK: 613 case ACPI_NOTIFY_DEVICE_CHECK: |
635 acpi_bus_get_device(handle, &adev); | |
636 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) { 637 begin_dock(ds); 638 dock(ds); 639 if (!dock_present(ds)) { 640 acpi_handle_err(handle, "Unable to dock!\n"); 641 complete_dock(ds); 642 break; 643 } --- 13 unchanged lines hidden (view full) --- 657 case ACPI_NOTIFY_EJECT_REQUEST: 658 begin_undock(ds); 659 if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) 660 || surprise_removal) 661 handle_eject_request(ds, event); 662 else 663 dock_event(ds, event, UNDOCK_EVENT); 664 break; | 614 if (!dock_in_progress(ds) && !acpi_device_enumerated(adev)) { 615 begin_dock(ds); 616 dock(ds); 617 if (!dock_present(ds)) { 618 acpi_handle_err(handle, "Unable to dock!\n"); 619 complete_dock(ds); 620 break; 621 } --- 13 unchanged lines hidden (view full) --- 635 case ACPI_NOTIFY_EJECT_REQUEST: 636 begin_undock(ds); 637 if ((immediate_undock && !(ds->flags & DOCK_IS_ATA)) 638 || surprise_removal) 639 handle_eject_request(ds, event); 640 else 641 dock_event(ds, event, UNDOCK_EVENT); 642 break; |
665 default: 666 acpi_handle_err(handle, "Unknown dock event %d\n", event); | |
667 } | 643 } |
644 return 0; |
|
668} 669 | 645} 646 |
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} 709 | |
710/* 711 * show_docked - read method for "docked" file in sysfs 712 */ 713static ssize_t show_docked(struct device *dev, 714 struct device_attribute *attr, char *buf) 715{ | 647/* 648 * show_docked - read method for "docked" file in sysfs 649 */ 650static ssize_t show_docked(struct device *dev, 651 struct device_attribute *attr, char *buf) 652{ |
716 struct acpi_device *tmp; 717 | |
718 struct dock_station *dock_station = dev->platform_data; | 653 struct dock_station *dock_station = dev->platform_data; |
654 struct acpi_device *adev = NULL; |
|
719 | 655 |
720 if (!acpi_bus_get_device(dock_station->handle, &tmp)) 721 return snprintf(buf, PAGE_SIZE, "1\n"); 722 return snprintf(buf, PAGE_SIZE, "0\n"); | 656 acpi_bus_get_device(dock_station->handle, &adev); 657 return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); |
723} 724static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 725 726/* 727 * show_flags - read method for flags file in sysfs 728 */ 729static ssize_t show_flags(struct device *dev, 730 struct device_attribute *attr, char *buf) --- 69 unchanged lines hidden (view full) --- 800 NULL 801}; 802 803static struct attribute_group dock_attribute_group = { 804 .attrs = dock_attributes 805}; 806 807/** | 658} 659static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); 660 661/* 662 * show_flags - read method for flags file in sysfs 663 */ 664static ssize_t show_flags(struct device *dev, 665 struct device_attribute *attr, char *buf) --- 69 unchanged lines hidden (view full) --- 735 NULL 736}; 737 738static struct attribute_group dock_attribute_group = { 739 .attrs = dock_attributes 740}; 741 742/** |
808 * dock_add - add a new dock station 809 * @handle: the dock station handle | 743 * acpi_dock_add - Add a new dock station 744 * @adev: Dock station ACPI device object. |
810 * | 745 * |
811 * allocated and initialize a new dock station device. Find all devices 812 * that are on the dock station, and register for dock event notifications. | 746 * allocated and initialize a new dock station device. |
813 */ | 747 */ |
814static int __init dock_add(acpi_handle handle) | 748void acpi_dock_add(struct acpi_device *adev) |
815{ 816 struct dock_station *dock_station, ds = { NULL, }; | 749{ 750 struct dock_station *dock_station, ds = { NULL, }; |
751 struct platform_device_info pdevinfo; 752 acpi_handle handle = adev->handle; |
|
817 struct platform_device *dd; | 753 struct platform_device *dd; |
818 acpi_status status; | |
819 int ret; 820 | 754 int ret; 755 |
821 dd = platform_device_register_data(NULL, "dock", dock_station_count, 822 &ds, sizeof(ds)); | 756 memset(&pdevinfo, 0, sizeof(pdevinfo)); 757 pdevinfo.name = "dock"; 758 pdevinfo.id = dock_station_count; 759 pdevinfo.acpi_node.companion = adev; 760 pdevinfo.data = &ds; 761 pdevinfo.size_data = sizeof(ds); 762 dd = platform_device_register_full(&pdevinfo); |
823 if (IS_ERR(dd)) | 763 if (IS_ERR(dd)) |
824 return PTR_ERR(dd); | 764 return; |
825 826 dock_station = dd->dev.platform_data; 827 828 dock_station->handle = handle; 829 dock_station->dock_device = dd; 830 dock_station->last_dock_time = jiffies - HZ; 831 832 INIT_LIST_HEAD(&dock_station->sibling); 833 INIT_LIST_HEAD(&dock_station->dependent_devices); 834 835 /* we want the dock device to send uevents */ 836 dev_set_uevent_suppress(&dd->dev, 0); 837 838 if (acpi_dock_match(handle)) 839 dock_station->flags |= DOCK_IS_DOCK; 840 if (acpi_ata_match(handle)) 841 dock_station->flags |= DOCK_IS_ATA; | 765 766 dock_station = dd->dev.platform_data; 767 768 dock_station->handle = handle; 769 dock_station->dock_device = dd; 770 dock_station->last_dock_time = jiffies - HZ; 771 772 INIT_LIST_HEAD(&dock_station->sibling); 773 INIT_LIST_HEAD(&dock_station->dependent_devices); 774 775 /* we want the dock device to send uevents */ 776 dev_set_uevent_suppress(&dd->dev, 0); 777 778 if (acpi_dock_match(handle)) 779 dock_station->flags |= DOCK_IS_DOCK; 780 if (acpi_ata_match(handle)) 781 dock_station->flags |= DOCK_IS_ATA; |
842 if (is_battery(handle)) | 782 if (acpi_device_is_battery(adev)) |
843 dock_station->flags |= DOCK_IS_BAT; 844 845 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); 846 if (ret) 847 goto err_unregister; 848 | 783 dock_station->flags |= DOCK_IS_BAT; 784 785 ret = sysfs_create_group(&dd->dev.kobj, &dock_attribute_group); 786 if (ret) 787 goto err_unregister; 788 |
849 /* Find dependent devices */ 850 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 851 ACPI_UINT32_MAX, find_dock_devices, NULL, 852 dock_station, NULL); 853 | |
854 /* add the dock station as a device dependent on itself */ | 789 /* add the dock station as a device dependent on itself */ |
855 ret = add_dock_dependent_device(dock_station, handle); | 790 ret = add_dock_dependent_device(dock_station, adev); |
856 if (ret) 857 goto err_rmgroup; 858 | 791 if (ret) 792 goto err_rmgroup; 793 |
859 status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, 860 dock_notify_handler, dock_station); 861 if (ACPI_FAILURE(status)) { 862 ret = -ENODEV; 863 goto err_rmgroup; 864 } 865 | |
866 dock_station_count++; 867 list_add(&dock_station->sibling, &dock_stations); | 794 dock_station_count++; 795 list_add(&dock_station->sibling, &dock_stations); |
868 return 0; | 796 adev->flags.is_dock_station = true; 797 dev_info(&adev->dev, "ACPI dock station (docks/bays count: %d)\n", 798 dock_station_count); 799 return; |
869 870err_rmgroup: 871 remove_dock_dependent_devices(dock_station); 872 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); 873err_unregister: 874 platform_device_unregister(dd); 875 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); | 800 801err_rmgroup: 802 remove_dock_dependent_devices(dock_station); 803 sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); 804err_unregister: 805 platform_device_unregister(dd); 806 acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); |
876 return ret; | |
877} | 807} |
878 879/** 880 * find_dock_and_bay - look for dock stations and bays 881 * @handle: acpi handle of a device 882 * @lvl: unused 883 * @context: unused 884 * @rv: unused 885 * 886 * This is called by acpi_walk_namespace to look for dock stations and bays. 887 */ 888static acpi_status __init 889find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) 890{ 891 if (acpi_dock_match(handle) || is_ejectable_bay(handle)) 892 dock_add(handle); 893 894 return AE_OK; 895} 896 897void __init acpi_dock_init(void) 898{ 899 /* look for dock stations and bays */ 900 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 901 ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); 902 903 if (!dock_station_count) { 904 pr_info(PREFIX "No dock devices found.\n"); 905 return; 906 } 907 908 pr_info(PREFIX "%s: %d docks/bays found\n", 909 ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); 910} | |