aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/bus.c16
-rw-r--r--drivers/acpi/scan.c35
-rw-r--r--drivers/pnp/pnpacpi/core.c6
3 files changed, 38 insertions, 19 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 945cd2f2807d..e9b116d2b56d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -112,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device)
112 } 112 }
113 113
114 /* 114 /*
115 * Otherwise we assume the status of our parent (unless we don't 115 * According to ACPI spec some device can be present and functional
116 * have one, in which case status is implied). 116 * even if the parent is not present but functional.
117 * In such conditions the child device should not inherit the status
118 * from the parent.
117 */ 119 */
118 else if (device->parent)
119 device->status = device->parent->status;
120 else 120 else
121 STRUCT_TO_INT(device->status) = 121 STRUCT_TO_INT(device->status) =
122 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | 122 ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
123 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; 123 ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING;
124 124
125 if (device->status.functional && !device->status.present) { 125 if (device->status.functional && !device->status.present) {
126 printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: " 126 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
127 "functional but not present; setting present\n", 127 "functional but not present;\n",
128 device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)); 128 device->pnp.bus_id,
129 device->status.present = 1; 129 (u32) STRUCT_TO_INT(device->status)));
130 } 130 }
131 131
132 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", 132 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ad0679843bd5..89c112ef9e14 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -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))
@@ -1222,15 +1229,18 @@ acpi_add_single_object(struct acpi_device **child,
1222 result = -ENODEV; 1229 result = -ENODEV;
1223 goto end; 1230 goto end;
1224 } 1231 }
1225 if (!device->status.present) { 1232 /*
1226 /* Bay and dock should be handled even if absent */ 1233 * When the device is neither present nor functional, the
1227 if (!ACPI_SUCCESS( 1234 * device should not be added to Linux ACPI device tree.
1228 acpi_is_child_device(device, acpi_bay_match)) && 1235 * When the status of the device is not present but functinal,
1229 !ACPI_SUCCESS( 1236 * it should be added to Linux ACPI tree. For example : bay
1230 acpi_is_child_device(device, acpi_dock_match))) { 1237 * device , dock device.
1231 result = -ENODEV; 1238 * In such conditions it is unncessary to check whether it is
1232 goto end; 1239 * bay device or dock device.
1233 } 1240 */
1241 if (!device->status.present && !device->status.functional) {
1242 result = -ENODEV;
1243 goto end;
1234 } 1244 }
1235 break; 1245 break;
1236 default: 1246 default:
@@ -1411,7 +1421,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1411 * TBD: Need notifications and other detection mechanisms 1421 * TBD: Need notifications and other detection mechanisms
1412 * in place before we can fully implement this. 1422 * in place before we can fully implement this.
1413 */ 1423 */
1414 if (child->status.present) { 1424 /*
1425 * When the device is not present but functional, it is also
1426 * necessary to scan the children of this device.
1427 */
1428 if (child->status.present || (!child->status.present &&
1429 child->status.functional)) {
1415 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, 1430 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
1416 NULL, NULL); 1431 NULL, NULL);
1417 if (ACPI_SUCCESS(status)) { 1432 if (ACPI_SUCCESS(status)) {
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index c1b9ea34977b..98b9df7776e9 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
148 acpi_status status; 148 acpi_status status;
149 struct pnp_dev *dev; 149 struct pnp_dev *dev;
150 150
151 /*
152 * If a PnPacpi device is not present , the device
153 * driver should not be loaded.
154 */
151 status = acpi_get_handle(device->handle, "_CRS", &temp); 155 status = acpi_get_handle(device->handle, "_CRS", &temp);
152 if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || 156 if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
153 is_exclusive_device(device)) 157 is_exclusive_device(device) || (!device->status.present))
154 return 0; 158 return 0;
155 159
156 dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); 160 dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));