aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/container.c2
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/scan.c126
-rw-r--r--include/acpi/acpi_bus.h17
4 files changed, 119 insertions, 28 deletions
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 5a0adbf8bc04..97013ddfa202 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
153 return_VALUE(-ENODEV); 153 return_VALUE(-ENODEV);
154 } 154 }
155 155
156 result = acpi_bus_scan(*device); 156 result = acpi_bus_start(*device);
157 157
158 return_VALUE(result); 158 return_VALUE(result);
159} 159}
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index f4778747e889..76156ac91bd3 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -723,7 +723,7 @@ int acpi_processor_device_add(
723 return_VALUE(-ENODEV); 723 return_VALUE(-ENODEV);
724 } 724 }
725 725
726 acpi_bus_scan(*device); 726 acpi_bus_start(*device);
727 727
728 pr = acpi_driver_data(*device); 728 pr = acpi_driver_data(*device);
729 if (!pr) 729 if (!pr)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e85885593280..337d49b5564b 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -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);
@@ -1140,7 +1150,7 @@ acpi_bus_add (
1140 * 1150 *
1141 * TBD: Assumes LDM provides driver hot-plug capability. 1151 * TBD: Assumes LDM provides driver hot-plug capability.
1142 */ 1152 */
1143 acpi_bus_find_driver(device); 1153 result = acpi_bus_find_driver(device);
1144 1154
1145end: 1155end:
1146 if (!result) 1156 if (!result)
@@ -1153,10 +1163,10 @@ end:
1153 1163
1154 return_VALUE(result); 1164 return_VALUE(result);
1155} 1165}
1156EXPORT_SYMBOL(acpi_bus_add);
1157 1166
1158 1167
1159int acpi_bus_scan (struct acpi_device *start) 1168static int acpi_bus_scan (struct acpi_device *start,
1169 struct acpi_bus_ops *ops)
1160{ 1170{
1161 acpi_status status = AE_OK; 1171 acpi_status status = AE_OK;
1162 struct acpi_device *parent = NULL; 1172 struct acpi_device *parent = NULL;
@@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start)
1229 continue; 1239 continue;
1230 } 1240 }
1231 1241
1232 status = acpi_bus_add(&child, parent, chandle, type); 1242 if (ops->acpi_op_add)
1233 if (ACPI_FAILURE(status)) 1243 status = acpi_add_single_object(&child, parent,
1234 continue; 1244 chandle, type);
1245 else
1246 status = acpi_bus_get_device(chandle, &child);
1247
1248 if (ACPI_FAILURE(status))
1249 continue;
1250
1251 if (ops->acpi_op_start) {
1252 status = acpi_start_single_object(child);
1253 if (ACPI_FAILURE(status))
1254 continue;
1255 }
1235 1256
1236 /* 1257 /*
1237 * If the device is present, enabled, and functioning then 1258 * If the device is present, enabled, and functioning then
@@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start)
1257 1278
1258 return_VALUE(0); 1279 return_VALUE(0);
1259} 1280}
1260EXPORT_SYMBOL(acpi_bus_scan);
1261 1281
1282int
1283acpi_bus_add (
1284 struct acpi_device **child,
1285 struct acpi_device *parent,
1286 acpi_handle handle,
1287 int type)
1288{
1289 int result;
1290 struct acpi_bus_ops ops;
1291
1292 ACPI_FUNCTION_TRACE("acpi_bus_add");
1293
1294 result = acpi_add_single_object(child, parent, handle, type);
1295 if (!result) {
1296 memset(&ops, 0, sizeof(ops));
1297 ops.acpi_op_add = 1;
1298 result = acpi_bus_scan(*child, &ops);
1299 }
1300 return_VALUE(result);
1301}
1302EXPORT_SYMBOL(acpi_bus_add);
1303
1304int
1305acpi_bus_start (
1306 struct acpi_device *device)
1307{
1308 int result;
1309 struct acpi_bus_ops ops;
1310
1311 ACPI_FUNCTION_TRACE("acpi_bus_start");
1312
1313 if (!device)
1314 return_VALUE(-EINVAL);
1315
1316 result = acpi_start_single_object(device);
1317 if (!result) {
1318 memset(&ops, 0, sizeof(ops));
1319 ops.acpi_op_start = 1;
1320 result = acpi_bus_scan(device, &ops);
1321 }
1322 return_VALUE(result);
1323}
1324EXPORT_SYMBOL(acpi_bus_start);
1262 1325
1263static int 1326static int
1264acpi_bus_trim(struct acpi_device *start, 1327acpi_bus_trim(struct acpi_device *start,
@@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed (
1331 /* 1394 /*
1332 * Enumerate all fixed-feature devices. 1395 * Enumerate all fixed-feature devices.
1333 */ 1396 */
1334 if (acpi_fadt.pwr_button == 0) 1397 if (acpi_fadt.pwr_button == 0) {
1335 result = acpi_bus_add(&device, acpi_root, 1398 result = acpi_add_single_object(&device, acpi_root,
1336 NULL, ACPI_BUS_TYPE_POWER_BUTTON); 1399 NULL, ACPI_BUS_TYPE_POWER_BUTTON);
1400 if (!result)
1401 result = acpi_start_single_object(device);
1402 }
1337 1403
1338 if (acpi_fadt.sleep_button == 0) 1404 if (acpi_fadt.sleep_button == 0) {
1339 result = acpi_bus_add(&device, acpi_root, 1405 result = acpi_add_single_object(&device, acpi_root,
1340 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); 1406 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
1407 if (!result)
1408 result = acpi_start_single_object(device);
1409 }
1341 1410
1342 return_VALUE(result); 1411 return_VALUE(result);
1343} 1412}
@@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed (
1346static int __init acpi_scan_init(void) 1415static int __init acpi_scan_init(void)
1347{ 1416{
1348 int result; 1417 int result;
1418 struct acpi_bus_ops ops;
1349 1419
1350 ACPI_FUNCTION_TRACE("acpi_scan_init"); 1420 ACPI_FUNCTION_TRACE("acpi_scan_init");
1351 1421
@@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void)
1357 /* 1427 /*
1358 * Create the root device in the bus's device tree 1428 * Create the root device in the bus's device tree
1359 */ 1429 */
1360 result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1430 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1361 ACPI_BUS_TYPE_SYSTEM); 1431 ACPI_BUS_TYPE_SYSTEM);
1362 if (result) 1432 if (result)
1363 goto Done; 1433 goto Done;
1364 1434
1435 result = acpi_start_single_object(acpi_root);
1436
1365 /* 1437 /*
1366 * Enumerate devices in the ACPI namespace. 1438 * Enumerate devices in the ACPI namespace.
1367 */ 1439 */
1368 result = acpi_bus_scan_fixed(acpi_root); 1440 result = acpi_bus_scan_fixed(acpi_root);
1369 if (!result) 1441 if (!result) {
1370 result = acpi_bus_scan(acpi_root); 1442 memset(&ops, 0, sizeof(ops));
1443 ops.acpi_op_add = 1;
1444 ops.acpi_op_start = 1;
1445 result = acpi_bus_scan(acpi_root, &ops);
1446 }
1371 1447
1372 if (result) 1448 if (result)
1373 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1449 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index c627bc408a6b..9ad142476f33 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device);
108typedef int (*acpi_op_match) (struct acpi_device *device, 108typedef int (*acpi_op_match) (struct acpi_device *device,
109 struct acpi_driver *driver); 109 struct acpi_driver *driver);
110 110
111struct acpi_bus_ops {
112 u32 acpi_op_add:1;
113 u32 acpi_op_remove:1;
114 u32 acpi_op_lock:1;
115 u32 acpi_op_start:1;
116 u32 acpi_op_stop:1;
117 u32 acpi_op_suspend:1;
118 u32 acpi_op_resume:1;
119 u32 acpi_op_scan:1;
120 u32 acpi_op_bind:1;
121 u32 acpi_op_unbind:1;
122 u32 acpi_op_match:1;
123 u32 reserved:21;
124};
125
111struct acpi_device_ops { 126struct acpi_device_ops {
112 acpi_op_add add; 127 acpi_op_add add;
113 acpi_op_remove remove; 128 acpi_op_remove remove;
@@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data);
327int acpi_bus_receive_event (struct acpi_bus_event *event); 342int acpi_bus_receive_event (struct acpi_bus_event *event);
328int acpi_bus_register_driver (struct acpi_driver *driver); 343int acpi_bus_register_driver (struct acpi_driver *driver);
329int acpi_bus_unregister_driver (struct acpi_driver *driver); 344int acpi_bus_unregister_driver (struct acpi_driver *driver);
330int acpi_bus_scan (struct acpi_device *start);
331int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent, 345int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent,
332 acpi_handle handle, int type); 346 acpi_handle handle, int type);
347int acpi_bus_start (struct acpi_device *device);
333 348
334 349
335int acpi_match_ids (struct acpi_device *device, char *ids); 350int acpi_match_ids (struct acpi_device *device, char *ids);