diff options
-rw-r--r-- | drivers/acpi/pci_irq.c | 102 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 18 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 24 | ||||
-rw-r--r-- | include/acpi/acpi_drivers.h | 5 |
4 files changed, 34 insertions, 115 deletions
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 68a921d03247..41c5e1b799ef 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -53,9 +53,6 @@ struct acpi_prt_entry { | |||
53 | u32 index; /* GSI, or link _CRS index */ | 53 | u32 index; /* GSI, or link _CRS index */ |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static LIST_HEAD(acpi_prt_list); | ||
57 | static DEFINE_SPINLOCK(acpi_prt_lock); | ||
58 | |||
59 | static inline char pin_name(int pin) | 56 | static inline char pin_name(int pin) |
60 | { | 57 | { |
61 | return 'A' + pin - 1; | 58 | return 'A' + pin - 1; |
@@ -65,28 +62,6 @@ static inline char pin_name(int pin) | |||
65 | PCI IRQ Routing Table (PRT) Support | 62 | PCI IRQ Routing Table (PRT) Support |
66 | -------------------------------------------------------------------------- */ | 63 | -------------------------------------------------------------------------- */ |
67 | 64 | ||
68 | static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev, | ||
69 | int pin) | ||
70 | { | ||
71 | struct acpi_prt_entry *entry; | ||
72 | int segment = pci_domain_nr(dev->bus); | ||
73 | int bus = dev->bus->number; | ||
74 | int device = PCI_SLOT(dev->devfn); | ||
75 | |||
76 | spin_lock(&acpi_prt_lock); | ||
77 | list_for_each_entry(entry, &acpi_prt_list, list) { | ||
78 | if ((segment == entry->id.segment) | ||
79 | && (bus == entry->id.bus) | ||
80 | && (device == entry->id.device) | ||
81 | && (pin == entry->pin)) { | ||
82 | spin_unlock(&acpi_prt_lock); | ||
83 | return entry; | ||
84 | } | ||
85 | } | ||
86 | spin_unlock(&acpi_prt_lock); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ | 65 | /* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */ |
91 | static const struct dmi_system_id medion_md9580[] = { | 66 | static const struct dmi_system_id medion_md9580[] = { |
92 | { | 67 | { |
@@ -184,11 +159,19 @@ static void do_prt_fixups(struct acpi_prt_entry *entry, | |||
184 | } | 159 | } |
185 | } | 160 | } |
186 | 161 | ||
187 | static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | 162 | static int acpi_pci_irq_check_entry(acpi_handle handle, struct pci_dev *dev, |
188 | struct acpi_pci_routing_table *prt) | 163 | int pin, struct acpi_pci_routing_table *prt, |
164 | struct acpi_prt_entry **entry_ptr) | ||
189 | { | 165 | { |
166 | int segment = pci_domain_nr(dev->bus); | ||
167 | int bus = dev->bus->number; | ||
168 | int device = PCI_SLOT(dev->devfn); | ||
190 | struct acpi_prt_entry *entry; | 169 | struct acpi_prt_entry *entry; |
191 | 170 | ||
171 | if (((prt->address >> 16) & 0xffff) != device || | ||
172 | prt->pin + 1 != pin) | ||
173 | return -ENODEV; | ||
174 | |||
192 | entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); | 175 | entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); |
193 | if (!entry) | 176 | if (!entry) |
194 | return -ENOMEM; | 177 | return -ENOMEM; |
@@ -237,43 +220,37 @@ static int acpi_pci_irq_add_entry(acpi_handle handle, int segment, int bus, | |||
237 | entry->id.device, pin_name(entry->pin), | 220 | entry->id.device, pin_name(entry->pin), |
238 | prt->source, entry->index)); | 221 | prt->source, entry->index)); |
239 | 222 | ||
240 | spin_lock(&acpi_prt_lock); | 223 | *entry_ptr = entry; |
241 | list_add_tail(&entry->list, &acpi_prt_list); | ||
242 | spin_unlock(&acpi_prt_lock); | ||
243 | 224 | ||
244 | return 0; | 225 | return 0; |
245 | } | 226 | } |
246 | 227 | ||
247 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | 228 | static int acpi_pci_irq_find_prt_entry(struct pci_dev *dev, |
229 | int pin, struct acpi_prt_entry **entry_ptr) | ||
248 | { | 230 | { |
249 | acpi_status status; | 231 | acpi_status status; |
250 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 232 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
251 | struct acpi_pci_routing_table *entry; | 233 | struct acpi_pci_routing_table *entry; |
234 | acpi_handle handle = NULL; | ||
252 | 235 | ||
253 | /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ | 236 | if (dev->bus->bridge) |
254 | status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | 237 | handle = ACPI_HANDLE(dev->bus->bridge); |
255 | if (ACPI_FAILURE(status)) | ||
256 | return -ENODEV; | ||
257 | |||
258 | printk(KERN_DEBUG "ACPI: PCI Interrupt Routing Table [%s._PRT]\n", | ||
259 | (char *) buffer.pointer); | ||
260 | |||
261 | kfree(buffer.pointer); | ||
262 | 238 | ||
263 | buffer.length = ACPI_ALLOCATE_BUFFER; | 239 | if (!handle) |
264 | buffer.pointer = NULL; | 240 | return -ENODEV; |
265 | 241 | ||
242 | /* 'handle' is the _PRT's parent (root bridge or PCI-PCI bridge) */ | ||
266 | status = acpi_get_irq_routing_table(handle, &buffer); | 243 | status = acpi_get_irq_routing_table(handle, &buffer); |
267 | if (ACPI_FAILURE(status)) { | 244 | if (ACPI_FAILURE(status)) { |
268 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRT [%s]", | ||
269 | acpi_format_exception(status))); | ||
270 | kfree(buffer.pointer); | 245 | kfree(buffer.pointer); |
271 | return -ENODEV; | 246 | return -ENODEV; |
272 | } | 247 | } |
273 | 248 | ||
274 | entry = buffer.pointer; | 249 | entry = buffer.pointer; |
275 | while (entry && (entry->length > 0)) { | 250 | while (entry && (entry->length > 0)) { |
276 | acpi_pci_irq_add_entry(handle, segment, bus, entry); | 251 | if (!acpi_pci_irq_check_entry(handle, dev, pin, |
252 | entry, entry_ptr)) | ||
253 | break; | ||
277 | entry = (struct acpi_pci_routing_table *) | 254 | entry = (struct acpi_pci_routing_table *) |
278 | ((unsigned long)entry + entry->length); | 255 | ((unsigned long)entry + entry->length); |
279 | } | 256 | } |
@@ -282,23 +259,6 @@ int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus) | |||
282 | return 0; | 259 | return 0; |
283 | } | 260 | } |
284 | 261 | ||
285 | void acpi_pci_irq_del_prt(int segment, int bus) | ||
286 | { | ||
287 | struct acpi_prt_entry *entry, *tmp; | ||
288 | |||
289 | printk(KERN_DEBUG | ||
290 | "ACPI: Delete PCI Interrupt Routing Table for %04x:%02x\n", | ||
291 | segment, bus); | ||
292 | spin_lock(&acpi_prt_lock); | ||
293 | list_for_each_entry_safe(entry, tmp, &acpi_prt_list, list) { | ||
294 | if (segment == entry->id.segment && bus == entry->id.bus) { | ||
295 | list_del(&entry->list); | ||
296 | kfree(entry); | ||
297 | } | ||
298 | } | ||
299 | spin_unlock(&acpi_prt_lock); | ||
300 | } | ||
301 | |||
302 | /* -------------------------------------------------------------------------- | 262 | /* -------------------------------------------------------------------------- |
303 | PCI Interrupt Routing Support | 263 | PCI Interrupt Routing Support |
304 | -------------------------------------------------------------------------- */ | 264 | -------------------------------------------------------------------------- */ |
@@ -359,12 +319,13 @@ static int acpi_reroute_boot_interrupt(struct pci_dev *dev, | |||
359 | 319 | ||
360 | static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | 320 | static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) |
361 | { | 321 | { |
362 | struct acpi_prt_entry *entry; | 322 | struct acpi_prt_entry *entry = NULL; |
363 | struct pci_dev *bridge; | 323 | struct pci_dev *bridge; |
364 | u8 bridge_pin, orig_pin = pin; | 324 | u8 bridge_pin, orig_pin = pin; |
325 | int ret; | ||
365 | 326 | ||
366 | entry = acpi_pci_irq_find_prt_entry(dev, pin); | 327 | ret = acpi_pci_irq_find_prt_entry(dev, pin, &entry); |
367 | if (entry) { | 328 | if (!ret && entry) { |
368 | #ifdef CONFIG_X86_IO_APIC | 329 | #ifdef CONFIG_X86_IO_APIC |
369 | acpi_reroute_boot_interrupt(dev, entry); | 330 | acpi_reroute_boot_interrupt(dev, entry); |
370 | #endif /* CONFIG_X86_IO_APIC */ | 331 | #endif /* CONFIG_X86_IO_APIC */ |
@@ -373,7 +334,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | |||
373 | return entry; | 334 | return entry; |
374 | } | 335 | } |
375 | 336 | ||
376 | /* | 337 | /* |
377 | * Attempt to derive an IRQ for this device from a parent bridge's | 338 | * Attempt to derive an IRQ for this device from a parent bridge's |
378 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). | 339 | * PCI interrupt routing entry (eg. yenta bridge and add-in card bridge). |
379 | */ | 340 | */ |
@@ -393,8 +354,8 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) | |||
393 | pin = bridge_pin; | 354 | pin = bridge_pin; |
394 | } | 355 | } |
395 | 356 | ||
396 | entry = acpi_pci_irq_find_prt_entry(bridge, pin); | 357 | ret = acpi_pci_irq_find_prt_entry(bridge, pin, &entry); |
397 | if (entry) { | 358 | if (!ret && entry) { |
398 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 359 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
399 | "Derived GSI for %s INT %c from %s\n", | 360 | "Derived GSI for %s INT %c from %s\n", |
400 | pci_name(dev), pin_name(orig_pin), | 361 | pci_name(dev), pin_name(orig_pin), |
@@ -470,6 +431,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
470 | dev_warn(&dev->dev, "PCI INT %c: no GSI\n", | 431 | dev_warn(&dev->dev, "PCI INT %c: no GSI\n", |
471 | pin_name(pin)); | 432 | pin_name(pin)); |
472 | } | 433 | } |
434 | |||
473 | return 0; | 435 | return 0; |
474 | } | 436 | } |
475 | 437 | ||
@@ -477,6 +439,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
477 | if (rc < 0) { | 439 | if (rc < 0) { |
478 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", | 440 | dev_warn(&dev->dev, "PCI INT %c: failed to register GSI\n", |
479 | pin_name(pin)); | 441 | pin_name(pin)); |
442 | kfree(entry); | ||
480 | return rc; | 443 | return rc; |
481 | } | 444 | } |
482 | dev->irq = rc; | 445 | dev->irq = rc; |
@@ -491,6 +454,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
491 | (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", | 454 | (triggering == ACPI_LEVEL_SENSITIVE) ? "level" : "edge", |
492 | (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); | 455 | (polarity == ACPI_ACTIVE_LOW) ? "low" : "high", dev->irq); |
493 | 456 | ||
457 | kfree(entry); | ||
494 | return 0; | 458 | return 0; |
495 | } | 459 | } |
496 | 460 | ||
@@ -513,6 +477,8 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
513 | else | 477 | else |
514 | gsi = entry->index; | 478 | gsi = entry->index; |
515 | 479 | ||
480 | kfree(entry); | ||
481 | |||
516 | /* | 482 | /* |
517 | * TBD: It might be worth clearing dev->irq by magic constant | 483 | * TBD: It might be worth clearing dev->irq by magic constant |
518 | * (e.g. PCI_UNDEFINED_IRQ). | 484 | * (e.g. PCI_UNDEFINED_IRQ). |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 417487a201fb..8b5a73b76202 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -416,7 +416,6 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
416 | acpi_status status; | 416 | acpi_status status; |
417 | int result; | 417 | int result; |
418 | struct acpi_pci_root *root; | 418 | struct acpi_pci_root *root; |
419 | acpi_handle handle; | ||
420 | struct acpi_pci_driver *driver; | 419 | struct acpi_pci_driver *driver; |
421 | u32 flags, base_flags; | 420 | u32 flags, base_flags; |
422 | bool is_osc_granted = false; | 421 | bool is_osc_granted = false; |
@@ -471,16 +470,6 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
471 | acpi_device_name(device), acpi_device_bid(device), | 470 | acpi_device_name(device), acpi_device_bid(device), |
472 | root->segment, &root->secondary); | 471 | root->segment, &root->secondary); |
473 | 472 | ||
474 | /* | ||
475 | * PCI Routing Table | ||
476 | * ----------------- | ||
477 | * Evaluate and parse _PRT, if exists. | ||
478 | */ | ||
479 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | ||
480 | if (ACPI_SUCCESS(status)) | ||
481 | result = acpi_pci_irq_add_prt(device->handle, root->segment, | ||
482 | root->secondary.start); | ||
483 | |||
484 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); | 473 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle); |
485 | 474 | ||
486 | /* | 475 | /* |
@@ -605,7 +594,6 @@ out_del_root: | |||
605 | list_del(&root->node); | 594 | list_del(&root->node); |
606 | mutex_unlock(&acpi_pci_root_lock); | 595 | mutex_unlock(&acpi_pci_root_lock); |
607 | 596 | ||
608 | acpi_pci_irq_del_prt(root->segment, root->secondary.start); | ||
609 | end: | 597 | end: |
610 | kfree(root); | 598 | kfree(root); |
611 | return result; | 599 | return result; |
@@ -613,8 +601,6 @@ end: | |||
613 | 601 | ||
614 | static int acpi_pci_root_remove(struct acpi_device *device, int type) | 602 | static int acpi_pci_root_remove(struct acpi_device *device, int type) |
615 | { | 603 | { |
616 | acpi_status status; | ||
617 | acpi_handle handle; | ||
618 | struct acpi_pci_root *root = acpi_driver_data(device); | 604 | struct acpi_pci_root *root = acpi_driver_data(device); |
619 | struct acpi_pci_driver *driver; | 605 | struct acpi_pci_driver *driver; |
620 | 606 | ||
@@ -629,10 +615,6 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
629 | device_set_run_wake(root->bus->bridge, false); | 615 | device_set_run_wake(root->bus->bridge, false); |
630 | pci_acpi_remove_bus_pm_notifier(device); | 616 | pci_acpi_remove_bus_pm_notifier(device); |
631 | 617 | ||
632 | status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); | ||
633 | if (ACPI_SUCCESS(status)) | ||
634 | acpi_pci_irq_del_prt(root->segment, root->secondary.start); | ||
635 | |||
636 | pci_remove_root_bus(root->bus); | 618 | pci_remove_root_bus(root->bus); |
637 | 619 | ||
638 | mutex_lock(&acpi_pci_root_lock); | 620 | mutex_lock(&acpi_pci_root_lock); |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 1c2587c40299..c685ff5e12d2 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -307,25 +307,6 @@ static void pci_acpi_setup(struct device *dev) | |||
307 | struct pci_dev *pci_dev = to_pci_dev(dev); | 307 | struct pci_dev *pci_dev = to_pci_dev(dev); |
308 | acpi_handle handle = ACPI_HANDLE(dev); | 308 | acpi_handle handle = ACPI_HANDLE(dev); |
309 | struct acpi_device *adev; | 309 | struct acpi_device *adev; |
310 | acpi_status status; | ||
311 | acpi_handle dummy; | ||
312 | |||
313 | /* | ||
314 | * Evaluate and parse _PRT, if exists. This code allows parsing of | ||
315 | * _PRT objects within the scope of non-bridge devices. Note that | ||
316 | * _PRTs within the scope of a PCI bridge assume the bridge's | ||
317 | * subordinate bus number. | ||
318 | * | ||
319 | * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? | ||
320 | */ | ||
321 | status = acpi_get_handle(handle, METHOD_NAME__PRT, &dummy); | ||
322 | if (ACPI_SUCCESS(status)) { | ||
323 | unsigned char bus; | ||
324 | |||
325 | bus = pci_dev->subordinate ? | ||
326 | pci_dev->subordinate->number : pci_dev->bus->number; | ||
327 | acpi_pci_irq_add_prt(handle, pci_domain_nr(pci_dev->bus), bus); | ||
328 | } | ||
329 | 310 | ||
330 | acpi_power_resource_register_device(dev, handle); | 311 | acpi_power_resource_register_device(dev, handle); |
331 | if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) | 312 | if (acpi_bus_get_device(handle, &adev) || !adev->wakeup.flags.valid) |
@@ -341,7 +322,6 @@ static void pci_acpi_setup(struct device *dev) | |||
341 | 322 | ||
342 | static void pci_acpi_cleanup(struct device *dev) | 323 | static void pci_acpi_cleanup(struct device *dev) |
343 | { | 324 | { |
344 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
345 | acpi_handle handle = ACPI_HANDLE(dev); | 325 | acpi_handle handle = ACPI_HANDLE(dev); |
346 | struct acpi_device *adev; | 326 | struct acpi_device *adev; |
347 | 327 | ||
@@ -351,10 +331,6 @@ static void pci_acpi_cleanup(struct device *dev) | |||
351 | pci_acpi_remove_pm_notifier(adev); | 331 | pci_acpi_remove_pm_notifier(adev); |
352 | } | 332 | } |
353 | acpi_power_resource_unregister_device(dev, handle); | 333 | acpi_power_resource_unregister_device(dev, handle); |
354 | |||
355 | if (pci_dev->subordinate) | ||
356 | acpi_pci_irq_del_prt(pci_domain_nr(pci_dev->bus), | ||
357 | pci_dev->subordinate->number); | ||
358 | } | 334 | } |
359 | 335 | ||
360 | static struct acpi_bus_type acpi_pci_bus = { | 336 | static struct acpi_bus_type acpi_pci_bus = { |
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index 8b1d7a6a9695..627749af0ba7 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h | |||
@@ -90,11 +90,6 @@ int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering, | |||
90 | int *polarity, char **name); | 90 | int *polarity, char **name); |
91 | int acpi_pci_link_free_irq(acpi_handle handle); | 91 | int acpi_pci_link_free_irq(acpi_handle handle); |
92 | 92 | ||
93 | /* ACPI PCI Interrupt Routing (pci_irq.c) */ | ||
94 | |||
95 | int acpi_pci_irq_add_prt(acpi_handle handle, int segment, int bus); | ||
96 | void acpi_pci_irq_del_prt(int segment, int bus); | ||
97 | |||
98 | /* ACPI PCI Device Binding (pci_bind.c) */ | 93 | /* ACPI PCI Device Binding (pci_bind.c) */ |
99 | 94 | ||
100 | struct pci_bus; | 95 | struct pci_bus; |