Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
587 | giacomo | 1 | /* |
2 | * drivers/pci/setup-irq.c |
||
3 | * |
||
4 | * Extruded from code written by |
||
5 | * Dave Rusling (david.rusling@reo.mts.dec.com) |
||
6 | * David Mosberger (davidm@cs.arizona.edu) |
||
7 | * David Miller (davem@redhat.com) |
||
8 | * |
||
9 | * Support routines for initializing a PCI subsystem. |
||
10 | */ |
||
11 | |||
12 | #include <linuxcomp.h> |
||
13 | |||
14 | #include <linux/init.h> |
||
15 | #include <linux/kernel.h> |
||
16 | #include <linux/pci.h> |
||
17 | #include <linux/errno.h> |
||
18 | #include <linux/ioport.h> |
||
19 | #include <linux/cache.h> |
||
20 | |||
21 | |||
22 | #define DEBUG_CONFIG 0 |
||
23 | #if DEBUG_CONFIG |
||
24 | # define DBGC(args) printk args |
||
25 | #else |
||
26 | # define DBGC(args) |
||
27 | #endif |
||
28 | |||
29 | |||
30 | static void __init |
||
31 | pdev_fixup_irq(struct pci_dev *dev, |
||
32 | u8 (*swizzle)(struct pci_dev *, u8 *), |
||
33 | int (*map_irq)(struct pci_dev *, u8, u8)) |
||
34 | { |
||
35 | u8 pin, slot; |
||
36 | int irq; |
||
37 | |||
38 | /* If this device is not on the primary bus, we need to figure out |
||
39 | which interrupt pin it will come in on. We know which slot it |
||
40 | will come in on 'cos that slot is where the bridge is. Each |
||
41 | time the interrupt line passes through a PCI-PCI bridge we must |
||
42 | apply the swizzle function. */ |
||
43 | |||
44 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); |
||
45 | /* Cope with 0 and illegal. */ |
||
46 | if (pin == 0 || pin > 4) |
||
47 | pin = 1; |
||
48 | |||
49 | /* Follow the chain of bridges, swizzling as we go. */ |
||
50 | slot = (*swizzle)(dev, &pin); |
||
51 | |||
52 | irq = (*map_irq)(dev, slot, pin); |
||
53 | if (irq == -1) |
||
54 | irq = 0; |
||
55 | dev->irq = irq; |
||
56 | |||
57 | DBGC((KERN_ERR "PCI fixup irq: (%s) got %d\n", dev->dev.name, dev->irq)); |
||
58 | |||
59 | /* Always tell the device, so the driver knows what is |
||
60 | the real IRQ to use; the device does not use it. */ |
||
61 | pcibios_update_irq(dev, irq); |
||
62 | } |
||
63 | |||
64 | void __init |
||
65 | pci_fixup_irqs(u8 (*swizzle)(struct pci_dev *, u8 *), |
||
66 | int (*map_irq)(struct pci_dev *, u8, u8)) |
||
67 | { |
||
68 | struct pci_dev *dev = NULL; |
||
69 | while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
||
70 | pdev_fixup_irq(dev, swizzle, map_irq); |
||
71 | } |
||
72 | } |