@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
+#include <linux/of_pci.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
@@ -245,6 +246,16 @@ void pci_bus_add_device(struct pci_dev *dev)
* are not assigned yet for some devices.
*/
pci_fixup_device(pci_fixup_final, dev);
+ /*
+ * Devices which are hot-added after boot have not
+ * been assigned an irq by the bios.
+ */
+ if (unlikely(!dev->irq)) {
+ dev_dbg(&dev->dev,
+ "PCI device missing IRQ, attempting to assign one\n");
+ pdev_fixup_irq(dev, pci_common_swizzle,
+ of_irq_parse_and_map_pci);
+ }
pci_create_sysfs_dev_files(dev);
pci_proc_attach_device(dev);
@@ -22,7 +22,7 @@ void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
-static void pdev_fixup_irq(struct pci_dev *dev,
+void pdev_fixup_irq(struct pci_dev *dev,
u8 (*swizzle)(struct pci_dev *, u8 *),
int (*map_irq)(const struct pci_dev *, u8, u8))
{
@@ -1056,6 +1056,8 @@ void pci_assign_unassigned_bus_resources(struct pci_bus *bus);
void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus);
void pdev_enable_device(struct pci_dev *);
int pci_enable_resources(struct pci_dev *, int mask);
+void pdev_fixup_irq(struct pci_dev *, u8 (*)(struct pci_dev *, u8 *),
+ int (*)(const struct pci_dev *, u8, u8));
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
int (*)(const struct pci_dev *, u8, u8));
#define HAVE_PCI_REQ_REGIONS 2