aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig4
-rw-r--r--drivers/acpi/container.c2
-rw-r--r--drivers/acpi/pci_bind.c27
-rw-r--r--drivers/acpi/pci_irq.c3
-rw-r--r--drivers/acpi/pci_root.c24
-rw-r--r--drivers/acpi/processor_core.c2
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/acpi/scan.c130
8 files changed, 153 insertions, 41 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 84bbcb051cb7..986410e7b483 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -55,8 +55,8 @@ if ACPI_INTERPRETER
55 55
56config ACPI_SLEEP 56config ACPI_SLEEP
57 bool "Sleep States (EXPERIMENTAL)" 57 bool "Sleep States (EXPERIMENTAL)"
58 depends on X86 58 depends on X86 && (!SMP || SUSPEND_SMP)
59 depends on EXPERIMENTAL 59 depends on EXPERIMENTAL && PM
60 default y 60 default y
61 ---help--- 61 ---help---
62 This option adds support for ACPI suspend states. 62 This option adds support for ACPI suspend states.
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 5a0adbf8bc04..97013ddfa202 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle)
153 return_VALUE(-ENODEV); 153 return_VALUE(-ENODEV);
154 } 154 }
155 155
156 result = acpi_bus_scan(*device); 156 result = acpi_bus_start(*device);
157 157
158 return_VALUE(result); 158 return_VALUE(result);
159} 159}
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 5d19b39e9e2b..5148f3c10b5c 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -61,15 +61,14 @@ acpi_pci_data_handler (
61 61
62 62
63/** 63/**
64 * acpi_os_get_pci_id 64 * acpi_get_pci_id
65 * ------------------ 65 * ------------------
66 * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) 66 * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem)
67 * to resolve PCI information for ACPI-PCI devices defined in the namespace. 67 * to resolve PCI information for ACPI-PCI devices defined in the namespace.
68 * This typically occurs when resolving PCI operation region information. 68 * This typically occurs when resolving PCI operation region information.
69 */ 69 */
70#ifdef ACPI_FUTURE_USAGE
71acpi_status 70acpi_status
72acpi_os_get_pci_id ( 71acpi_get_pci_id (
73 acpi_handle handle, 72 acpi_handle handle,
74 struct acpi_pci_id *id) 73 struct acpi_pci_id *id)
75{ 74{
@@ -78,7 +77,7 @@ acpi_os_get_pci_id (
78 struct acpi_device *device = NULL; 77 struct acpi_device *device = NULL;
79 struct acpi_pci_data *data = NULL; 78 struct acpi_pci_data *data = NULL;
80 79
81 ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); 80 ACPI_FUNCTION_TRACE("acpi_get_pci_id");
82 81
83 if (!id) 82 if (!id)
84 return_ACPI_STATUS(AE_BAD_PARAMETER); 83 return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -92,7 +91,7 @@ acpi_os_get_pci_id (
92 } 91 }
93 92
94 status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); 93 status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data);
95 if (ACPI_FAILURE(status) || !data || !data->dev) { 94 if (ACPI_FAILURE(status) || !data) {
96 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 95 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
97 "Invalid ACPI-PCI context for device %s\n", 96 "Invalid ACPI-PCI context for device %s\n",
98 acpi_device_bid(device))); 97 acpi_device_bid(device)));
@@ -115,7 +114,7 @@ acpi_os_get_pci_id (
115 114
116 return_ACPI_STATUS(AE_OK); 115 return_ACPI_STATUS(AE_OK);
117} 116}
118#endif /* ACPI_FUTURE_USAGE */ 117EXPORT_SYMBOL(acpi_get_pci_id);
119 118
120 119
121int 120int
@@ -129,6 +128,8 @@ acpi_pci_bind (
129 char *pathname = NULL; 128 char *pathname = NULL;
130 struct acpi_buffer buffer = {0, NULL}; 129 struct acpi_buffer buffer = {0, NULL};
131 acpi_handle handle = NULL; 130 acpi_handle handle = NULL;
131 struct pci_dev *dev;
132 struct pci_bus *bus;
132 133
133 ACPI_FUNCTION_TRACE("acpi_pci_bind"); 134 ACPI_FUNCTION_TRACE("acpi_pci_bind");
134 135
@@ -193,8 +194,20 @@ acpi_pci_bind (
193 * Locate matching device in PCI namespace. If it doesn't exist 194 * Locate matching device in PCI namespace. If it doesn't exist
194 * this typically means that the device isn't currently inserted 195 * this typically means that the device isn't currently inserted
195 * (e.g. docking station, port replicator, etc.). 196 * (e.g. docking station, port replicator, etc.).
197 * We cannot simply search the global pci device list, since
198 * PCI devices are added to the global pci list when the root
199 * bridge start ops are run, which may not have happened yet.
196 */ 200 */
197 data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); 201 bus = pci_find_bus(data->id.segment, data->id.bus);
202 if (bus) {
203 list_for_each_entry(dev, &bus->devices, bus_list) {
204 if (dev->devfn == PCI_DEVFN(data->id.device,
205 data->id.function)) {
206 data->dev = dev;
207 break;
208 }
209 }
210 }
198 if (!data->dev) { 211 if (!data->dev) {
199 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 212 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
200 "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", 213 "Device %02x:%02x:%02x.%02x not present in PCI namespace\n",
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 8093f2e00321..d1f42b972821 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -433,8 +433,9 @@ acpi_pci_irq_enable (
433 printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", 433 printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI",
434 pci_name(dev), ('A' + pin)); 434 pci_name(dev), ('A' + pin));
435 /* Interrupt Line values above 0xF are forbidden */ 435 /* Interrupt Line values above 0xF are forbidden */
436 if (dev->irq >= 0 && (dev->irq <= 0xF)) { 436 if (dev->irq > 0 && (dev->irq <= 0xF)) {
437 printk(" - using IRQ %d\n", dev->irq); 437 printk(" - using IRQ %d\n", dev->irq);
438 acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW);
438 return_VALUE(0); 439 return_VALUE(0);
439 } 440 }
440 else { 441 else {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 7e6b8e3b2ed4..5d2f77fcd50c 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root")
46 46
47static int acpi_pci_root_add (struct acpi_device *device); 47static int acpi_pci_root_add (struct acpi_device *device);
48static int acpi_pci_root_remove (struct acpi_device *device, int type); 48static int acpi_pci_root_remove (struct acpi_device *device, int type);
49static int acpi_pci_root_start (struct acpi_device *device);
49 50
50static struct acpi_driver acpi_pci_root_driver = { 51static struct acpi_driver acpi_pci_root_driver = {
51 .name = ACPI_PCI_ROOT_DRIVER_NAME, 52 .name = ACPI_PCI_ROOT_DRIVER_NAME,
@@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = {
54 .ops = { 55 .ops = {
55 .add = acpi_pci_root_add, 56 .add = acpi_pci_root_add,
56 .remove = acpi_pci_root_remove, 57 .remove = acpi_pci_root_remove,
58 .start = acpi_pci_root_start,
57 }, 59 },
58}; 60};
59 61
@@ -169,6 +171,7 @@ acpi_pci_root_add (
169 if (!root) 171 if (!root)
170 return_VALUE(-ENOMEM); 172 return_VALUE(-ENOMEM);
171 memset(root, 0, sizeof(struct acpi_pci_root)); 173 memset(root, 0, sizeof(struct acpi_pci_root));
174 INIT_LIST_HEAD(&root->node);
172 175
173 root->handle = device->handle; 176 root->handle = device->handle;
174 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); 177 strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
@@ -298,12 +301,31 @@ acpi_pci_root_add (
298 root->id.bus); 301 root->id.bus);
299 302
300end: 303end:
301 if (result) 304 if (result) {
305 if (!list_empty(&root->node))
306 list_del(&root->node);
302 kfree(root); 307 kfree(root);
308 }
303 309
304 return_VALUE(result); 310 return_VALUE(result);
305} 311}
306 312
313static int
314acpi_pci_root_start (
315 struct acpi_device *device)
316{
317 struct acpi_pci_root *root;
318
319 ACPI_FUNCTION_TRACE("acpi_pci_root_start");
320
321 list_for_each_entry(root, &acpi_pci_roots, node) {
322 if (root->handle == device->handle) {
323 pci_bus_add_devices(root->bus);
324 return_VALUE(0);
325 }
326 }
327 return_VALUE(-ENODEV);
328}
307 329
308static int 330static int
309acpi_pci_root_remove ( 331acpi_pci_root_remove (
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index e421842888b9..d56a439ac614 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -760,7 +760,7 @@ int acpi_processor_device_add(
760 return_VALUE(-ENODEV); 760 return_VALUE(-ENODEV);
761 } 761 }
762 762
763 acpi_bus_scan(*device); 763 acpi_bus_start(*device);
764 764
765 pr = acpi_driver_data(*device); 765 pr = acpi_driver_data(*device);
766 if (!pr) 766 if (!pr)
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 8f038cd29477..893b074e3d1a 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -176,7 +176,7 @@ static void acpi_processor_idle (void)
176 int sleep_ticks = 0; 176 int sleep_ticks = 0;
177 u32 t1, t2 = 0; 177 u32 t1, t2 = 0;
178 178
179 pr = processors[_smp_processor_id()]; 179 pr = processors[raw_smp_processor_id()];
180 if (!pr) 180 if (!pr)
181 return; 181 return;
182 182
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7c26fed0bdf0..cbcda30c172d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -65,14 +65,14 @@ static ssize_t acpi_device_attr_show(struct kobject *kobj,
65{ 65{
66 struct acpi_device *device = to_acpi_device(kobj); 66 struct acpi_device *device = to_acpi_device(kobj);
67 struct acpi_device_attribute *attribute = to_handle_attr(attr); 67 struct acpi_device_attribute *attribute = to_handle_attr(attr);
68 return attribute->show ? attribute->show(device, buf) : 0; 68 return attribute->show ? attribute->show(device, buf) : -EIO;
69} 69}
70static ssize_t acpi_device_attr_store(struct kobject *kobj, 70static ssize_t acpi_device_attr_store(struct kobject *kobj,
71 struct attribute *attr, const char *buf, size_t len) 71 struct attribute *attr, const char *buf, size_t len)
72{ 72{
73 struct acpi_device *device = to_acpi_device(kobj); 73 struct acpi_device *device = to_acpi_device(kobj);
74 struct acpi_device_attribute *attribute = to_handle_attr(attr); 74 struct acpi_device_attribute *attribute = to_handle_attr(attr);
75 return attribute->store ? attribute->store(device, buf, len) : len; 75 return attribute->store ? attribute->store(device, buf, len) : -EIO;
76} 76}
77 77
78static struct sysfs_ops acpi_device_sysfs_ops = { 78static struct sysfs_ops acpi_device_sysfs_ops = {
@@ -553,20 +553,29 @@ acpi_bus_driver_init (
553 * upon possible configuration and currently allocated resources. 553 * upon possible configuration and currently allocated resources.
554 */ 554 */
555 555
556 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n"));
557 return_VALUE(0);
558}
559
560int
561acpi_start_single_object (
562 struct acpi_device *device)
563{
564 int result = 0;
565 struct acpi_driver *driver;
566
567 ACPI_FUNCTION_TRACE("acpi_start_single_object");
568
569 if (!(driver = device->driver))
570 return_VALUE(0);
571
556 if (driver->ops.start) { 572 if (driver->ops.start) {
557 result = driver->ops.start(device); 573 result = driver->ops.start(device);
558 if (result && driver->ops.remove) 574 if (result && driver->ops.remove)
559 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); 575 driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL);
560 return_VALUE(result);
561 } 576 }
562 577
563 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); 578 return_VALUE(result);
564
565 if (driver->ops.scan) {
566 driver->ops.scan(device);
567 }
568
569 return_VALUE(0);
570} 579}
571 580
572static int acpi_driver_attach(struct acpi_driver * drv) 581static int acpi_driver_attach(struct acpi_driver * drv)
@@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv)
586 595
587 if (!acpi_bus_match(dev, drv)) { 596 if (!acpi_bus_match(dev, drv)) {
588 if (!acpi_bus_driver_init(dev, drv)) { 597 if (!acpi_bus_driver_init(dev, drv)) {
598 acpi_start_single_object(dev);
589 atomic_inc(&drv->references); 599 atomic_inc(&drv->references);
590 count++; 600 count++;
591 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", 601 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
@@ -1009,8 +1019,8 @@ acpi_bus_remove (
1009} 1019}
1010 1020
1011 1021
1012int 1022static int
1013acpi_bus_add ( 1023acpi_add_single_object (
1014 struct acpi_device **child, 1024 struct acpi_device **child,
1015 struct acpi_device *parent, 1025 struct acpi_device *parent,
1016 acpi_handle handle, 1026 acpi_handle handle,
@@ -1019,7 +1029,7 @@ acpi_bus_add (
1019 int result = 0; 1029 int result = 0;
1020 struct acpi_device *device = NULL; 1030 struct acpi_device *device = NULL;
1021 1031
1022 ACPI_FUNCTION_TRACE("acpi_bus_add"); 1032 ACPI_FUNCTION_TRACE("acpi_add_single_object");
1023 1033
1024 if (!child) 1034 if (!child)
1025 return_VALUE(-EINVAL); 1035 return_VALUE(-EINVAL);
@@ -1142,7 +1152,7 @@ acpi_bus_add (
1142 * 1152 *
1143 * TBD: Assumes LDM provides driver hot-plug capability. 1153 * TBD: Assumes LDM provides driver hot-plug capability.
1144 */ 1154 */
1145 acpi_bus_find_driver(device); 1155 result = acpi_bus_find_driver(device);
1146 1156
1147end: 1157end:
1148 if (!result) 1158 if (!result)
@@ -1155,10 +1165,10 @@ end:
1155 1165
1156 return_VALUE(result); 1166 return_VALUE(result);
1157} 1167}
1158EXPORT_SYMBOL(acpi_bus_add);
1159 1168
1160 1169
1161int acpi_bus_scan (struct acpi_device *start) 1170static int acpi_bus_scan (struct acpi_device *start,
1171 struct acpi_bus_ops *ops)
1162{ 1172{
1163 acpi_status status = AE_OK; 1173 acpi_status status = AE_OK;
1164 struct acpi_device *parent = NULL; 1174 struct acpi_device *parent = NULL;
@@ -1231,9 +1241,20 @@ int acpi_bus_scan (struct acpi_device *start)
1231 continue; 1241 continue;
1232 } 1242 }
1233 1243
1234 status = acpi_bus_add(&child, parent, chandle, type); 1244 if (ops->acpi_op_add)
1235 if (ACPI_FAILURE(status)) 1245 status = acpi_add_single_object(&child, parent,
1236 continue; 1246 chandle, type);
1247 else
1248 status = acpi_bus_get_device(chandle, &child);
1249
1250 if (ACPI_FAILURE(status))
1251 continue;
1252
1253 if (ops->acpi_op_start) {
1254 status = acpi_start_single_object(child);
1255 if (ACPI_FAILURE(status))
1256 continue;
1257 }
1237 1258
1238 /* 1259 /*
1239 * If the device is present, enabled, and functioning then 1260 * If the device is present, enabled, and functioning then
@@ -1259,8 +1280,50 @@ int acpi_bus_scan (struct acpi_device *start)
1259 1280
1260 return_VALUE(0); 1281 return_VALUE(0);
1261} 1282}
1262EXPORT_SYMBOL(acpi_bus_scan);
1263 1283
1284int
1285acpi_bus_add (
1286 struct acpi_device **child,
1287 struct acpi_device *parent,
1288 acpi_handle handle,
1289 int type)
1290{
1291 int result;
1292 struct acpi_bus_ops ops;
1293
1294 ACPI_FUNCTION_TRACE("acpi_bus_add");
1295
1296 result = acpi_add_single_object(child, parent, handle, type);
1297 if (!result) {
1298 memset(&ops, 0, sizeof(ops));
1299 ops.acpi_op_add = 1;
1300 result = acpi_bus_scan(*child, &ops);
1301 }
1302 return_VALUE(result);
1303}
1304EXPORT_SYMBOL(acpi_bus_add);
1305
1306int
1307acpi_bus_start (
1308 struct acpi_device *device)
1309{
1310 int result;
1311 struct acpi_bus_ops ops;
1312
1313 ACPI_FUNCTION_TRACE("acpi_bus_start");
1314
1315 if (!device)
1316 return_VALUE(-EINVAL);
1317
1318 result = acpi_start_single_object(device);
1319 if (!result) {
1320 memset(&ops, 0, sizeof(ops));
1321 ops.acpi_op_start = 1;
1322 result = acpi_bus_scan(device, &ops);
1323 }
1324 return_VALUE(result);
1325}
1326EXPORT_SYMBOL(acpi_bus_start);
1264 1327
1265static int 1328static int
1266acpi_bus_trim(struct acpi_device *start, 1329acpi_bus_trim(struct acpi_device *start,
@@ -1333,13 +1396,19 @@ acpi_bus_scan_fixed (
1333 /* 1396 /*
1334 * Enumerate all fixed-feature devices. 1397 * Enumerate all fixed-feature devices.
1335 */ 1398 */
1336 if (acpi_fadt.pwr_button == 0) 1399 if (acpi_fadt.pwr_button == 0) {
1337 result = acpi_bus_add(&device, acpi_root, 1400 result = acpi_add_single_object(&device, acpi_root,
1338 NULL, ACPI_BUS_TYPE_POWER_BUTTON); 1401 NULL, ACPI_BUS_TYPE_POWER_BUTTON);
1402 if (!result)
1403 result = acpi_start_single_object(device);
1404 }
1339 1405
1340 if (acpi_fadt.sleep_button == 0) 1406 if (acpi_fadt.sleep_button == 0) {
1341 result = acpi_bus_add(&device, acpi_root, 1407 result = acpi_add_single_object(&device, acpi_root,
1342 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); 1408 NULL, ACPI_BUS_TYPE_SLEEP_BUTTON);
1409 if (!result)
1410 result = acpi_start_single_object(device);
1411 }
1343 1412
1344 return_VALUE(result); 1413 return_VALUE(result);
1345} 1414}
@@ -1348,6 +1417,7 @@ acpi_bus_scan_fixed (
1348static int __init acpi_scan_init(void) 1417static int __init acpi_scan_init(void)
1349{ 1418{
1350 int result; 1419 int result;
1420 struct acpi_bus_ops ops;
1351 1421
1352 ACPI_FUNCTION_TRACE("acpi_scan_init"); 1422 ACPI_FUNCTION_TRACE("acpi_scan_init");
1353 1423
@@ -1359,17 +1429,23 @@ static int __init acpi_scan_init(void)
1359 /* 1429 /*
1360 * Create the root device in the bus's device tree 1430 * Create the root device in the bus's device tree
1361 */ 1431 */
1362 result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, 1432 result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT,
1363 ACPI_BUS_TYPE_SYSTEM); 1433 ACPI_BUS_TYPE_SYSTEM);
1364 if (result) 1434 if (result)
1365 goto Done; 1435 goto Done;
1366 1436
1437 result = acpi_start_single_object(acpi_root);
1438
1367 /* 1439 /*
1368 * Enumerate devices in the ACPI namespace. 1440 * Enumerate devices in the ACPI namespace.
1369 */ 1441 */
1370 result = acpi_bus_scan_fixed(acpi_root); 1442 result = acpi_bus_scan_fixed(acpi_root);
1371 if (!result) 1443 if (!result) {
1372 result = acpi_bus_scan(acpi_root); 1444 memset(&ops, 0, sizeof(ops));
1445 ops.acpi_op_add = 1;
1446 ops.acpi_op_start = 1;
1447 result = acpi_bus_scan(acpi_root, &ops);
1448 }
1373 1449
1374 if (result) 1450 if (result)
1375 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); 1451 acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL);