]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - arch/x86/pci/common.c
Merge branch 'acpi-resources'
[mirror_ubuntu-artful-kernel.git] / arch / x86 / pci / common.c
index 2fb384724ebb52d1cf0ba6131b418e81609ca55c..3d2612b68694efd294ca214d478c7777030f4b03 100644 (file)
@@ -513,6 +513,31 @@ void __init pcibios_set_cache_line_size(void)
        }
 }
 
+/*
+ * Some device drivers assume dev->irq won't change after calling
+ * pci_disable_device(). So delay releasing of IRQ resource to driver
+ * unbinding time. Otherwise it will break PM subsystem and drivers
+ * like xen-pciback etc.
+ */
+static int pci_irq_notifier(struct notifier_block *nb, unsigned long action,
+                           void *data)
+{
+       struct pci_dev *dev = to_pci_dev(data);
+
+       if (action != BUS_NOTIFY_UNBOUND_DRIVER)
+               return NOTIFY_DONE;
+
+       if (pcibios_disable_irq)
+               pcibios_disable_irq(dev);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block pci_irq_nb = {
+       .notifier_call = pci_irq_notifier,
+       .priority = INT_MIN,
+};
+
 int __init pcibios_init(void)
 {
        if (!raw_pci_ops) {
@@ -525,6 +550,9 @@ int __init pcibios_init(void)
 
        if (pci_bf_sort >= pci_force_bf)
                pci_sort_breadthfirst();
+
+       bus_register_notifier(&pci_bus_type, &pci_irq_nb);
+
        return 0;
 }
 
@@ -683,12 +711,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
        return 0;
 }
 
-void pcibios_disable_device (struct pci_dev *dev)
-{
-       if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
-               pcibios_disable_irq(dev);
-}
-
 int pci_ext_cfg_avail(void)
 {
        if (raw_pci_ext_ops)