diff options
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 90 |
1 files changed, 53 insertions, 37 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index f6f52c1a2aba..a9dda8e0f9f9 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -113,16 +113,16 @@ static int acpi_bus_hot_remove_device(void *context) | |||
113 | 113 | ||
114 | 114 | ||
115 | if (acpi_bus_trim(device, 1)) { | 115 | if (acpi_bus_trim(device, 1)) { |
116 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 116 | printk(KERN_ERR PREFIX |
117 | "Removing device failed\n")); | 117 | "Removing device failed\n"); |
118 | return -1; | 118 | return -1; |
119 | } | 119 | } |
120 | 120 | ||
121 | /* power off device */ | 121 | /* power off device */ |
122 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); | 122 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); |
123 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 123 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
124 | ACPI_DEBUG_PRINT((ACPI_DB_WARN, | 124 | printk(KERN_WARNING PREFIX |
125 | "Power-off device failed\n")); | 125 | "Power-off device failed\n"); |
126 | 126 | ||
127 | if (device->flags.lockable) { | 127 | if (device->flags.lockable) { |
128 | arg_list.count = 1; | 128 | arg_list.count = 1; |
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
276 | { | 276 | { |
277 | const struct acpi_device_id *id; | 277 | const struct acpi_device_id *id; |
278 | 278 | ||
279 | /* | ||
280 | * If the device is not present, it is unnecessary to load device | ||
281 | * driver for it. | ||
282 | */ | ||
283 | if (!device->status.present) | ||
284 | return -ENODEV; | ||
285 | |||
279 | if (device->flags.hardware_id) { | 286 | if (device->flags.hardware_id) { |
280 | for (id = ids; id->id[0]; id++) { | 287 | for (id = ids; id->id[0]; id++) { |
281 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) | 288 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) |
@@ -384,7 +391,7 @@ static int acpi_device_remove(struct device * dev) | |||
384 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 391 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); |
385 | } | 392 | } |
386 | acpi_dev->driver = NULL; | 393 | acpi_dev->driver = NULL; |
387 | acpi_driver_data(dev) = NULL; | 394 | acpi_dev->driver_data = NULL; |
388 | 395 | ||
389 | put_device(dev); | 396 | put_device(dev); |
390 | return 0; | 397 | return 0; |
@@ -477,7 +484,7 @@ static int acpi_device_register(struct acpi_device *device, | |||
477 | 484 | ||
478 | result = acpi_device_setup_files(device); | 485 | result = acpi_device_setup_files(device); |
479 | if(result) | 486 | if(result) |
480 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error creating sysfs interface for device %s\n", device->dev.bus_id)); | 487 | printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n", device->dev.bus_id); |
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 | ||
@@ -744,6 +751,16 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | |||
744 | if (!acpi_match_device_ids(device, button_device_ids)) | 751 | if (!acpi_match_device_ids(device, button_device_ids)) |
745 | device->wakeup.flags.run_wake = 1; | 752 | device->wakeup.flags.run_wake = 1; |
746 | 753 | ||
754 | /* | ||
755 | * Don't set Power button GPE as run_wake | ||
756 | * if Fixed Power button is used | ||
757 | */ | ||
758 | if (!strcmp(device->pnp.hardware_id, "PNP0C0C") && | ||
759 | !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { | ||
760 | device->wakeup.flags.run_wake = 0; | ||
761 | device->wakeup.flags.valid = 0; | ||
762 | } | ||
763 | |||
747 | end: | 764 | end: |
748 | if (ACPI_FAILURE(status)) | 765 | if (ACPI_FAILURE(status)) |
749 | device->flags.wake_capable = 0; | 766 | device->flags.wake_capable = 0; |
@@ -807,6 +824,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
807 | /* TBD: System wake support and resource requirements. */ | 824 | /* TBD: System wake support and resource requirements. */ |
808 | 825 | ||
809 | device->power.state = ACPI_STATE_UNKNOWN; | 826 | device->power.state = ACPI_STATE_UNKNOWN; |
827 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
810 | 828 | ||
811 | return 0; | 829 | return 0; |
812 | } | 830 | } |
@@ -1153,20 +1171,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
1153 | } | 1171 | } |
1154 | 1172 | ||
1155 | static int | 1173 | 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, | 1174 | acpi_add_single_object(struct acpi_device **child, |
1171 | struct acpi_device *parent, acpi_handle handle, int type, | 1175 | struct acpi_device *parent, acpi_handle handle, int type, |
1172 | struct acpi_bus_ops *ops) | 1176 | struct acpi_bus_ops *ops) |
@@ -1221,15 +1225,18 @@ acpi_add_single_object(struct acpi_device **child, | |||
1221 | result = -ENODEV; | 1225 | result = -ENODEV; |
1222 | goto end; | 1226 | goto end; |
1223 | } | 1227 | } |
1224 | if (!device->status.present) { | 1228 | /* |
1225 | /* Bay and dock should be handled even if absent */ | 1229 | * When the device is neither present nor functional, the |
1226 | if (!ACPI_SUCCESS( | 1230 | * device should not be added to Linux ACPI device tree. |
1227 | acpi_is_child_device(device, acpi_bay_match)) && | 1231 | * When the status of the device is not present but functinal, |
1228 | !ACPI_SUCCESS( | 1232 | * it should be added to Linux ACPI tree. For example : bay |
1229 | acpi_is_child_device(device, acpi_dock_match))) { | 1233 | * device , dock device. |
1230 | result = -ENODEV; | 1234 | * In such conditions it is unncessary to check whether it is |
1231 | goto end; | 1235 | * bay device or dock device. |
1232 | } | 1236 | */ |
1237 | if (!device->status.present && !device->status.functional) { | ||
1238 | result = -ENODEV; | ||
1239 | goto end; | ||
1233 | } | 1240 | } |
1234 | break; | 1241 | break; |
1235 | default: | 1242 | default: |
@@ -1252,6 +1259,16 @@ acpi_add_single_object(struct acpi_device **child, | |||
1252 | acpi_device_set_id(device, parent, handle, type); | 1259 | acpi_device_set_id(device, parent, handle, type); |
1253 | 1260 | ||
1254 | /* | 1261 | /* |
1262 | * The ACPI device is attached to acpi handle before getting | ||
1263 | * the power/wakeup/peformance flags. Otherwise OS can't get | ||
1264 | * the corresponding ACPI device by the acpi handle in the course | ||
1265 | * of getting the power/wakeup/performance flags. | ||
1266 | */ | ||
1267 | result = acpi_device_set_context(device, type); | ||
1268 | if (result) | ||
1269 | goto end; | ||
1270 | |||
1271 | /* | ||
1255 | * Power Management | 1272 | * Power Management |
1256 | * ---------------- | 1273 | * ---------------- |
1257 | */ | 1274 | */ |
@@ -1281,8 +1298,6 @@ acpi_add_single_object(struct acpi_device **child, | |||
1281 | goto end; | 1298 | goto end; |
1282 | } | 1299 | } |
1283 | 1300 | ||
1284 | if ((result = acpi_device_set_context(device, type))) | ||
1285 | goto end; | ||
1286 | 1301 | ||
1287 | result = acpi_device_register(device, parent); | 1302 | result = acpi_device_register(device, parent); |
1288 | 1303 | ||
@@ -1402,7 +1417,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) | |||
1402 | * TBD: Need notifications and other detection mechanisms | 1417 | * TBD: Need notifications and other detection mechanisms |
1403 | * in place before we can fully implement this. | 1418 | * in place before we can fully implement this. |
1404 | */ | 1419 | */ |
1405 | if (child->status.present) { | 1420 | /* |
1421 | * When the device is not present but functional, it is also | ||
1422 | * necessary to scan the children of this device. | ||
1423 | */ | ||
1424 | if (child->status.present || (!child->status.present && | ||
1425 | child->status.functional)) { | ||
1406 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, | 1426 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, |
1407 | NULL, NULL); | 1427 | NULL, NULL); |
1408 | if (ACPI_SUCCESS(status)) { | 1428 | if (ACPI_SUCCESS(status)) { |
@@ -1545,7 +1565,6 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1545 | return result; | 1565 | return result; |
1546 | } | 1566 | } |
1547 | 1567 | ||
1548 | int __init acpi_boot_ec_enable(void); | ||
1549 | 1568 | ||
1550 | static int __init acpi_scan_init(void) | 1569 | static int __init acpi_scan_init(void) |
1551 | { | 1570 | { |
@@ -1579,9 +1598,6 @@ static int __init acpi_scan_init(void) | |||
1579 | */ | 1598 | */ |
1580 | result = acpi_bus_scan_fixed(acpi_root); | 1599 | result = acpi_bus_scan_fixed(acpi_root); |
1581 | 1600 | ||
1582 | /* EC region might be needed at bus_scan, so enable it now */ | ||
1583 | acpi_boot_ec_enable(); | ||
1584 | |||
1585 | if (!result) | 1601 | if (!result) |
1586 | result = acpi_bus_scan(acpi_root, &ops); | 1602 | result = acpi_bus_scan(acpi_root, &ops); |
1587 | 1603 | ||