diff options
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r-- | drivers/acpi/pci_root.c | 130 |
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 |
40 | ACPI_MODULE_NAME ("pci_root") | 39 | ACPI_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 | 44 | static int acpi_pci_root_add(struct acpi_device *device); | |
47 | static int acpi_pci_root_add (struct acpi_device *device); | 45 | static int acpi_pci_root_remove(struct acpi_device *device, int type); |
48 | static int acpi_pci_root_remove (struct acpi_device *device, int type); | 46 | static int acpi_pci_root_start(struct acpi_device *device); |
49 | static int acpi_pci_root_start (struct acpi_device *device); | ||
50 | 47 | ||
51 | static struct acpi_driver acpi_pci_root_driver = { | 48 | static 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 | ||
62 | struct acpi_pci_root { | 59 | struct 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 | ||
69 | static LIST_HEAD(acpi_pci_roots); | 66 | static 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 | |||
95 | EXPORT_SYMBOL(acpi_pci_register_driver); | 93 | EXPORT_SYMBOL(acpi_pci_register_driver); |
96 | 94 | ||
97 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | 95 | void 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 | |||
118 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 117 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
119 | 118 | ||
120 | static acpi_status | 119 | static acpi_status |
121 | get_root_bridge_busnr_callback (struct acpi_resource *resource, void *data) | 120 | get_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 | ||
139 | static acpi_status | 138 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, int *busnum) |
140 | try_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 | ||
154 | static int | 154 | static int acpi_pci_root_add(struct acpi_device *device) |
155 | acpi_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 | ||
303 | end: | 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 | ||
313 | static int | 312 | static int acpi_pci_root_start(struct acpi_device *device) |
314 | acpi_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 | ||
330 | static int | 327 | static int acpi_pci_root_remove(struct acpi_device *device, int type) |
331 | acpi_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 | 343 | static int __init acpi_pci_root_init(void) | |
350 | static 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 | ||
368 | subsys_initcall(acpi_pci_root_init); | 361 | subsys_initcall(acpi_pci_root_init); |
369 | |||