diff options
author | Bjorn Helgaas <bjorn.helgaas@hp.com> | 2009-09-21 15:30:06 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2009-09-25 14:24:31 -0400 |
commit | 778cbc1d3abd434b6d882714630235e3711bb15b (patch) | |
tree | 5a81030166825fabf4a2e81bf9a7f5440133c3d8 | |
parent | 402ac53614bce0c273c73a80339556bf56dd3d39 (diff) |
ACPI: factor out device type and status checking
This patch adds acpi_bus_type_and_status(), which determines the type
of the object and whether we want to build an acpi_device for it. If
it is acpi_device-worthy, it returns the type and the device's current
status.
Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/scan.c | 129 |
1 files changed, 52 insertions, 77 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ed2b5f9a9815..954bd01f295a 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -1252,6 +1252,7 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
1252 | 1252 | ||
1253 | static int acpi_add_single_object(struct acpi_device **child, | 1253 | static int acpi_add_single_object(struct acpi_device **child, |
1254 | acpi_handle handle, int type, | 1254 | acpi_handle handle, int type, |
1255 | unsigned long long sta, | ||
1255 | struct acpi_bus_ops *ops) | 1256 | struct acpi_bus_ops *ops) |
1256 | { | 1257 | { |
1257 | int result; | 1258 | int result; |
@@ -1268,61 +1269,21 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1268 | device->handle = handle; | 1269 | device->handle = handle; |
1269 | device->parent = acpi_bus_get_parent(handle); | 1270 | device->parent = acpi_bus_get_parent(handle); |
1270 | device->bus_ops = *ops; /* workround for not call .start */ | 1271 | device->bus_ops = *ops; /* workround for not call .start */ |
1272 | STRUCT_TO_INT(device->status) = sta; | ||
1271 | 1273 | ||
1272 | acpi_device_get_busid(device); | 1274 | acpi_device_get_busid(device); |
1273 | 1275 | ||
1274 | /* | 1276 | /* |
1275 | * Flags | 1277 | * Flags |
1276 | * ----- | 1278 | * ----- |
1277 | * Get prior to calling acpi_bus_get_status() so we know whether | 1279 | * Note that we only look for object handles -- cannot evaluate objects |
1278 | * or not _STA is present. Note that we only look for object | 1280 | * until we know the device is present and properly initialized. |
1279 | * handles -- cannot evaluate objects until we know the device is | ||
1280 | * present and properly initialized. | ||
1281 | */ | 1281 | */ |
1282 | result = acpi_bus_get_flags(device); | 1282 | result = acpi_bus_get_flags(device); |
1283 | if (result) | 1283 | if (result) |
1284 | goto end; | 1284 | goto end; |
1285 | 1285 | ||
1286 | /* | 1286 | /* |
1287 | * Status | ||
1288 | * ------ | ||
1289 | * See if the device is present. We always assume that non-Device | ||
1290 | * and non-Processor objects (e.g. thermal zones, power resources, | ||
1291 | * etc.) are present, functioning, etc. (at least when parent object | ||
1292 | * is present). Note that _STA has a different meaning for some | ||
1293 | * objects (e.g. power resources) so we need to be careful how we use | ||
1294 | * it. | ||
1295 | */ | ||
1296 | switch (type) { | ||
1297 | case ACPI_BUS_TYPE_PROCESSOR: | ||
1298 | case ACPI_BUS_TYPE_DEVICE: | ||
1299 | result = acpi_bus_get_status(device); | ||
1300 | if (ACPI_FAILURE(result)) { | ||
1301 | result = -ENODEV; | ||
1302 | goto end; | ||
1303 | } | ||
1304 | /* | ||
1305 | * When the device is neither present nor functional, the | ||
1306 | * device should not be added to Linux ACPI device tree. | ||
1307 | * When the status of the device is not present but functinal, | ||
1308 | * it should be added to Linux ACPI tree. For example : bay | ||
1309 | * device , dock device. | ||
1310 | * In such conditions it is unncessary to check whether it is | ||
1311 | * bay device or dock device. | ||
1312 | */ | ||
1313 | if (!device->status.present && !device->status.functional) { | ||
1314 | result = -ENODEV; | ||
1315 | goto end; | ||
1316 | } | ||
1317 | break; | ||
1318 | default: | ||
1319 | STRUCT_TO_INT(device->status) = | ||
1320 | ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | | ||
1321 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; | ||
1322 | break; | ||
1323 | } | ||
1324 | |||
1325 | /* | ||
1326 | * Initialize Device | 1287 | * Initialize Device |
1327 | * ----------------- | 1288 | * ----------------- |
1328 | * TBD: Synch with Core's enumeration/initialization process. | 1289 | * TBD: Synch with Core's enumeration/initialization process. |
@@ -1393,41 +1354,69 @@ end: | |||
1393 | return result; | 1354 | return result; |
1394 | } | 1355 | } |
1395 | 1356 | ||
1396 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | 1357 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ |
1397 | void *context, void **return_value) | 1358 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) |
1359 | |||
1360 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | ||
1361 | unsigned long long *sta) | ||
1398 | { | 1362 | { |
1399 | acpi_status status = AE_OK; | 1363 | acpi_status status; |
1400 | struct acpi_device *device = NULL; | 1364 | acpi_object_type acpi_type; |
1401 | acpi_object_type type = 0; | ||
1402 | struct acpi_bus_ops *ops = context; | ||
1403 | 1365 | ||
1404 | status = acpi_get_type(handle, &type); | 1366 | status = acpi_get_type(handle, &acpi_type); |
1405 | if (ACPI_FAILURE(status)) | 1367 | if (ACPI_FAILURE(status)) |
1406 | return AE_OK; | 1368 | return -ENODEV; |
1407 | 1369 | ||
1408 | /* | 1370 | switch (acpi_type) { |
1409 | * We're only interested in objects that we consider 'devices'. | ||
1410 | */ | ||
1411 | switch (type) { | ||
1412 | case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ | 1371 | case ACPI_TYPE_ANY: /* for ACPI_ROOT_OBJECT */ |
1413 | case ACPI_TYPE_DEVICE: | 1372 | case ACPI_TYPE_DEVICE: |
1414 | type = ACPI_BUS_TYPE_DEVICE; | 1373 | *type = ACPI_BUS_TYPE_DEVICE; |
1374 | status = acpi_bus_get_status_handle(handle, sta); | ||
1375 | if (ACPI_FAILURE(status)) | ||
1376 | return -ENODEV; | ||
1415 | break; | 1377 | break; |
1416 | case ACPI_TYPE_PROCESSOR: | 1378 | case ACPI_TYPE_PROCESSOR: |
1417 | type = ACPI_BUS_TYPE_PROCESSOR; | 1379 | *type = ACPI_BUS_TYPE_PROCESSOR; |
1380 | status = acpi_bus_get_status_handle(handle, sta); | ||
1381 | if (ACPI_FAILURE(status)) | ||
1382 | return -ENODEV; | ||
1418 | break; | 1383 | break; |
1419 | case ACPI_TYPE_THERMAL: | 1384 | case ACPI_TYPE_THERMAL: |
1420 | type = ACPI_BUS_TYPE_THERMAL; | 1385 | *type = ACPI_BUS_TYPE_THERMAL; |
1386 | *sta = ACPI_STA_DEFAULT; | ||
1421 | break; | 1387 | break; |
1422 | case ACPI_TYPE_POWER: | 1388 | case ACPI_TYPE_POWER: |
1423 | type = ACPI_BUS_TYPE_POWER; | 1389 | *type = ACPI_BUS_TYPE_POWER; |
1390 | *sta = ACPI_STA_DEFAULT; | ||
1424 | break; | 1391 | break; |
1425 | default: | 1392 | default: |
1426 | return AE_OK; | 1393 | return -ENODEV; |
1427 | } | 1394 | } |
1428 | 1395 | ||
1396 | return 0; | ||
1397 | } | ||
1398 | |||
1399 | static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | ||
1400 | void *context, void **return_value) | ||
1401 | { | ||
1402 | struct acpi_bus_ops *ops = context; | ||
1403 | struct acpi_device *device = NULL; | ||
1404 | acpi_status status; | ||
1405 | int type; | ||
1406 | unsigned long long sta; | ||
1407 | int result; | ||
1408 | |||
1409 | result = acpi_bus_type_and_status(handle, &type, &sta); | ||
1410 | if (result) | ||
1411 | return AE_OK; | ||
1412 | |||
1413 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | ||
1414 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) | ||
1415 | return AE_CTRL_DEPTH; | ||
1416 | |||
1429 | if (ops->acpi_op_add) | 1417 | if (ops->acpi_op_add) |
1430 | status = acpi_add_single_object(&device, handle, type, ops); | 1418 | status = acpi_add_single_object(&device, handle, type, sta, |
1419 | ops); | ||
1431 | else | 1420 | else |
1432 | status = acpi_bus_get_device(handle, &device); | 1421 | status = acpi_bus_get_device(handle, &device); |
1433 | 1422 | ||
@@ -1440,22 +1429,6 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1440 | return AE_CTRL_DEPTH; | 1429 | return AE_CTRL_DEPTH; |
1441 | } | 1430 | } |
1442 | 1431 | ||
1443 | /* | ||
1444 | * If the device is present, enabled, and functioning then | ||
1445 | * parse its scope (depth-first). Note that we need to | ||
1446 | * represent absent devices to facilitate PnP notifications | ||
1447 | * -- but only the subtree head (not all of its children, | ||
1448 | * which will be enumerated when the parent is inserted). | ||
1449 | * | ||
1450 | * TBD: Need notifications and other detection mechanisms | ||
1451 | * in place before we can fully implement this. | ||
1452 | * | ||
1453 | * When the device is not present but functional, it is also | ||
1454 | * necessary to scan the children of this device. | ||
1455 | */ | ||
1456 | if (!device->status.present && !device->status.functional) | ||
1457 | return AE_CTRL_DEPTH; | ||
1458 | |||
1459 | if (!*return_value) | 1432 | if (!*return_value) |
1460 | *return_value = device; | 1433 | *return_value = device; |
1461 | return AE_OK; | 1434 | return AE_OK; |
@@ -1579,12 +1552,14 @@ static int acpi_bus_scan_fixed(void) | |||
1579 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { | 1552 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { |
1580 | result = acpi_add_single_object(&device, NULL, | 1553 | result = acpi_add_single_object(&device, NULL, |
1581 | ACPI_BUS_TYPE_POWER_BUTTON, | 1554 | ACPI_BUS_TYPE_POWER_BUTTON, |
1555 | ACPI_STA_DEFAULT, | ||
1582 | &ops); | 1556 | &ops); |
1583 | } | 1557 | } |
1584 | 1558 | ||
1585 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { | 1559 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { |
1586 | result = acpi_add_single_object(&device, NULL, | 1560 | result = acpi_add_single_object(&device, NULL, |
1587 | ACPI_BUS_TYPE_SLEEP_BUTTON, | 1561 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
1562 | ACPI_STA_DEFAULT, | ||
1588 | &ops); | 1563 | &ops); |
1589 | } | 1564 | } |
1590 | 1565 | ||