diff options
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 120 |
1 files changed, 48 insertions, 72 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f6f52c1a2aba..39b7233c3485 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -109,20 +109,19 @@ static int acpi_bus_hot_remove_device(void *context) | |||
109 | return 0; | 109 | return 0; |
110 | 110 | ||
111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 111 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
112 | "Hot-removing device %s...\n", device->dev.bus_id)); | 112 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
113 | |||
114 | 113 | ||
115 | if (acpi_bus_trim(device, 1)) { | 114 | if (acpi_bus_trim(device, 1)) { |
116 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 115 | printk(KERN_ERR PREFIX |
117 | "Removing device failed\n")); | 116 | "Removing device failed\n"); |
118 | return -1; | 117 | return -1; |
119 | } | 118 | } |
120 | 119 | ||
121 | /* power off device */ | 120 | /* power off device */ |
122 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); | 121 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); |
123 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 122 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
124 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 123 | printk(KERN_WARNING PREFIX |
125 | "Power-off device failed\n")); | 124 | "Power-off device failed\n"); |
126 | 125 | ||
127 | if (device->flags.lockable) { | 126 | if (device->flags.lockable) { |
128 | arg_list.count = 1; | 127 | arg_list.count = 1; |
@@ -276,6 +275,13 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
276 | { | 275 | { |
277 | const struct acpi_device_id *id; | 276 | const struct acpi_device_id *id; |
278 | 277 | ||
278 | /* | ||
279 | * If the device is not present, it is unnecessary to load device | ||
280 | * driver for it. | ||
281 | */ | ||
282 | if (!device->status.present) | ||
283 | return -ENODEV; | ||
284 | |||
279 | if (device->flags.hardware_id) { | 285 | if (device->flags.hardware_id) { |
280 | for (id = ids; id->id[0]; id++) { | 286 | for (id = ids; id->id[0]; id++) { |
281 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) | 287 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) |
@@ -384,7 +390,7 @@ static int acpi_device_remove(struct device * dev) | |||
384 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 390 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
385 | } | 391 | } |
386 | acpi_dev->driver = NULL; | 392 | acpi_dev->driver = NULL; |
387 | acpi_driver_data(dev) = NULL; | 393 | acpi_dev->driver_data = NULL; |
388 | 394 | ||
389 | put_device(dev); | 395 | put_device(dev); |
390 | return 0; | 396 | return 0; |
@@ -453,7 +459,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
453 | acpi_device_bus_id->instance_no = 0; | 459 | acpi_device_bus_id->instance_no = 0; |
454 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); | 460 | list_add_tail(&acpi_device_bus_id->node, &acpi_bus_id_list); |
455 | } | 461 | } |
456 | sprintf(device->dev.bus_id, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); | 462 | dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no); |
457 | 463 | ||
458 | if (device->parent) { | 464 | if (device->parent) { |
459 | list_add_tail(&device->node, &device->parent->children); | 465 | list_add_tail(&device->node, &device->parent->children); |
@@ -477,7 +483,8 @@ static int acpi_device_register(struct acpi_device *device, | |||
477 | 483 | ||
478 | result = acpi_device_setup_files(device); | 484 | result = acpi_device_setup_files(device); |
479 | if(result) | 485 | if(result) |
480 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id)); | 486 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", |
487 | dev_name(&device->dev)); | ||
481 | 488 | ||
482 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; | 489 | device->removal_type = ACPI_BUS_REMOVAL_NORMAL; |
483 | return 0; | 490 | return 0; |
@@ -537,7 +544,7 @@ acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver) | |||
537 | result = driver->ops.add(device); | 544 | result = driver->ops.add(device); |
538 | if (result) { | 545 | if (result) { |
539 | device->driver = NULL; | 546 | device->driver = NULL; |
540 | acpi_driver_data(device) = NULL; | 547 | device->driver_data = NULL; |
541 | return result; | 548 | return result; |
542 | } | 549 | } |
543 | 550 | ||
@@ -807,6 +814,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
807 | /* TBD: System wake support and resource requirements. */ | 814 | /* TBD: System wake support and resource requirements. */ |
808 | 815 | ||
809 | device->power.state = ACPI_STATE_UNKNOWN; | 816 | device->power.state = ACPI_STATE_UNKNOWN; |
817 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
810 | 818 | ||
811 | return 0; | 819 | return 0; |
812 | } | 820 | } |
@@ -901,36 +909,6 @@ static void acpi_device_get_busid(struct acpi_device *device, | |||
901 | } | 909 | } |
902 | } | 910 | } |
903 | 911 | ||
904 | static int | ||
905 | acpi_video_bus_match(struct acpi_device *device) | ||
906 | { | ||
907 | acpi_handle h_dummy; | ||
908 | |||
909 | if (!device) | ||
910 | return -EINVAL; | ||
911 | |||
912 | /* Since there is no HID, CID for ACPI Video drivers, we have | ||
913 | * to check well known required nodes for each feature we support. | ||
914 | */ | ||
915 | |||
916 | /* Does this device able to support video switching ? */ | ||
917 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && | ||
918 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
919 | return 0; | ||
920 | |||
921 | /* Does this device able to retrieve a video ROM ? */ | ||
922 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | ||
923 | return 0; | ||
924 | |||
925 | /* Does this device able to configure which video head to be POSTed ? */ | ||
926 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_VPO", &h_dummy)) && | ||
927 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_GPD", &h_dummy)) && | ||
928 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_SPD", &h_dummy))) | ||
929 | return 0; | ||
930 | |||
931 | return -ENODEV; | ||
932 | } | ||
933 | |||
934 | /* | 912 | /* |
935 | * acpi_bay_match - see if a device is an ejectable driver bay | 913 | * acpi_bay_match - see if a device is an ejectable driver bay |
936 | * | 914 | * |
@@ -1013,7 +991,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1013 | will get autoloaded and the device might still match | 991 | will get autoloaded and the device might still match |
1014 | against another driver. | 992 | against another driver. |
1015 | */ | 993 | */ |
1016 | if (ACPI_SUCCESS(acpi_video_bus_match(device))) | 994 | if (acpi_is_video_device(device)) |
1017 | cid_add = ACPI_VIDEO_HID; | 995 | cid_add = ACPI_VIDEO_HID; |
1018 | else if (ACPI_SUCCESS(acpi_bay_match(device))) | 996 | else if (ACPI_SUCCESS(acpi_bay_match(device))) |
1019 | cid_add = ACPI_BAY_HID; | 997 | cid_add = ACPI_BAY_HID; |
@@ -1025,7 +1003,7 @@ static void acpi_device_set_id(struct acpi_device *device, | |||
1025 | hid = ACPI_POWER_HID; | 1003 | hid = ACPI_POWER_HID; |
1026 | break; | 1004 | break; |
1027 | case ACPI_BUS_TYPE_PROCESSOR: | 1005 | case ACPI_BUS_TYPE_PROCESSOR: |
1028 | hid = ACPI_PROCESSOR_HID; | 1006 | hid = ACPI_PROCESSOR_OBJECT_HID; |
1029 | break; | 1007 | break; |
1030 | case ACPI_BUS_TYPE_SYSTEM: | 1008 | case ACPI_BUS_TYPE_SYSTEM: |
1031 | hid = ACPI_SYSTEM_HID; | 1009 | hid = ACPI_SYSTEM_HID; |
@@ -1153,20 +1131,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
1153 | } | 1131 | } |
1154 | 1132 | ||
1155 | static int | 1133 | static int |
1156 | acpi_is_child_device(struct acpi_device *device, | ||
1157 | int (*matcher)(struct acpi_device *)) | ||
1158 | { | ||
1159 | int result = -ENODEV; | ||
1160 | |||
1161 | do { | ||
1162 | if (ACPI_SUCCESS(matcher(device))) | ||
1163 | return AE_OK; | ||
1164 | } while ((device = device->parent)); | ||
1165 | |||
1166 | return result; | ||
1167 | } | ||
1168 | |||
1169 | static int | ||
1170 | acpi_add_single_object(struct acpi_device **child, | 1134 | acpi_add_single_object(struct acpi_device **child, |
1171 | struct acpi_device *parent, acpi_handle handle, int type, | 1135 | struct acpi_device *parent, acpi_handle handle, int type, |
1172 | struct acpi_bus_ops *ops) | 1136 | struct acpi_bus_ops *ops) |
@@ -1221,15 +1185,18 @@ acpi_add_single_object(struct acpi_device **child, | |||
1221 | result = -ENODEV; | 1185 | result = -ENODEV; |
1222 | goto end; | 1186 | goto end; |
1223 | } | 1187 | } |
1224 | if (!device->status.present) { | 1188 | /* |
1225 | /* Bay and dock should be handled even if absent */ | 1189 | * When the device is neither present nor functional, the |
1226 | if (!ACPI_SUCCESS( | 1190 | * device should not be added to Linux ACPI device tree. |
1227 | acpi_is_child_device(device, acpi_bay_match)) && | 1191 | * When the status of the device is not present but functinal, |
1228 | !ACPI_SUCCESS( | 1192 | * it should be added to Linux ACPI tree. For example : bay |
1229 | acpi_is_child_device(device, acpi_dock_match))) { | 1193 | * device , dock device. |
1230 | result = -ENODEV; | 1194 | * In such conditions it is unncessary to check whether it is |
1231 | goto end; | 1195 | * bay device or dock device. |
1232 | } | 1196 | */ |
1197 | if (!device->status.present && !device->status.functional) { | ||
1198 | result = -ENODEV; | ||
1199 | goto end; | ||
1233 | } | 1200 | } |
1234 | break; | 1201 | break; |
1235 | default: | 1202 | default: |
@@ -1252,6 +1219,16 @@ acpi_add_single_object(struct acpi_device **child, | |||
1252 | acpi_device_set_id(device, parent, handle, type); | 1219 | acpi_device_set_id(device, parent, handle, type); |
1253 | 1220 | ||
1254 | /* | 1221 | /* |
1222 | * The ACPI device is attached to acpi handle before getting | ||
1223 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1224 | * the corresponding ACPI device by the acpi handle in the course | ||
1225 | * of getting the power/wakeup/performance flags. | ||
1226 | */ | ||
1227 | result = acpi_device_set_context(device, type); | ||
1228 | if (result) | ||
1229 | goto end; | ||
1230 | |||
1231 | /* | ||
1255 | * Power Management | 1232 | * Power Management |
1256 | * ---------------- | 1233 | * ---------------- |
1257 | */ | 1234 | */ |
@@ -1281,8 +1258,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1281 | goto end; | 1258 | goto end; |
1282 | } | 1259 | } |
1283 | 1260 | ||
1284 | if ((result = acpi_device_set_context(device, type))) | ||
1285 | goto end; | ||
1286 | 1261 | ||
1287 | result = acpi_device_register(device, parent); | 1262 | result = acpi_device_register(device, parent); |
1288 | 1263 | ||
@@ -1402,7 +1377,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) | |||
1402 | * TBD: Need notifications and other detection mechanisms | 1377 | * TBD: Need notifications and other detection mechanisms |
1403 | * in place before we can fully implement this. | 1378 | * in place before we can fully implement this. |
1404 | */ | 1379 | */ |
1405 | if (child->status.present) { | 1380 | /* |
1381 | * When the device is not present but functional, it is also | ||
1382 | * necessary to scan the children of this device. | ||
1383 | */ | ||
1384 | if (child->status.present || (!child->status.present && | ||
1385 | child->status.functional)) { | ||
1406 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, | 1386 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, |
1407 | NULL, NULL); | 1387 | NULL, NULL); |
1408 | if (ACPI_SUCCESS(status)) { | 1388 | if (ACPI_SUCCESS(status)) { |
@@ -1545,7 +1525,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1545 | return result; | 1525 | return result; |
1546 | } | 1526 | } |
1547 | 1527 | ||
1548 | int __init acpi_boot_ec_enable(void); | ||
1549 | 1528 | ||
1550 | static int __init acpi_scan_init(void) | 1529 | static int __init acpi_scan_init(void) |
1551 | { | 1530 | { |
@@ -1579,9 +1558,6 @@ static int __init acpi_scan_init(void) | |||
1579 | */ | 1558 | */ |
1580 | result = acpi_bus_scan_fixed(acpi_root); | 1559 | result = acpi_bus_scan_fixed(acpi_root); |
1581 | 1560 | ||
1582 | /* EC region might be needed at bus_scan, so enable it now */ | ||
1583 | acpi_boot_ec_enable(); | ||
1584 | |||
1585 | if (!result) | 1561 | if (!result) |
1586 | result = acpi_bus_scan(acpi_root, &ops); | 1562 | result = acpi_bus_scan(acpi_root, &ops); |
1587 | 1563 | ||