aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-17 08:11:05 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-17 08:11:05 -0500
commitd43e167db44b37bb284dc72fff2c3b61bb155752 (patch)
tree7ae48a798412e10a9531932080489e2a57836989
parentbc9b6407bd6df3ab7189e5622816bbc11ae9d2d8 (diff)
ACPI / scan: More straightforward preparation of ACPI device objects
Simplify the code preparing struct acpi_device objects for registration by removing useless code, moving different pieces of code into the functions they belong to and making a couple of int functions always returning 0 void. This also fixes a possible memory leak in ACPI device registration error code path by making acpi_device_register() detach data from device->handle if device_register() fails and prepares the scanning code for special-casing ACPI power resources (next patch). Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/scan.c178
1 files changed, 61 insertions, 117 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c6d60910e8a8..02629a810c04 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -472,6 +472,7 @@ static void acpi_free_ids(struct acpi_device *device)
472 kfree(id->id); 472 kfree(id->id);
473 kfree(id); 473 kfree(id);
474 } 474 }
475 kfree(device->pnp.unique_id);
475} 476}
476 477
477static void acpi_device_release(struct device *dev) 478static void acpi_device_release(struct device *dev)
@@ -479,7 +480,6 @@ static void acpi_device_release(struct device *dev)
479 struct acpi_device *acpi_dev = to_acpi_device(dev); 480 struct acpi_device *acpi_dev = to_acpi_device(dev);
480 481
481 acpi_free_ids(acpi_dev); 482 acpi_free_ids(acpi_dev);
482 kfree(acpi_dev->pnp.unique_id);
483 kfree(acpi_dev); 483 kfree(acpi_dev);
484} 484}
485 485
@@ -623,6 +623,18 @@ static int acpi_device_register(struct acpi_device *device)
623 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id; 623 struct acpi_device_bus_id *acpi_device_bus_id, *new_bus_id;
624 int found = 0; 624 int found = 0;
625 625
626 if (device->handle) {
627 acpi_status status;
628
629 status = acpi_attach_data(device->handle, acpi_bus_data_handler,
630 device);
631 if (ACPI_FAILURE(status)) {
632 acpi_handle_err(device->handle,
633 "Unable to attach device data\n");
634 return -ENODEV;
635 }
636 }
637
626 /* 638 /*
627 * Linkage 639 * Linkage
628 * ------- 640 * -------
@@ -637,8 +649,9 @@ static int acpi_device_register(struct acpi_device *device)
637 649
638 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); 650 new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
639 if (!new_bus_id) { 651 if (!new_bus_id) {
640 printk(KERN_ERR PREFIX "Memory allocation error\n"); 652 pr_err(PREFIX "Memory allocation error\n");
641 return -ENOMEM; 653 result = -ENOMEM;
654 goto err_detach;
642 } 655 }
643 656
644 mutex_lock(&acpi_device_lock); 657 mutex_lock(&acpi_device_lock);
@@ -677,7 +690,7 @@ static int acpi_device_register(struct acpi_device *device)
677 result = device_register(&device->dev); 690 result = device_register(&device->dev);
678 if (result) { 691 if (result) {
679 dev_err(&device->dev, "Error registering device\n"); 692 dev_err(&device->dev, "Error registering device\n");
680 goto end; 693 goto err;
681 } 694 }
682 695
683 result = acpi_device_setup_files(device); 696 result = acpi_device_setup_files(device);
@@ -687,12 +700,16 @@ static int acpi_device_register(struct acpi_device *device)
687 700
688 device->removal_type = ACPI_BUS_REMOVAL_NORMAL; 701 device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
689 return 0; 702 return 0;
690end: 703
704 err:
691 mutex_lock(&acpi_device_lock); 705 mutex_lock(&acpi_device_lock);
692 if (device->parent) 706 if (device->parent)
693 list_del(&device->node); 707 list_del(&device->node);
694 list_del(&device->wakeup_list); 708 list_del(&device->wakeup_list);
695 mutex_unlock(&acpi_device_lock); 709 mutex_unlock(&acpi_device_lock);
710
711 err_detach:
712 acpi_detach_data(device->handle, acpi_bus_data_handler);
696 return result; 713 return result;
697} 714}
698 715
@@ -857,12 +874,6 @@ void acpi_bus_data_handler(acpi_handle handle, void *context)
857 return; 874 return;
858} 875}
859 876
860static int acpi_bus_get_perf_flags(struct acpi_device *device)
861{
862 device->performance.state = ACPI_STATE_UNKNOWN;
863 return 0;
864}
865
866static acpi_status 877static acpi_status
867acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, 878acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
868 struct acpi_device_wakeup *wakeup) 879 struct acpi_device_wakeup *wakeup)
@@ -1013,12 +1024,25 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
1013 1024
1014static void acpi_bus_add_power_resource(acpi_handle handle); 1025static void acpi_bus_add_power_resource(acpi_handle handle);
1015 1026
1016static int acpi_bus_get_power_flags(struct acpi_device *device) 1027static void acpi_bus_get_power_flags(struct acpi_device *device)
1017{ 1028{
1018 acpi_status status = 0; 1029 acpi_status status = 0;
1019 acpi_handle handle = NULL; 1030 acpi_handle handle = NULL;
1020 u32 i = 0; 1031 u32 i = 0;
1021 1032
1033 /* Power resources cannot be power manageable. */
1034 if (device->device_type == ACPI_BUS_TYPE_POWER)
1035 return;
1036
1037 /* Presence of _PS0|_PR0 indicates 'power manageable' */
1038 status = acpi_get_handle(device->handle, "_PS0", &handle);
1039 if (ACPI_FAILURE(status)) {
1040 status = acpi_get_handle(device->handle, "_PR0", &handle);
1041 if (ACPI_FAILURE(status))
1042 return;
1043 }
1044
1045 device->flags.power_manageable = 1;
1022 1046
1023 /* 1047 /*
1024 * Power Management Flags 1048 * Power Management Flags
@@ -1084,16 +1108,13 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
1084 device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1; 1108 device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
1085 1109
1086 acpi_bus_init_power(device); 1110 acpi_bus_init_power(device);
1087
1088 return 0;
1089} 1111}
1090 1112
1091static int acpi_bus_get_flags(struct acpi_device *device) 1113static void acpi_bus_get_flags(struct acpi_device *device)
1092{ 1114{
1093 acpi_status status = AE_OK; 1115 acpi_status status = AE_OK;
1094 acpi_handle temp = NULL; 1116 acpi_handle temp = NULL;
1095 1117
1096
1097 /* Presence of _STA indicates 'dynamic_status' */ 1118 /* Presence of _STA indicates 'dynamic_status' */
1098 status = acpi_get_handle(device->handle, "_STA", &temp); 1119 status = acpi_get_handle(device->handle, "_STA", &temp);
1099 if (ACPI_SUCCESS(status)) 1120 if (ACPI_SUCCESS(status))
@@ -1113,21 +1134,6 @@ static int acpi_bus_get_flags(struct acpi_device *device)
1113 if (ACPI_SUCCESS(status)) 1134 if (ACPI_SUCCESS(status))
1114 device->flags.ejectable = 1; 1135 device->flags.ejectable = 1;
1115 } 1136 }
1116
1117 /* Power resources cannot be power manageable. */
1118 if (device->device_type == ACPI_BUS_TYPE_POWER)
1119 return 0;
1120
1121 /* Presence of _PS0|_PR0 indicates 'power manageable' */
1122 status = acpi_get_handle(device->handle, "_PS0", &temp);
1123 if (ACPI_FAILURE(status))
1124 status = acpi_get_handle(device->handle, "_PR0", &temp);
1125 if (ACPI_SUCCESS(status))
1126 device->flags.power_manageable = 1;
1127
1128 /* TBD: Performance management */
1129
1130 return 0;
1131} 1137}
1132 1138
1133static void acpi_device_get_busid(struct acpi_device *device) 1139static void acpi_device_get_busid(struct acpi_device *device)
@@ -1352,27 +1358,18 @@ static void acpi_device_set_id(struct acpi_device *device)
1352 } 1358 }
1353} 1359}
1354 1360
1355static int acpi_device_set_context(struct acpi_device *device) 1361static void acpi_init_device_object(struct acpi_device *device,
1362 acpi_handle handle,
1363 int type, unsigned long long sta)
1356{ 1364{
1357 acpi_status status; 1365 INIT_LIST_HEAD(&device->pnp.ids);
1358 1366 device->device_type = type;
1359 /* 1367 device->handle = handle;
1360 * Context 1368 device->parent = acpi_bus_get_parent(handle);
1361 * ------- 1369 STRUCT_TO_INT(device->status) = sta;
1362 * Attach this 'struct acpi_device' to the ACPI object. This makes 1370 acpi_device_get_busid(device);
1363 * resolutions from handle->device very efficient. Fixed hardware 1371 acpi_device_set_id(device);
1364 * devices have no handles, so we skip them. 1372 acpi_bus_get_flags(device);
1365 */
1366 if (!device->handle)
1367 return 0;
1368
1369 status = acpi_attach_data(device->handle,
1370 acpi_bus_data_handler, device);
1371 if (ACPI_SUCCESS(status))
1372 return 0;
1373
1374 printk(KERN_ERR PREFIX "Error attaching device data\n");
1375 return -ENODEV;
1376} 1373}
1377 1374
1378static int acpi_add_single_object(struct acpi_device **child, 1375static int acpi_add_single_object(struct acpi_device **child,
@@ -1389,78 +1386,25 @@ static int acpi_add_single_object(struct acpi_device **child,
1389 return -ENOMEM; 1386 return -ENOMEM;
1390 } 1387 }
1391 1388
1392 INIT_LIST_HEAD(&device->pnp.ids); 1389 acpi_init_device_object(device, handle, type, sta);
1393 device->device_type = type; 1390 acpi_bus_get_power_flags(device);
1394 device->handle = handle;
1395 device->parent = acpi_bus_get_parent(handle);
1396 STRUCT_TO_INT(device->status) = sta;
1397
1398 acpi_device_get_busid(device);
1399
1400 /*
1401 * Flags
1402 * -----
1403 * Note that we only look for object handles -- cannot evaluate objects
1404 * until we know the device is present and properly initialized.
1405 */
1406 result = acpi_bus_get_flags(device);
1407 if (result)
1408 goto end;
1409
1410 /*
1411 * Initialize Device
1412 * -----------------
1413 * TBD: Synch with Core's enumeration/initialization process.
1414 */
1415 acpi_device_set_id(device);
1416
1417 /*
1418 * Power Management
1419 * ----------------
1420 */
1421 if (device->flags.power_manageable) {
1422 result = acpi_bus_get_power_flags(device);
1423 if (result)
1424 goto end;
1425 }
1426
1427 /*
1428 * Wakeup device management
1429 *-----------------------
1430 */
1431 acpi_bus_get_wakeup_device_flags(device); 1391 acpi_bus_get_wakeup_device_flags(device);
1432 1392
1433 /*
1434 * Performance Management
1435 * ----------------------
1436 */
1437 if (device->flags.performance_manageable) {
1438 result = acpi_bus_get_perf_flags(device);
1439 if (result)
1440 goto end;
1441 }
1442
1443 if ((result = acpi_device_set_context(device)))
1444 goto end;
1445
1446 device->flags.match_driver = match_driver; 1393 device->flags.match_driver = match_driver;
1447 result = acpi_device_register(device); 1394 result = acpi_device_register(device);
1448 1395 if (result) {
1449end:
1450 if (!result) {
1451 acpi_power_add_remove_device(device, true);
1452 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1453 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1454 "Adding %s [%s] parent %s\n", dev_name(&device->dev),
1455 (char *) buffer.pointer,
1456 device->parent ? dev_name(&device->parent->dev) :
1457 "(null)"));
1458 kfree(buffer.pointer);
1459 *child = device;
1460 } else
1461 acpi_device_release(&device->dev); 1396 acpi_device_release(&device->dev);
1397 return result;
1398 }
1462 1399
1463 return result; 1400 acpi_power_add_remove_device(device, true);
1401 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1402 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Added %s [%s] parent %s\n",
1403 dev_name(&device->dev), (char *) buffer.pointer,
1404 device->parent ? dev_name(&device->parent->dev) : "(null)"));
1405 kfree(buffer.pointer);
1406 *child = device;
1407 return 0;
1464} 1408}
1465 1409
1466#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ 1410#define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \