aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c178
1 files changed, 129 insertions, 49 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index a0ab828b2cc5..f8316a05ede7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -142,7 +142,7 @@ static void acpi_device_register(struct acpi_device *device,
142 create_sysfs_device_files(device); 142 create_sysfs_device_files(device);
143} 143}
144 144
145static int acpi_device_unregister(struct acpi_device *device, int type) 145static void acpi_device_unregister(struct acpi_device *device, int type)
146{ 146{
147 spin_lock(&acpi_device_lock); 147 spin_lock(&acpi_device_lock);
148 if (device->parent) { 148 if (device->parent) {
@@ -158,7 +158,6 @@ static int acpi_device_unregister(struct acpi_device *device, int type)
158 acpi_detach_data(device->handle, acpi_bus_data_handler); 158 acpi_detach_data(device->handle, acpi_bus_data_handler);
159 remove_sysfs_device_files(device); 159 remove_sysfs_device_files(device);
160 kobject_unregister(&device->kobj); 160 kobject_unregister(&device->kobj);
161 return 0;
162} 161}
163 162
164void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) 163void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context)
@@ -234,12 +233,9 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
234 233
235int acpi_match_ids(struct acpi_device *device, char *ids) 234int acpi_match_ids(struct acpi_device *device, char *ids)
236{ 235{
237 int error = 0;
238 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
239
240 if (device->flags.hardware_id) 236 if (device->flags.hardware_id)
241 if (strstr(ids, device->pnp.hardware_id)) 237 if (strstr(ids, device->pnp.hardware_id))
242 goto Done; 238 return 0;
243 239
244 if (device->flags.compatible_ids) { 240 if (device->flags.compatible_ids) {
245 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; 241 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
@@ -248,15 +244,10 @@ int acpi_match_ids(struct acpi_device *device, char *ids)
248 /* compare multiple _CID entries against driver ids */ 244 /* compare multiple _CID entries against driver ids */
249 for (i = 0; i < cid_list->count; i++) { 245 for (i = 0; i < cid_list->count; i++) {
250 if (strstr(ids, cid_list->id[i].value)) 246 if (strstr(ids, cid_list->id[i].value))
251 goto Done; 247 return 0;
252 } 248 }
253 } 249 }
254 error = -ENOENT; 250 return -ENOENT;
255
256 Done:
257 if (buffer.pointer)
258 acpi_os_free(buffer.pointer);
259 return error;
260} 251}
261 252
262static acpi_status 253static acpi_status
@@ -441,10 +432,7 @@ acpi_eject_store(struct acpi_device *device, const char *buf, size_t count)
441 islockable = device->flags.lockable; 432 islockable = device->flags.lockable;
442 handle = device->handle; 433 handle = device->handle;
443 434
444 if (type == ACPI_TYPE_PROCESSOR) 435 result = acpi_bus_trim(device, 1);
445 result = acpi_bus_trim(device, 0);
446 else
447 result = acpi_bus_trim(device, 1);
448 436
449 if (!result) 437 if (!result)
450 result = acpi_eject_operation(handle, islockable); 438 result = acpi_eject_operation(handle, islockable);
@@ -471,7 +459,6 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device)
471 -------------------------------------------------------------------------- */ 459 -------------------------------------------------------------------------- */
472 460
473static LIST_HEAD(acpi_bus_drivers); 461static LIST_HEAD(acpi_bus_drivers);
474static DECLARE_MUTEX(acpi_bus_drivers_lock);
475 462
476/** 463/**
477 * acpi_bus_match - match device IDs to driver's supported IDs 464 * acpi_bus_match - match device IDs to driver's supported IDs
@@ -548,10 +535,9 @@ static int acpi_start_single_object(struct acpi_device *device)
548 return_VALUE(result); 535 return_VALUE(result);
549} 536}
550 537
551static int acpi_driver_attach(struct acpi_driver *drv) 538static void acpi_driver_attach(struct acpi_driver *drv)
552{ 539{
553 struct list_head *node, *next; 540 struct list_head *node, *next;
554 int count = 0;
555 541
556 ACPI_FUNCTION_TRACE("acpi_driver_attach"); 542 ACPI_FUNCTION_TRACE("acpi_driver_attach");
557 543
@@ -568,7 +554,6 @@ static int acpi_driver_attach(struct acpi_driver *drv)
568 if (!acpi_bus_driver_init(dev, drv)) { 554 if (!acpi_bus_driver_init(dev, drv)) {
569 acpi_start_single_object(dev); 555 acpi_start_single_object(dev);
570 atomic_inc(&drv->references); 556 atomic_inc(&drv->references);
571 count++;
572 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 557 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
573 "Found driver [%s] for device [%s]\n", 558 "Found driver [%s] for device [%s]\n",
574 drv->name, dev->pnp.bus_id)); 559 drv->name, dev->pnp.bus_id));
@@ -577,10 +562,9 @@ static int acpi_driver_attach(struct acpi_driver *drv)
577 spin_lock(&acpi_device_lock); 562 spin_lock(&acpi_device_lock);
578 } 563 }
579 spin_unlock(&acpi_device_lock); 564 spin_unlock(&acpi_device_lock);
580 return_VALUE(count);
581} 565}
582 566
583static int acpi_driver_detach(struct acpi_driver *drv) 567static void acpi_driver_detach(struct acpi_driver *drv)
584{ 568{
585 struct list_head *node, *next; 569 struct list_head *node, *next;
586 570
@@ -602,7 +586,6 @@ static int acpi_driver_detach(struct acpi_driver *drv)
602 } 586 }
603 } 587 }
604 spin_unlock(&acpi_device_lock); 588 spin_unlock(&acpi_device_lock);
605 return_VALUE(0);
606} 589}
607 590
608/** 591/**
@@ -610,28 +593,22 @@ static int acpi_driver_detach(struct acpi_driver *drv)
610 * @driver: driver being registered 593 * @driver: driver being registered
611 * 594 *
612 * Registers a driver with the ACPI bus. Searches the namespace for all 595 * Registers a driver with the ACPI bus. Searches the namespace for all
613 * devices that match the driver's criteria and binds. Returns the 596 * devices that match the driver's criteria and binds. Returns zero for
614 * number of devices that were claimed by the driver, or a negative 597 * success or a negative error status for failure.
615 * error status for failure.
616 */ 598 */
617int acpi_bus_register_driver(struct acpi_driver *driver) 599int acpi_bus_register_driver(struct acpi_driver *driver)
618{ 600{
619 int count;
620
621 ACPI_FUNCTION_TRACE("acpi_bus_register_driver"); 601 ACPI_FUNCTION_TRACE("acpi_bus_register_driver");
622 602
623 if (acpi_disabled) 603 if (acpi_disabled)
624 return_VALUE(-ENODEV); 604 return_VALUE(-ENODEV);
625 605
626 if (!driver)
627 return_VALUE(-EINVAL);
628
629 spin_lock(&acpi_device_lock); 606 spin_lock(&acpi_device_lock);
630 list_add_tail(&driver->node, &acpi_bus_drivers); 607 list_add_tail(&driver->node, &acpi_bus_drivers);
631 spin_unlock(&acpi_device_lock); 608 spin_unlock(&acpi_device_lock);
632 count = acpi_driver_attach(driver); 609 acpi_driver_attach(driver);
633 610
634 return_VALUE(count); 611 return_VALUE(0);
635} 612}
636 613
637EXPORT_SYMBOL(acpi_bus_register_driver); 614EXPORT_SYMBOL(acpi_bus_register_driver);
@@ -643,23 +620,16 @@ EXPORT_SYMBOL(acpi_bus_register_driver);
643 * Unregisters a driver with the ACPI bus. Searches the namespace for all 620 * Unregisters a driver with the ACPI bus. Searches the namespace for all
644 * devices that match the driver's criteria and unbinds. 621 * devices that match the driver's criteria and unbinds.
645 */ 622 */
646int acpi_bus_unregister_driver(struct acpi_driver *driver) 623void acpi_bus_unregister_driver(struct acpi_driver *driver)
647{ 624{
648 int error = 0; 625 acpi_driver_detach(driver);
649 626
650 ACPI_FUNCTION_TRACE("acpi_bus_unregister_driver"); 627 if (!atomic_read(&driver->references)) {
651 628 spin_lock(&acpi_device_lock);
652 if (driver) { 629 list_del_init(&driver->node);
653 acpi_driver_detach(driver); 630 spin_unlock(&acpi_device_lock);
654 631 }
655 if (!atomic_read(&driver->references)) { 632 return;
656 spin_lock(&acpi_device_lock);
657 list_del_init(&driver->node);
658 spin_unlock(&acpi_device_lock);
659 }
660 } else
661 error = -EINVAL;
662 return_VALUE(error);
663} 633}
664 634
665EXPORT_SYMBOL(acpi_bus_unregister_driver); 635EXPORT_SYMBOL(acpi_bus_unregister_driver);
@@ -1371,6 +1341,100 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1371 return_VALUE(result); 1341 return_VALUE(result);
1372} 1342}
1373 1343
1344
1345static inline struct acpi_device * to_acpi_dev(struct device * dev)
1346{
1347 return container_of(dev, struct acpi_device, dev);
1348}
1349
1350
1351static int root_suspend(struct acpi_device * acpi_dev, pm_message_t state)
1352{
1353 struct acpi_device * dev, * next;
1354 int result;
1355
1356 spin_lock(&acpi_device_lock);
1357 list_for_each_entry_safe_reverse(dev, next, &acpi_device_list, g_list) {
1358 if (dev->driver && dev->driver->ops.suspend) {
1359 spin_unlock(&acpi_device_lock);
1360 result = dev->driver->ops.suspend(dev, 0);
1361 if (result) {
1362 printk(KERN_ERR PREFIX "[%s - %s] Suspend failed: %d\n",
1363 acpi_device_name(dev),
1364 acpi_device_bid(dev), result);
1365 }
1366 spin_lock(&acpi_device_lock);
1367 }
1368 }
1369 spin_unlock(&acpi_device_lock);
1370 return 0;
1371}
1372
1373
1374static int acpi_device_suspend(struct device * dev, pm_message_t state)
1375{
1376 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1377
1378 /*
1379 * For now, we should only register 1 generic device -
1380 * the ACPI root device - and from there, we walk the
1381 * tree of ACPI devices to suspend each one using the
1382 * ACPI driver methods.
1383 */
1384 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1385 root_suspend(acpi_dev, state);
1386 return 0;
1387}
1388
1389
1390
1391static int root_resume(struct acpi_device * acpi_dev)
1392{
1393 struct acpi_device * dev, * next;
1394 int result;
1395
1396 spin_lock(&acpi_device_lock);
1397 list_for_each_entry_safe(dev, next, &acpi_device_list, g_list) {
1398 if (dev->driver && dev->driver->ops.resume) {
1399 spin_unlock(&acpi_device_lock);
1400 result = dev->driver->ops.resume(dev, 0);
1401 if (result) {
1402 printk(KERN_ERR PREFIX "[%s - %s] resume failed: %d\n",
1403 acpi_device_name(dev),
1404 acpi_device_bid(dev), result);
1405 }
1406 spin_lock(&acpi_device_lock);
1407 }
1408 }
1409 spin_unlock(&acpi_device_lock);
1410 return 0;
1411}
1412
1413
1414static int acpi_device_resume(struct device * dev)
1415{
1416 struct acpi_device * acpi_dev = to_acpi_dev(dev);
1417
1418 /*
1419 * For now, we should only register 1 generic device -
1420 * the ACPI root device - and from there, we walk the
1421 * tree of ACPI devices to resume each one using the
1422 * ACPI driver methods.
1423 */
1424 if (acpi_dev->handle == ACPI_ROOT_OBJECT)
1425 root_resume(acpi_dev);
1426 return 0;
1427}
1428
1429
1430struct bus_type acpi_bus_type = {
1431 .name = "acpi",
1432 .suspend = acpi_device_suspend,
1433 .resume = acpi_device_resume,
1434};
1435
1436
1437
1374static int __init acpi_scan_init(void) 1438static int __init acpi_scan_init(void)
1375{ 1439{
1376 int result; 1440 int result;
@@ -1383,6 +1447,12 @@ static int __init acpi_scan_init(void)
1383 1447
1384 kset_register(&acpi_namespace_kset); 1448 kset_register(&acpi_namespace_kset);
1385 1449
1450 result = bus_register(&acpi_bus_type);
1451 if (result) {
1452 /* We don't want to quit even if we failed to add suspend/resume */
1453 printk(KERN_ERR PREFIX "Could not register bus type\n");
1454 }
1455
1386 /* 1456 /*
1387 * Create the root device in the bus's device tree 1457 * Create the root device in the bus's device tree
1388 */ 1458 */
@@ -1392,6 +1462,16 @@ static int __init acpi_scan_init(void)
1392 goto Done; 1462 goto Done;
1393 1463
1394 result = acpi_start_single_object(acpi_root); 1464 result = acpi_start_single_object(acpi_root);
1465 if (result)
1466 goto Done;
1467
1468 acpi_root->dev.bus = &acpi_bus_type;
1469 snprintf(acpi_root->dev.bus_id, BUS_ID_SIZE, "%s", acpi_bus_type.name);
1470 result = device_register(&acpi_root->dev);
1471 if (result) {
1472 /* We don't want to quit even if we failed to add suspend/resume */
1473 printk(KERN_ERR PREFIX "Could not register device\n");
1474 }
1395 1475
1396 /* 1476 /*
1397 * Enumerate devices in the ACPI namespace. 1477 * Enumerate devices in the ACPI namespace.