aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2009-09-21 15:30:06 -0400
committerLen Brown <len.brown@intel.com>2009-09-25 14:24:31 -0400
commit778cbc1d3abd434b6d882714630235e3711bb15b (patch)
tree5a81030166825fabf4a2e81bf9a7f5440133c3d8 /drivers/acpi/scan.c
parent402ac53614bce0c273c73a80339556bf56dd3d39 (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>
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c129
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
1253static int acpi_add_single_object(struct acpi_device **child, 1253static 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
1396static 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
1360static 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
1399static 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