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.c130
1 files changed, 103 insertions, 27 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7c26fed0bdf0..cbcda30c172d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -65,14 +65,14 @@ static ssize_t acpi_device_attr_show(struct kobject *kobj,
65{ 65{
66 struct acpi_device *device = to_acpi_device(kobj); 66 struct acpi_device *device = to_acpi_device(kobj);
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 67 struct acpi_device_attribute *attribute = to_handle_attr(attr);
68 return attribute->show ? attribute->show(device, buf) : 0; 68 return attribute->show ? attribute->show(device, buf) : -EIO;
69} 69}
70static ssize_t acpi_device_attr_store(struct kobject *kobj, 70static ssize_t acpi_device_attr_store(struct kobject *kobj,
71 struct attribute *attr, const char *buf, size_t len) 71 struct attribute *attr, const char *buf, size_t len)
72{ 72{
73 struct acpi_device *device = to_acpi_device(kobj); 73 struct acpi_device *device = to_acpi_device(kobj);
74 struct acpi_device_attribute *attribute = to_handle_attr(attr); 74 struct acpi_device_attribute *attribute = to_handle_attr(attr);
75 return attribute->store ? attribute->store(device, buf, len) : len; 75 return attribute->store ? attribute->store(device, buf, len) : -EIO;
76} 76}
77 77
78static struct sysfs_ops acpi_device_sysfs_ops = { 78static struct sysfs_ops acpi_device_sysfs_ops = {
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
553 * upon possible configuration and currently allocated resources. 553 * upon possible configuration and currently allocated resources.
554 */ 554 */
555 555
556 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
557 return_VALUE(0);
558}
559
560int
561acpi_start_single_object (
562 struct acpi_device *device)
563{
564 int result = 0;
565 struct acpi_driver *driver;
566
567 ACPI_FUNCTION_TRACE("acpi_start_single_object");
568
569 if (!(driver = device->driver))
570 return_VALUE(0);
571
556 if (driver->ops.start) { 572 if (driver->ops.start) {
557 result = driver->ops.start(device); 573 result = driver->ops.start(device);
558 if (result && driver->ops.remove) 574 if (result && driver->ops.remove)
559 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); 575 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
560 return_VALUE(result);
561 } 576 }
562 577
563 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); 578 return_VALUE(result);
564
565 if (driver->ops.scan) {
566 driver->ops.scan(device);
567 }
568
569 return_VALUE(0);
570} 579}
571 580
572static int acpi_driver_attach(struct acpi_driver * drv) 581static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv)
586 595
587 if (!acpi_bus_match(dev, drv)) { 596 if (!acpi_bus_match(dev, drv)) {
588 if (!acpi_bus_driver_init(dev, drv)) { 597 if (!acpi_bus_driver_init(dev, drv)) {
598 acpi_start_single_object(dev);
589 atomic_inc(&drv->references); 599 atomic_inc(&drv->references);
590 count++; 600 count++;
591 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", 601 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
1009} 1019}
1010 1020
1011 1021
1012int 1022static int
1013acpi_bus_add ( 1023acpi_add_single_object (
1014 struct acpi_device **child, 1024 struct acpi_device **child,
1015 struct acpi_device *parent, 1025 struct acpi_device *parent,
1016 acpi_handle handle, 1026 acpi_handle handle,
@@ -1019,7 +1029,7 @@ acpi_bus_add (
1019 int result = 0; 1029 int result = 0;
1020 struct acpi_device *device = NULL; 1030 struct acpi_device *device = NULL;
1021 1031
1022 ACPI_FUNCTION_TRACE("acpi_bus_add"); 1032 ACPI_FUNCTION_TRACE("acpi_add_single_object");
1023 1033
1024 if (!child) 1034 if (!child)
1025 return_VALUE(-EINVAL); 1035 return_VALUE(-EINVAL);
@@ -1142,7 +1152,7 @@ acpi_bus_add (
1142 * 1152 *
1143 * TBD: Assumes LDM provides driver hot-plug capability. 1153 * TBD: Assumes LDM provides driver hot-plug capability.
1144 */ 1154 */
1145 acpi_bus_find_driver(device); 1155 result = acpi_bus_find_driver(device);
1146 1156
1147end: 1157end:
1148 if (!result) 1158 if (!result)
@@ -1155,10 +1165,10 @@ end:
1155 1165
1156 return_VALUE(result); 1166 return_VALUE(result);
1157} 1167}
1158EXPORT_SYMBOL(acpi_bus_add);
1159 1168
1160 1169
1161int acpi_bus_scan (struct acpi_device *start) 1170static int acpi_bus_scan (struct acpi_device *start,
1171 struct acpi_bus_ops *ops)
1162{ 1172{
1163 acpi_status status = AE_OK; 1173 acpi_status status = AE_OK;
1164 struct acpi_device *parent = NULL; 1174 struct acpi_device *parent = NULL;
@@ -1231,9 +1241,20 @@ int acpi_bus_scan (struct acpi_device *start)
1231 continue; 1241 continue;
1232 } 1242 }
1233 1243
1234 status = acpi_bus_add(&child, parent, chandle, type); 1244 if (ops->acpi_op_add)
1235 if (ACPI_FAILURE(status)) 1245 status = acpi_add_single_object(&child, parent,
1236 continue; 1246 chandle, type);
1247 else
1248 status = acpi_bus_get_device(chandle, &child);
1249
1250 if (ACPI_FAILURE(status))
1251 continue;
1252
1253 if (ops->acpi_op_start) {
1254 status = acpi_start_single_object(child);
1255 if (ACPI_FAILURE(status))
1256 continue;
1257 }
1237 1258
1238 /* 1259 /*
1239 * If the device is present, enabled, and functioning then 1260 * If the device is present, enabled, and functioning then
@@ -1259,8 +1280,50 @@ int acpi_bus_scan (struct acpi_device *start)
1259 1280
1260 return_VALUE(0); 1281 return_VALUE(0);
1261} 1282}
1262EXPORT_SYMBOL(acpi_bus_scan);
1263 1283
1284int
1285acpi_bus_add (
1286 struct acpi_device **child,
1287 struct acpi_device *parent,
1288 acpi_handle handle,
1289 int type)
1290{
1291 int result;
1292 struct acpi_bus_ops ops;
1293
1294 ACPI_FUNCTION_TRACE("acpi_bus_add");
1295
1296 result = acpi_add_single_object(child, parent, handle, type);
1297 if (!result) {
1298 memset(&ops, 0, sizeof(ops));
1299 ops.acpi_op_add = 1;
1300 result = acpi_bus_scan(*child, &ops);
1301 }
1302 return_VALUE(result);
1303}
1304EXPORT_SYMBOL(acpi_bus_add);
1305
1306int
1307acpi_bus_start (
1308 struct acpi_device *device)
1309{
1310 int result;
1311 struct acpi_bus_ops ops;
1312
1313 ACPI_FUNCTION_TRACE("acpi_bus_start");
1314
1315 if (!device)
1316 return_VALUE(-EINVAL);
1317
1318 result = acpi_start_single_object(device);
1319 if (!result) {
1320 memset(&ops, 0, sizeof(ops));
1321 ops.acpi_op_start = 1;
1322 result = acpi_bus_scan(device, &ops);
1323 }
1324 return_VALUE(result);
1325}
1326EXPORT_SYMBOL(acpi_bus_start);
1264 1327
1265static int 1328static int
1266acpi_bus_trim(struct acpi_device *start, 1329acpi_bus_trim(struct acpi_device *start,
@@ -1333,13 +1396,19 @@ acpi_bus_scan_fixed (
1333 /* 1396 /*
1334 * Enumerate all fixed-feature devices. 1397 * Enumerate all fixed-feature devices.
1335 */ 1398 */
1336 if (acpi_fadt.pwr_button == 0) 1399 if (acpi_fadt.pwr_button == 0) {
1337 result = acpi_bus_add(&device, acpi_root, 1400 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, ACPI_BUS_TYPE_POWER_BUTTON); 1401 NULL, ACPI_BUS_TYPE_POWER_BUTTON);
1402 if (!result)
1403 result = acpi_start_single_object(device);
1404 }
1339 1405
1340 if (acpi_fadt.sleep_button == 0) 1406 if (acpi_fadt.sleep_button == 0) {
1341 result = acpi_bus_add(&device, acpi_root, 1407 result = acpi_add_single_object(&device, acpi_root,
1342 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); 1408 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
1409 if (!result)
1410 result = acpi_start_single_object(device);
1411 }
1343 1412
1344 return_VALUE(result); 1413 return_VALUE(result);
1345} 1414}
@@ -1348,6 +1417,7 @@ acpi_bus_scan_fixed (
1348static int __init acpi_scan_init(void) 1417static int __init acpi_scan_init(void)
1349{ 1418{
1350 int result; 1419 int result;
1420 struct acpi_bus_ops ops;
1351 1421
1352 ACPI_FUNCTION_TRACE("acpi_scan_init"); 1422 ACPI_FUNCTION_TRACE("acpi_scan_init");
1353 1423
@@ -1359,17 +1429,23 @@ static int __init acpi_scan_init(void)
1359 /* 1429 /*
1360 * Create the root device in the bus's device tree 1430 * Create the root device in the bus's device tree
1361 */ 1431 */
1362 result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1432 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1363 ACPI_BUS_TYPE_SYSTEM); 1433 ACPI_BUS_TYPE_SYSTEM);
1364 if (result) 1434 if (result)
1365 goto Done; 1435 goto Done;
1366 1436
1437 result = acpi_start_single_object(acpi_root);
1438
1367 /* 1439 /*
1368 * Enumerate devices in the ACPI namespace. 1440 * Enumerate devices in the ACPI namespace.
1369 */ 1441 */
1370 result = acpi_bus_scan_fixed(acpi_root); 1442 result = acpi_bus_scan_fixed(acpi_root);
1371 if (!result) 1443 if (!result) {
1372 result = acpi_bus_scan(acpi_root); 1444 memset(&ops, 0, sizeof(ops));
1445 ops.acpi_op_add = 1;
1446 ops.acpi_op_start = 1;
1447 result = acpi_bus_scan(acpi_root, &ops);
1448 }
1373 1449
1374 if (result) 1450 if (result)
1375 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1451 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);