diff options
Diffstat (limited to 'drivers/acpi/scan.c')
-rw-r--r-- | drivers/acpi/scan.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 97f6bbd6ef3c..2a82645c9dfe 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -212,7 +212,8 @@ static int acpi_device_probe(struct device * dev) | |||
212 | 212 | ||
213 | ret = acpi_bus_driver_init(acpi_dev, acpi_drv); | 213 | ret = acpi_bus_driver_init(acpi_dev, acpi_drv); |
214 | if (!ret) { | 214 | if (!ret) { |
215 | acpi_start_single_object(acpi_dev); | 215 | if (acpi_dev->bus_ops.acpi_op_start) |
216 | acpi_start_single_object(acpi_dev); | ||
216 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 217 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
217 | "Found driver [%s] for device [%s]\n", | 218 | "Found driver [%s] for device [%s]\n", |
218 | acpi_drv->name, acpi_dev->pnp.bus_id)); | 219 | acpi_drv->name, acpi_dev->pnp.bus_id)); |
@@ -305,7 +306,6 @@ static void acpi_device_unregister(struct acpi_device *device, int type) | |||
305 | list_del(&device->g_list); | 306 | list_del(&device->g_list); |
306 | 307 | ||
307 | list_del(&device->wakeup_list); | 308 | list_del(&device->wakeup_list); |
308 | |||
309 | spin_unlock(&acpi_device_lock); | 309 | spin_unlock(&acpi_device_lock); |
310 | 310 | ||
311 | acpi_detach_data(device->handle, acpi_bus_data_handler); | 311 | acpi_detach_data(device->handle, acpi_bus_data_handler); |
@@ -876,7 +876,8 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice) | |||
876 | 876 | ||
877 | static int | 877 | static int |
878 | acpi_add_single_object(struct acpi_device **child, | 878 | acpi_add_single_object(struct acpi_device **child, |
879 | struct acpi_device *parent, acpi_handle handle, int type) | 879 | struct acpi_device *parent, acpi_handle handle, int type, |
880 | struct acpi_bus_ops *ops) | ||
880 | { | 881 | { |
881 | int result = 0; | 882 | int result = 0; |
882 | struct acpi_device *device = NULL; | 883 | struct acpi_device *device = NULL; |
@@ -894,6 +895,8 @@ acpi_add_single_object(struct acpi_device **child, | |||
894 | 895 | ||
895 | device->handle = handle; | 896 | device->handle = handle; |
896 | device->parent = parent; | 897 | device->parent = parent; |
898 | device->bus_ops = *ops; /* workround for not call .start */ | ||
899 | |||
897 | 900 | ||
898 | acpi_device_get_busid(device, handle, type); | 901 | acpi_device_get_busid(device, handle, type); |
899 | 902 | ||
@@ -1079,14 +1082,14 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) | |||
1079 | 1082 | ||
1080 | if (ops->acpi_op_add) | 1083 | if (ops->acpi_op_add) |
1081 | status = acpi_add_single_object(&child, parent, | 1084 | status = acpi_add_single_object(&child, parent, |
1082 | chandle, type); | 1085 | chandle, type, ops); |
1083 | else | 1086 | else |
1084 | status = acpi_bus_get_device(chandle, &child); | 1087 | status = acpi_bus_get_device(chandle, &child); |
1085 | 1088 | ||
1086 | if (ACPI_FAILURE(status)) | 1089 | if (ACPI_FAILURE(status)) |
1087 | continue; | 1090 | continue; |
1088 | 1091 | ||
1089 | if (ops->acpi_op_start) { | 1092 | if (ops->acpi_op_start && !(ops->acpi_op_add)) { |
1090 | status = acpi_start_single_object(child); | 1093 | status = acpi_start_single_object(child); |
1091 | if (ACPI_FAILURE(status)) | 1094 | if (ACPI_FAILURE(status)) |
1092 | continue; | 1095 | continue; |
@@ -1124,13 +1127,13 @@ acpi_bus_add(struct acpi_device **child, | |||
1124 | int result; | 1127 | int result; |
1125 | struct acpi_bus_ops ops; | 1128 | struct acpi_bus_ops ops; |
1126 | 1129 | ||
1130 | memset(&ops, 0, sizeof(ops)); | ||
1131 | ops.acpi_op_add = 1; | ||
1127 | 1132 | ||
1128 | result = acpi_add_single_object(child, parent, handle, type); | 1133 | result = acpi_add_single_object(child, parent, handle, type, &ops); |
1129 | if (!result) { | 1134 | if (!result) |
1130 | memset(&ops, 0, sizeof(ops)); | ||
1131 | ops.acpi_op_add = 1; | ||
1132 | result = acpi_bus_scan(*child, &ops); | 1135 | result = acpi_bus_scan(*child, &ops); |
1133 | } | 1136 | |
1134 | return result; | 1137 | return result; |
1135 | } | 1138 | } |
1136 | 1139 | ||
@@ -1216,28 +1219,30 @@ static int acpi_bus_scan_fixed(struct acpi_device *root) | |||
1216 | { | 1219 | { |
1217 | int result = 0; | 1220 | int result = 0; |
1218 | struct acpi_device *device = NULL; | 1221 | struct acpi_device *device = NULL; |
1219 | 1222 | struct acpi_bus_ops ops; | |
1220 | 1223 | ||
1221 | if (!root) | 1224 | if (!root) |
1222 | return -ENODEV; | 1225 | return -ENODEV; |
1223 | 1226 | ||
1227 | memset(&ops, 0, sizeof(ops)); | ||
1228 | ops.acpi_op_add = 1; | ||
1229 | ops.acpi_op_start = 1; | ||
1230 | |||
1224 | /* | 1231 | /* |
1225 | * Enumerate all fixed-feature devices. | 1232 | * Enumerate all fixed-feature devices. |
1226 | */ | 1233 | */ |
1227 | if (acpi_fadt.pwr_button == 0) { | 1234 | if (acpi_fadt.pwr_button == 0) { |
1228 | result = acpi_add_single_object(&device, acpi_root, | 1235 | result = acpi_add_single_object(&device, acpi_root, |
1229 | NULL, | 1236 | NULL, |
1230 | ACPI_BUS_TYPE_POWER_BUTTON); | 1237 | ACPI_BUS_TYPE_POWER_BUTTON, |
1231 | if (!result) | 1238 | &ops); |
1232 | result = acpi_start_single_object(device); | ||
1233 | } | 1239 | } |
1234 | 1240 | ||
1235 | if (acpi_fadt.sleep_button == 0) { | 1241 | if (acpi_fadt.sleep_button == 0) { |
1236 | result = acpi_add_single_object(&device, acpi_root, | 1242 | result = acpi_add_single_object(&device, acpi_root, |
1237 | NULL, | 1243 | NULL, |
1238 | ACPI_BUS_TYPE_SLEEP_BUTTON); | 1244 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
1239 | if (!result) | 1245 | &ops); |
1240 | result = acpi_start_single_object(device); | ||
1241 | } | 1246 | } |
1242 | 1247 | ||
1243 | return result; | 1248 | return result; |
@@ -1252,6 +1257,10 @@ static int __init acpi_scan_init(void) | |||
1252 | if (acpi_disabled) | 1257 | if (acpi_disabled) |
1253 | return 0; | 1258 | return 0; |
1254 | 1259 | ||
1260 | memset(&ops, 0, sizeof(ops)); | ||
1261 | ops.acpi_op_add = 1; | ||
1262 | ops.acpi_op_start = 1; | ||
1263 | |||
1255 | result = bus_register(&acpi_bus_type); | 1264 | result = bus_register(&acpi_bus_type); |
1256 | if (result) { | 1265 | if (result) { |
1257 | /* We don't want to quit even if we failed to add suspend/resume */ | 1266 | /* We don't want to quit even if we failed to add suspend/resume */ |
@@ -1262,11 +1271,7 @@ static int __init acpi_scan_init(void) | |||
1262 | * Create the root device in the bus's device tree | 1271 | * Create the root device in the bus's device tree |
1263 | */ | 1272 | */ |
1264 | result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, | 1273 | result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, |
1265 | ACPI_BUS_TYPE_SYSTEM); | 1274 | ACPI_BUS_TYPE_SYSTEM, &ops); |
1266 | if (result) | ||
1267 | goto Done; | ||
1268 | |||
1269 | result = acpi_start_single_object(acpi_root); | ||
1270 | if (result) | 1275 | if (result) |
1271 | goto Done; | 1276 | goto Done; |
1272 | 1277 | ||
@@ -1274,12 +1279,8 @@ static int __init acpi_scan_init(void) | |||
1274 | * Enumerate devices in the ACPI namespace. | 1279 | * Enumerate devices in the ACPI namespace. |
1275 | */ | 1280 | */ |
1276 | result = acpi_bus_scan_fixed(acpi_root); | 1281 | result = acpi_bus_scan_fixed(acpi_root); |
1277 | if (!result) { | 1282 | if (!result) |
1278 | memset(&ops, 0, sizeof(ops)); | ||
1279 | ops.acpi_op_add = 1; | ||
1280 | ops.acpi_op_start = 1; | ||
1281 | result = acpi_bus_scan(acpi_root, &ops); | 1283 | result = acpi_bus_scan(acpi_root, &ops); |
1282 | } | ||
1283 | 1284 | ||
1284 | if (result) | 1285 | if (result) |
1285 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1286 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |