aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c130
1 files changed, 61 insertions, 69 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5d2f77fcd50c..0fd9988c283d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -35,35 +35,32 @@
35#include <acpi/acpi_bus.h> 35#include <acpi/acpi_bus.h>
36#include <acpi/acpi_drivers.h> 36#include <acpi/acpi_drivers.h>
37 37
38
39#define _COMPONENT ACPI_PCI_COMPONENT 38#define _COMPONENT ACPI_PCI_COMPONENT
40ACPI_MODULE_NAME ("pci_root") 39ACPI_MODULE_NAME("pci_root")
41
42#define ACPI_PCI_ROOT_CLASS "pci_bridge" 40#define ACPI_PCI_ROOT_CLASS "pci_bridge"
43#define ACPI_PCI_ROOT_HID "PNP0A03" 41#define ACPI_PCI_ROOT_HID "PNP0A03"
44#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver" 42#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver"
45#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" 43#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
46 44static int acpi_pci_root_add(struct acpi_device *device);
47static int acpi_pci_root_add (struct acpi_device *device); 45static int acpi_pci_root_remove(struct acpi_device *device, int type);
48static int acpi_pci_root_remove (struct acpi_device *device, int type); 46static int acpi_pci_root_start(struct acpi_device *device);
49static int acpi_pci_root_start (struct acpi_device *device);
50 47
51static struct acpi_driver acpi_pci_root_driver = { 48static struct acpi_driver acpi_pci_root_driver = {
52 .name = ACPI_PCI_ROOT_DRIVER_NAME, 49 .name = ACPI_PCI_ROOT_DRIVER_NAME,
53 .class = ACPI_PCI_ROOT_CLASS, 50 .class = ACPI_PCI_ROOT_CLASS,
54 .ids = ACPI_PCI_ROOT_HID, 51 .ids = ACPI_PCI_ROOT_HID,
55 .ops = { 52 .ops = {
56 .add = acpi_pci_root_add, 53 .add = acpi_pci_root_add,
57 .remove = acpi_pci_root_remove, 54 .remove = acpi_pci_root_remove,
58 .start = acpi_pci_root_start, 55 .start = acpi_pci_root_start,
59 }, 56 },
60}; 57};
61 58
62struct acpi_pci_root { 59struct acpi_pci_root {
63 struct list_head node; 60 struct list_head node;
64 acpi_handle handle; 61 acpi_handle handle;
65 struct acpi_pci_id id; 62 struct acpi_pci_id id;
66 struct pci_bus *bus; 63 struct pci_bus *bus;
67}; 64};
68 65
69static LIST_HEAD(acpi_pci_roots); 66static LIST_HEAD(acpi_pci_roots);
@@ -92,6 +89,7 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver)
92 89
93 return n; 90 return n;
94} 91}
92
95EXPORT_SYMBOL(acpi_pci_register_driver); 93EXPORT_SYMBOL(acpi_pci_register_driver);
96 94
97void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) 95void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
@@ -115,10 +113,11 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
115 driver->remove(root->handle); 113 driver->remove(root->handle);
116 } 114 }
117} 115}
116
118EXPORT_SYMBOL(acpi_pci_unregister_driver); 117EXPORT_SYMBOL(acpi_pci_unregister_driver);
119 118
120static acpi_status 119static acpi_status
121get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data) 120get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
122{ 121{
123 int *busnr = (int *)data; 122 int *busnr = (int *)data;
124 struct acpi_resource_address64 address; 123 struct acpi_resource_address64 address;
@@ -129,20 +128,21 @@ get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data)
129 return AE_OK; 128 return AE_OK;
130 129
131 acpi_resource_to_address64(resource, &address); 130 acpi_resource_to_address64(resource, &address);
132 if ((address.address_length > 0) && 131 if ((address.address_length > 0) &&
133 (address.resource_type == ACPI_BUS_NUMBER_RANGE)) 132 (address.resource_type == ACPI_BUS_NUMBER_RANGE))
134 *busnr = address.min_address_range; 133 *busnr = address.min_address_range;
135 134
136 return AE_OK; 135 return AE_OK;
137} 136}
138 137
139static acpi_status 138static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
140try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
141{ 139{
142 acpi_status status; 140 acpi_status status;
143 141
144 *busnum = -1; 142 *busnum = -1;
145 status = acpi_walk_resources(handle, METHOD_NAME__CRS, get_root_bridge_busnr_callback, busnum); 143 status =
144 acpi_walk_resources(handle, METHOD_NAME__CRS,
145 get_root_bridge_busnr_callback, busnum);
146 if (ACPI_FAILURE(status)) 146 if (ACPI_FAILURE(status))
147 return status; 147 return status;
148 /* Check if we really get a bus number from _CRS */ 148 /* Check if we really get a bus number from _CRS */
@@ -151,16 +151,14 @@ try_get_root_bridge_busnr(acpi_handle handle, int *busnum)
151 return AE_OK; 151 return AE_OK;
152} 152}
153 153
154static int 154static int acpi_pci_root_add(struct acpi_device *device)
155acpi_pci_root_add (
156 struct acpi_device *device)
157{ 155{
158 int result = 0; 156 int result = 0;
159 struct acpi_pci_root *root = NULL; 157 struct acpi_pci_root *root = NULL;
160 struct acpi_pci_root *tmp; 158 struct acpi_pci_root *tmp;
161 acpi_status status = AE_OK; 159 acpi_status status = AE_OK;
162 unsigned long value = 0; 160 unsigned long value = 0;
163 acpi_handle handle = NULL; 161 acpi_handle handle = NULL;
164 162
165 ACPI_FUNCTION_TRACE("acpi_pci_root_add"); 163 ACPI_FUNCTION_TRACE("acpi_pci_root_add");
166 164
@@ -188,15 +186,15 @@ acpi_pci_root_add (
188 * ------- 186 * -------
189 * Obtained via _SEG, if exists, otherwise assumed to be zero (0). 187 * Obtained via _SEG, if exists, otherwise assumed to be zero (0).
190 */ 188 */
191 status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL, 189 status = acpi_evaluate_integer(root->handle, METHOD_NAME__SEG, NULL,
192 &value); 190 &value);
193 switch (status) { 191 switch (status) {
194 case AE_OK: 192 case AE_OK:
195 root->id.segment = (u16) value; 193 root->id.segment = (u16) value;
196 break; 194 break;
197 case AE_NOT_FOUND: 195 case AE_NOT_FOUND:
198 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 196 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
199 "Assuming segment 0 (no _SEG)\n")); 197 "Assuming segment 0 (no _SEG)\n"));
200 root->id.segment = 0; 198 root->id.segment = 0;
201 break; 199 break;
202 default: 200 default:
@@ -210,8 +208,8 @@ acpi_pci_root_add (
210 * --- 208 * ---
211 * Obtained via _BBN, if exists, otherwise assumed to be zero (0). 209 * Obtained via _BBN, if exists, otherwise assumed to be zero (0).
212 */ 210 */
213 status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL, 211 status = acpi_evaluate_integer(root->handle, METHOD_NAME__BBN, NULL,
214 &value); 212 &value);
215 switch (status) { 213 switch (status) {
216 case AE_OK: 214 case AE_OK:
217 root->id.bus = (u16) value; 215 root->id.bus = (u16) value;
@@ -229,18 +227,19 @@ acpi_pci_root_add (
229 /* Some systems have wrong _BBN */ 227 /* Some systems have wrong _BBN */
230 list_for_each_entry(tmp, &acpi_pci_roots, node) { 228 list_for_each_entry(tmp, &acpi_pci_roots, node) {
231 if ((tmp->id.segment == root->id.segment) 229 if ((tmp->id.segment == root->id.segment)
232 && (tmp->id.bus == root->id.bus)) { 230 && (tmp->id.bus == root->id.bus)) {
233 int bus = 0; 231 int bus = 0;
234 acpi_status status; 232 acpi_status status;
235 233
236 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 234 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
237 "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n")); 235 "Wrong _BBN value, please reboot and using option 'pci=noacpi'\n"));
238 236
239 status = try_get_root_bridge_busnr(root->handle, &bus); 237 status = try_get_root_bridge_busnr(root->handle, &bus);
240 if (ACPI_FAILURE(status)) 238 if (ACPI_FAILURE(status))
241 break; 239 break;
242 if (bus != root->id.bus) { 240 if (bus != root->id.bus) {
243 printk(KERN_INFO PREFIX "PCI _CRS %d overrides _BBN 0\n", bus); 241 printk(KERN_INFO PREFIX
242 "PCI _CRS %d overrides _BBN 0\n", bus);
244 root->id.bus = bus; 243 root->id.bus = bus;
245 } 244 }
246 break; 245 break;
@@ -258,12 +257,12 @@ acpi_pci_root_add (
258 * TBD: Need PCI interface for enumeration/configuration of roots. 257 * TBD: Need PCI interface for enumeration/configuration of roots.
259 */ 258 */
260 259
261 /* TBD: Locking */ 260 /* TBD: Locking */
262 list_add_tail(&root->node, &acpi_pci_roots); 261 list_add_tail(&root->node, &acpi_pci_roots);
263 262
264 printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n", 263 printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
265 acpi_device_name(device), acpi_device_bid(device), 264 acpi_device_name(device), acpi_device_bid(device),
266 root->id.segment, root->id.bus); 265 root->id.segment, root->id.bus);
267 266
268 /* 267 /*
269 * Scan the Root Bridge 268 * Scan the Root Bridge
@@ -274,9 +273,9 @@ acpi_pci_root_add (
274 */ 273 */
275 root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus); 274 root->bus = pci_acpi_scan_root(device, root->id.segment, root->id.bus);
276 if (!root->bus) { 275 if (!root->bus) {
277 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 276 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
278 "Bus %04x:%02x not present in PCI namespace\n", 277 "Bus %04x:%02x not present in PCI namespace\n",
279 root->id.segment, root->id.bus)); 278 root->id.segment, root->id.bus));
280 result = -ENODEV; 279 result = -ENODEV;
281 goto end; 280 goto end;
282 } 281 }
@@ -298,9 +297,9 @@ acpi_pci_root_add (
298 status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle); 297 status = acpi_get_handle(root->handle, METHOD_NAME__PRT, &handle);
299 if (ACPI_SUCCESS(status)) 298 if (ACPI_SUCCESS(status))
300 result = acpi_pci_irq_add_prt(root->handle, root->id.segment, 299 result = acpi_pci_irq_add_prt(root->handle, root->id.segment,
301 root->id.bus); 300 root->id.bus);
302 301
303end: 302 end:
304 if (result) { 303 if (result) {
305 if (!list_empty(&root->node)) 304 if (!list_empty(&root->node))
306 list_del(&root->node); 305 list_del(&root->node);
@@ -310,11 +309,9 @@ end:
310 return_VALUE(result); 309 return_VALUE(result);
311} 310}
312 311
313static int 312static int acpi_pci_root_start(struct acpi_device *device)
314acpi_pci_root_start (
315 struct acpi_device *device)
316{ 313{
317 struct acpi_pci_root *root; 314 struct acpi_pci_root *root;
318 315
319 ACPI_FUNCTION_TRACE("acpi_pci_root_start"); 316 ACPI_FUNCTION_TRACE("acpi_pci_root_start");
320 317
@@ -327,27 +324,23 @@ acpi_pci_root_start (
327 return_VALUE(-ENODEV); 324 return_VALUE(-ENODEV);
328} 325}
329 326
330static int 327static int acpi_pci_root_remove(struct acpi_device *device, int type)
331acpi_pci_root_remove (
332 struct acpi_device *device,
333 int type)
334{ 328{
335 struct acpi_pci_root *root = NULL; 329 struct acpi_pci_root *root = NULL;
336 330
337 ACPI_FUNCTION_TRACE("acpi_pci_root_remove"); 331 ACPI_FUNCTION_TRACE("acpi_pci_root_remove");
338 332
339 if (!device || !acpi_driver_data(device)) 333 if (!device || !acpi_driver_data(device))
340 return_VALUE(-EINVAL); 334 return_VALUE(-EINVAL);
341 335
342 root = (struct acpi_pci_root *) acpi_driver_data(device); 336 root = (struct acpi_pci_root *)acpi_driver_data(device);
343 337
344 kfree(root); 338 kfree(root);
345 339
346 return_VALUE(0); 340 return_VALUE(0);
347} 341}
348 342
349 343static int __init acpi_pci_root_init(void)
350static int __init acpi_pci_root_init (void)
351{ 344{
352 ACPI_FUNCTION_TRACE("acpi_pci_root_init"); 345 ACPI_FUNCTION_TRACE("acpi_pci_root_init");
353 346
@@ -355,8 +348,8 @@ static int __init acpi_pci_root_init (void)
355 return_VALUE(0); 348 return_VALUE(0);
356 349
357 /* DEBUG: 350 /* DEBUG:
358 acpi_dbg_layer = ACPI_PCI_COMPONENT; 351 acpi_dbg_layer = ACPI_PCI_COMPONENT;
359 acpi_dbg_level = 0xFFFFFFFF; 352 acpi_dbg_level = 0xFFFFFFFF;
360 */ 353 */
361 354
362 if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) 355 if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
@@ -366,4 +359,3 @@ static int __init acpi_pci_root_init (void)
366} 359}
367 360
368subsys_initcall(acpi_pci_root_init); 361subsys_initcall(acpi_pci_root_init);
369