aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/scan.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2008-10-22 23:19:50 -0400
committerLen Brown <len.brown@intel.com>2008-10-22 23:19:50 -0400
commit955ba395616a78780e70dc3f3b0b56ca4db52e5c (patch)
treef5978cfdc2b5ede82445de6675301a0171e66ea0 /drivers/acpi/scan.c
parentaa58329fc8ec50b379388fcad55f62c3493730d3 (diff)
parent383d7a11c9989205db44c7f1be339e5097062f03 (diff)
Merge branch 'bugfixes' into test
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r--drivers/acpi/scan.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index f6f52c1a2aba..91fed422bae8 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))
@@ -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}
@@ -1153,20 +1161,6 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
1153} 1161}
1154 1162
1155static int 1163static int
1156acpi_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
1169static int
1170acpi_add_single_object(struct acpi_device **child, 1164acpi_add_single_object(struct acpi_device **child,
1171 struct acpi_device *parent, acpi_handle handle, int type, 1165 struct acpi_device *parent, acpi_handle handle, int type,
1172 struct acpi_bus_ops *ops) 1166 struct acpi_bus_ops *ops)
@@ -1221,15 +1215,18 @@ acpi_add_single_object(struct acpi_device **child,
1221 result = -ENODEV; 1215 result = -ENODEV;
1222 goto end; 1216 goto end;
1223 } 1217 }
1224 if (!device->status.present) { 1218 /*
1225 /* Bay and dock should be handled even if absent */ 1219 * When the device is neither present nor functional, the
1226 if (!ACPI_SUCCESS( 1220 * device should not be added to Linux ACPI device tree.
1227 acpi_is_child_device(device, acpi_bay_match)) && 1221 * When the status of the device is not present but functinal,
1228 !ACPI_SUCCESS( 1222 * it should be added to Linux ACPI tree. For example : bay
1229 acpi_is_child_device(device, acpi_dock_match))) { 1223 * device , dock device.
1230 result = -ENODEV; 1224 * In such conditions it is unncessary to check whether it is
1231 goto end; 1225 * bay device or dock device.
1232 } 1226 */
1227 if (!device->status.present && !device->status.functional) {
1228 result = -ENODEV;
1229 goto end;
1233 } 1230 }
1234 break; 1231 break;
1235 default: 1232 default:
@@ -1252,6 +1249,16 @@ acpi_add_single_object(struct acpi_device **child,
1252 acpi_device_set_id(device, parent, handle, type); 1249 acpi_device_set_id(device, parent, handle, type);
1253 1250
1254 /* 1251 /*
1252 * The ACPI device is attached to acpi handle before getting
1253 * the power/wakeup/peformance flags. Otherwise OS can't get
1254 * the corresponding ACPI device by the acpi handle in the course
1255 * of getting the power/wakeup/performance flags.
1256 */
1257 result = acpi_device_set_context(device, type);
1258 if (result)
1259 goto end;
1260
1261 /*
1255 * Power Management 1262 * Power Management
1256 * ---------------- 1263 * ----------------
1257 */ 1264 */
@@ -1281,8 +1288,6 @@ acpi_add_single_object(struct acpi_device **child,
1281 goto end; 1288 goto end;
1282 } 1289 }
1283 1290
1284 if ((result = acpi_device_set_context(device, type)))
1285 goto end;
1286 1291
1287 result = acpi_device_register(device, parent); 1292 result = acpi_device_register(device, parent);
1288 1293
@@ -1402,7 +1407,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
1402 * TBD: Need notifications and other detection mechanisms 1407 * TBD: Need notifications and other detection mechanisms
1403 * in place before we can fully implement this. 1408 * in place before we can fully implement this.
1404 */ 1409 */
1405 if (child->status.present) { 1410 /*
1411 * When the device is not present but functional, it is also
1412 * necessary to scan the children of this device.
1413 */
1414 if (child->status.present || (!child->status.present &&
1415 child->status.functional)) {
1406 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, 1416 status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
1407 NULL, NULL); 1417 NULL, NULL);
1408 if (ACPI_SUCCESS(status)) { 1418 if (ACPI_SUCCESS(status)) {