1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <linux/errno.h>
16#include <linux/ioport.h>
17#include <linux/cache.h>
18
19void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
20{
21 dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq);
22 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
23}
24
25static void pdev_fixup_irq(struct pci_dev *dev,
26 u8 (*swizzle)(struct pci_dev *, u8 *),
27 int (*map_irq)(const struct pci_dev *, u8, u8))
28{
29 u8 pin, slot;
30 int irq = 0;
31
32
33
34
35
36
37
38 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
39
40 if (pin > 4)
41 pin = 1;
42
43 if (pin != 0) {
44
45 slot = (*swizzle)(dev, &pin);
46
47 irq = (*map_irq)(dev, slot, pin);
48 if (irq == -1)
49 irq = 0;
50 }
51 dev->irq = irq;
52
53 dev_dbg(&dev->dev, "fixup irq: got %d\n", dev->irq);
54
55
56
57 pcibios_update_irq(dev, irq);
58}
59
60void pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *),
61 int (*map_irq)(const struct pci_dev *, u8, u8))
62{
63 struct pci_dev *dev = NULL;
64
65 for_each_pci_dev(dev)
66 pdev_fixup_irq(dev, swizzle, map_irq);
67}
68EXPORT_SYMBOL_GPL(pci_fixup_irqs);
69