aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/pci/common.c')
-rw-r--r--arch/x86/pci/common.c34
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 */
522static 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
536static struct notifier_block pci_irq_nb = {
537 .notifier_call = pci_irq_notifier,
538 .priority = INT_MIN,
539};
540
516int __init pcibios_init(void) 541int __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
686void 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
692int pci_ext_cfg_avail(void) 714int pci_ext_cfg_avail(void)
693{ 715{
694 if (raw_pci_ext_ops) 716 if (raw_pci_ext_ops)