aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@linux.intel.com>2006-12-07 07:56:31 -0500
committerLen Brown <len.brown@intel.com>2006-12-15 23:38:34 -0500
commit1890a97ab3f66d1e99768439f8067608b9b97fe3 (patch)
treeae9cc1f49e51e1fad5305caceac72b7f1dc584af /drivers/acpi
parent5d9464a46918ced087c351a10f38cee95725f85b (diff)
ACPI: change registration interface to follow driver model
ACPI device/driver registration Interfaces are modified to follow Linux driver model. Signed-off-by: Li Shaohua <shaohua.li@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/scan.c175
1 files changed, 29 insertions, 146 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 464746257d8e..b616e17de522 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -25,7 +25,7 @@ DEFINE_SPINLOCK(acpi_device_lock);
25LIST_HEAD(acpi_wakeup_device_list); 25LIST_HEAD(acpi_wakeup_device_list);
26 26
27 27
28static void acpi_device_release(struct kobject *kobj) 28static void acpi_device_release_legacy(struct kobject *kobj)
29{ 29{
30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj); 30 struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
31 kfree(dev->pnp.cid_list); 31 kfree(dev->pnp.cid_list);
@@ -75,7 +75,7 @@ static struct sysfs_ops acpi_device_sysfs_ops = {
75 75
76static struct kobj_type ktype_acpi_ns = { 76static struct kobj_type ktype_acpi_ns = {
77 .sysfs_ops = &acpi_device_sysfs_ops, 77 .sysfs_ops = &acpi_device_sysfs_ops,
78 .release = acpi_device_release, 78 .release = acpi_device_release_legacy,
79}; 79};
80 80
81static int namespace_uevent(struct kset *kset, struct kobject *kobj, 81static int namespace_uevent(struct kset *kset, struct kobject *kobj,
@@ -222,6 +222,14 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
222/* -------------------------------------------------------------------------- 222/* --------------------------------------------------------------------------
223 ACPI Bus operations 223 ACPI Bus operations
224 -------------------------------------------------------------------------- */ 224 -------------------------------------------------------------------------- */
225static void acpi_device_release(struct device *dev)
226{
227 struct acpi_device *acpi_dev = to_acpi_device(dev);
228
229 kfree(acpi_dev->pnp.cid_list);
230 kfree(acpi_dev);
231}
232
225static int acpi_device_suspend(struct device *dev, pm_message_t state) 233static int acpi_device_suspend(struct device *dev, pm_message_t state)
226{ 234{
227 struct acpi_device *acpi_dev = to_acpi_device(dev); 235 struct acpi_device *acpi_dev = to_acpi_device(dev);
@@ -377,6 +385,14 @@ static void acpi_device_register(struct acpi_device *device,
377 printk(KERN_WARNING "%s: kobject_register error: %d\n", 385 printk(KERN_WARNING "%s: kobject_register error: %d\n",
378 __FUNCTION__, err); 386 __FUNCTION__, err);
379 create_sysfs_device_files(device); 387 create_sysfs_device_files(device);
388
389 if (device->parent)
390 device->dev.parent = &parent->dev;
391 device->dev.bus = &acpi_bus_type;
392 device_initialize(&device->dev);
393 sprintf(device->dev.bus_id, "%s", device->pnp.bus_id);
394 device->dev.release = &acpi_device_release;
395 device_add(&device->dev);
380} 396}
381 397
382static void acpi_device_unregister(struct acpi_device *device, int type) 398static void acpi_device_unregister(struct acpi_device *device, int type)
@@ -395,20 +411,20 @@ static void acpi_device_unregister(struct acpi_device *device, int type)
395 acpi_detach_data(device->handle, acpi_bus_data_handler); 411 acpi_detach_data(device->handle, acpi_bus_data_handler);
396 remove_sysfs_device_files(device); 412 remove_sysfs_device_files(device);
397 kobject_unregister(&device->kobj); 413 kobject_unregister(&device->kobj);
414
415 device_unregister(&device->dev);
398} 416}
399 417
400/* -------------------------------------------------------------------------- 418/* --------------------------------------------------------------------------
401 Driver Management 419 Driver Management
402 -------------------------------------------------------------------------- */ 420 -------------------------------------------------------------------------- */
403static LIST_HEAD(acpi_bus_drivers);
404
405/** 421/**
406 * acpi_bus_driver_init - add a device to a driver 422 * acpi_bus_driver_init - add a device to a driver
407 * @device: the device to add and initialize 423 * @device: the device to add and initialize
408 * @driver: driver for the device 424 * @driver: driver for the device
409 * 425 *
410 * Used to initialize a device via its device driver. Called whenever a 426 * Used to initialize a device via its device driver. Called whenever a
411 * driver is bound to a device. Invokes the driver's add() and start() ops. 427 * driver is bound to a device. Invokes the driver's add() ops.
412 */ 428 */
413static int 429static int
414acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) 430acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
@@ -459,57 +475,6 @@ static int acpi_start_single_object(struct acpi_device *device)
459 return result; 475 return result;
460} 476}
461 477
462static void acpi_driver_attach(struct acpi_driver *drv)
463{
464 struct list_head *node, *next;
465
466
467 spin_lock(&acpi_device_lock);
468 list_for_each_safe(node, next, &acpi_device_list) {
469 struct acpi_device *dev =
470 container_of(node, struct acpi_device, g_list);
471
472 if (dev->driver || !dev->status.present)
473 continue;
474 spin_unlock(&acpi_device_lock);
475
476 if (!acpi_bus_match(&(dev->dev), &(drv->drv))) {
477 if (!acpi_bus_driver_init(dev, drv)) {
478 acpi_start_single_object(dev);
479 atomic_inc(&drv->references);
480 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
481 "Found driver [%s] for device [%s]\n",
482 drv->name, dev->pnp.bus_id));
483 }
484 }
485 spin_lock(&acpi_device_lock);
486 }
487 spin_unlock(&acpi_device_lock);
488}
489
490static void acpi_driver_detach(struct acpi_driver *drv)
491{
492 struct list_head *node, *next;
493
494
495 spin_lock(&acpi_device_lock);
496 list_for_each_safe(node, next, &acpi_device_list) {
497 struct acpi_device *dev =
498 container_of(node, struct acpi_device, g_list);
499
500 if (dev->driver == drv) {
501 spin_unlock(&acpi_device_lock);
502 if (drv->ops.remove)
503 drv->ops.remove(dev, ACPI_BUS_REMOVAL_NORMAL);
504 spin_lock(&acpi_device_lock);
505 dev->driver = NULL;
506 dev->driver_data = NULL;
507 atomic_dec(&drv->references);
508 }
509 }
510 spin_unlock(&acpi_device_lock);
511}
512
513/** 478/**
514 * acpi_bus_register_driver - register a driver with the ACPI bus 479 * acpi_bus_register_driver - register a driver with the ACPI bus
515 * @driver: driver being registered 480 * @driver: driver being registered
@@ -520,16 +485,16 @@ static void acpi_driver_detach(struct acpi_driver *drv)
520 */ 485 */
521int acpi_bus_register_driver(struct acpi_driver *driver) 486int acpi_bus_register_driver(struct acpi_driver *driver)
522{ 487{
488 int ret;
523 489
524 if (acpi_disabled) 490 if (acpi_disabled)
525 return -ENODEV; 491 return -ENODEV;
492 driver->drv.name = driver->name;
493 driver->drv.bus = &acpi_bus_type;
494 driver->drv.owner = driver->owner;
526 495
527 spin_lock(&acpi_device_lock); 496 ret = driver_register(&driver->drv);
528 list_add_tail(&driver->node, &acpi_bus_drivers); 497 return ret;
529 spin_unlock(&acpi_device_lock);
530 acpi_driver_attach(driver);
531
532 return 0;
533} 498}
534 499
535EXPORT_SYMBOL(acpi_bus_register_driver); 500EXPORT_SYMBOL(acpi_bus_register_driver);
@@ -543,52 +508,11 @@ EXPORT_SYMBOL(acpi_bus_register_driver);
543 */ 508 */
544void acpi_bus_unregister_driver(struct acpi_driver *driver) 509void acpi_bus_unregister_driver(struct acpi_driver *driver)
545{ 510{
546 acpi_driver_detach(driver); 511 driver_unregister(&driver->drv);
547
548 if (!atomic_read(&driver->references)) {
549 spin_lock(&acpi_device_lock);
550 list_del_init(&driver->node);
551 spin_unlock(&acpi_device_lock);
552 }
553 return;
554} 512}
555 513
556EXPORT_SYMBOL(acpi_bus_unregister_driver); 514EXPORT_SYMBOL(acpi_bus_unregister_driver);
557 515
558/**
559 * acpi_bus_find_driver - check if there is a driver installed for the device
560 * @device: device that we are trying to find a supporting driver for
561 *
562 * Parses the list of registered drivers looking for a driver applicable for
563 * the specified device.
564 */
565static int acpi_bus_find_driver(struct acpi_device *device)
566{
567 int result = 0;
568 struct list_head *node, *next;
569
570
571 spin_lock(&acpi_device_lock);
572 list_for_each_safe(node, next, &acpi_bus_drivers) {
573 struct acpi_driver *driver =
574 container_of(node, struct acpi_driver, node);
575
576 atomic_inc(&driver->references);
577 spin_unlock(&acpi_device_lock);
578 if (!acpi_bus_match(&(device->dev), &(driver->drv))) {
579 result = acpi_bus_driver_init(device, driver);
580 if (!result)
581 goto Done;
582 }
583 atomic_dec(&driver->references);
584 spin_lock(&acpi_device_lock);
585 }
586 spin_unlock(&acpi_device_lock);
587
588 Done:
589 return result;
590}
591
592/* -------------------------------------------------------------------------- 516/* --------------------------------------------------------------------------
593 Device Enumeration 517 Device Enumeration
594 -------------------------------------------------------------------------- */ 518 -------------------------------------------------------------------------- */
@@ -1033,32 +957,10 @@ static void acpi_device_get_debug_info(struct acpi_device *device,
1033 957
1034static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) 958static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
1035{ 959{
1036 int result = 0;
1037 struct acpi_driver *driver;
1038
1039
1040 if (!dev) 960 if (!dev)
1041 return -EINVAL; 961 return -EINVAL;
1042 962
1043 driver = dev->driver; 963 device_release_driver(&dev->dev);
1044
1045 if ((driver) && (driver->ops.remove)) {
1046
1047 if (driver->ops.stop) {
1048 result = driver->ops.stop(dev, ACPI_BUS_REMOVAL_EJECT);
1049 if (result)
1050 return result;
1051 }
1052
1053 result = dev->driver->ops.remove(dev, ACPI_BUS_REMOVAL_EJECT);
1054 if (result) {
1055 return result;
1056 }
1057
1058 atomic_dec(&dev->driver->references);
1059 dev->driver = NULL;
1060 acpi_driver_data(dev) = NULL;
1061 }
1062 964
1063 if (!rmdevice) 965 if (!rmdevice)
1064 return 0; 966 return 0;
@@ -1193,17 +1095,6 @@ acpi_add_single_object(struct acpi_device **child,
1193 device->parent->ops.bind(device); 1095 device->parent->ops.bind(device);
1194 } 1096 }
1195 1097
1196 /*
1197 * Locate & Attach Driver
1198 * ----------------------
1199 * If there's a hardware id (_HID) or compatible ids (_CID) we check
1200 * to see if there's a driver installed for this kind of device. Note
1201 * that drivers can install before or after a device is enumerated.
1202 *
1203 * TBD: Assumes LDM provides driver hot-plug capability.
1204 */
1205 acpi_bus_find_driver(device);
1206
1207 end: 1098 end:
1208 if (!result) 1099 if (!result)
1209 *child = device; 1100 *child = device;
@@ -1484,14 +1375,6 @@ static int __init acpi_scan_init(void)
1484 if (result) 1375 if (result)
1485 goto Done; 1376 goto Done;
1486 1377
1487 acpi_root->dev.bus = &acpi_bus_type;
1488 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1489 result = device_register(&acpi_root->dev);
1490 if (result) {
1491 /* We don't want to quit even if we failed to add suspend/resume */
1492 printk(KERN_ERR PREFIX "Could not register device\n");
1493 }
1494
1495 /* 1378 /*
1496 * Enumerate devices in the ACPI namespace. 1379 * Enumerate devices in the ACPI namespace.
1497 */ 1380 */