diff options
Diffstat (limited to 'arch/x86/pci/common.c')
-rw-r--r-- | arch/x86/pci/common.c | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2fb384724ebb..3d2612b68694 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -513,6 +513,31 @@ void __init pcibios_set_cache_line_size(void) | |||
513 | } | 513 | } |
514 | } | 514 | } |
515 | 515 | ||
516 | /* | ||
517 | * Some device drivers assume dev->irq won't change after calling | ||
518 | * pci_disable_device(). So delay releasing of IRQ resource to driver | ||
519 | * unbinding time. Otherwise it will break PM subsystem and drivers | ||
520 | * like xen-pciback etc. | ||
521 | */ | ||
522 | static int pci_irq_notifier(struct notifier_block *nb, unsigned long action, | ||
523 | void *data) | ||
524 | { | ||
525 | struct pci_dev *dev = to_pci_dev(data); | ||
526 | |||
527 | if (action != BUS_NOTIFY_UNBOUND_DRIVER) | ||
528 | return NOTIFY_DONE; | ||
529 | |||
530 | if (pcibios_disable_irq) | ||
531 | pcibios_disable_irq(dev); | ||
532 | |||
533 | return NOTIFY_OK; | ||
534 | } | ||
535 | |||
536 | static struct notifier_block pci_irq_nb = { | ||
537 | .notifier_call = pci_irq_notifier, | ||
538 | .priority = INT_MIN, | ||
539 | }; | ||
540 | |||
516 | int __init pcibios_init(void) | 541 | int __init pcibios_init(void) |
517 | { | 542 | { |
518 | if (!raw_pci_ops) { | 543 | if (!raw_pci_ops) { |
@@ -525,6 +550,9 @@ int __init pcibios_init(void) | |||
525 | 550 | ||
526 | if (pci_bf_sort >= pci_force_bf) | 551 | if (pci_bf_sort >= pci_force_bf) |
527 | pci_sort_breadthfirst(); | 552 | pci_sort_breadthfirst(); |
553 | |||
554 | bus_register_notifier(&pci_bus_type, &pci_irq_nb); | ||
555 | |||
528 | return 0; | 556 | return 0; |
529 | } | 557 | } |
530 | 558 | ||
@@ -683,12 +711,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
683 | return 0; | 711 | return 0; |
684 | } | 712 | } |
685 | 713 | ||
686 | void pcibios_disable_device (struct pci_dev *dev) | ||
687 | { | ||
688 | if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq) | ||
689 | pcibios_disable_irq(dev); | ||
690 | } | ||
691 | |||
692 | int pci_ext_cfg_avail(void) | 714 | int pci_ext_cfg_avail(void) |
693 | { | 715 | { |
694 | if (raw_pci_ext_ops) | 716 | if (raw_pci_ext_ops) |