Commit | Line | Data |
---|---|---|
7328c8f4 | 1 | // SPDX-License-Identifier: GPL-2.0 |
1da177e4 | 2 | /* |
df62ab5e | 3 | * Support routines for initializing a PCI subsystem |
1da177e4 LT |
4 | * |
5 | * Extruded from code written by | |
6 | * Dave Rusling (david.rusling@reo.mts.dec.com) | |
7 | * David Mosberger (davidm@cs.arizona.edu) | |
8 | * David Miller (davem@redhat.com) | |
1da177e4 LT |
9 | */ |
10 | ||
11 | ||
1da177e4 LT |
12 | #include <linux/kernel.h> |
13 | #include <linux/pci.h> | |
14 | #include <linux/errno.h> | |
15 | #include <linux/ioport.h> | |
16 | #include <linux/cache.h> | |
47a650f2 | 17 | #include "pci.h" |
1da177e4 | 18 | |
47a650f2 | 19 | void pci_assign_irq(struct pci_dev *dev) |
1da177e4 | 20 | { |
47a650f2 MM |
21 | u8 pin; |
22 | u8 slot = -1; | |
691cd0c2 | 23 | int irq = 0; |
47a650f2 MM |
24 | struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus); |
25 | ||
26 | if (!(hbrg->map_irq)) { | |
7506dc79 | 27 | pci_dbg(dev, "runtime IRQ mapping not provided by arch\n"); |
47a650f2 MM |
28 | return; |
29 | } | |
1da177e4 LT |
30 | |
31 | /* If this device is not on the primary bus, we need to figure out | |
32 | which interrupt pin it will come in on. We know which slot it | |
33 | will come in on 'cos that slot is where the bridge is. Each | |
34 | time the interrupt line passes through a PCI-PCI bridge we must | |
35 | apply the swizzle function. */ | |
36 | ||
37 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); | |
691cd0c2 AB |
38 | /* Cope with illegal. */ |
39 | if (pin > 4) | |
1da177e4 LT |
40 | pin = 1; |
41 | ||
47a650f2 | 42 | if (pin) { |
691cd0c2 | 43 | /* Follow the chain of bridges, swizzling as we go. */ |
47a650f2 MM |
44 | if (hbrg->swizzle_irq) |
45 | slot = (*(hbrg->swizzle_irq))(dev, &pin); | |
1da177e4 | 46 | |
47a650f2 MM |
47 | /* |
48 | * If a swizzling function is not used map_irq must | |
49 | * ignore slot | |
50 | */ | |
51 | irq = (*(hbrg->map_irq))(dev, slot, pin); | |
691cd0c2 AB |
52 | if (irq == -1) |
53 | irq = 0; | |
54 | } | |
1da177e4 LT |
55 | dev->irq = irq; |
56 | ||
7506dc79 | 57 | pci_dbg(dev, "assign IRQ: got %d\n", dev->irq); |
1da177e4 LT |
58 | |
59 | /* Always tell the device, so the driver knows what is | |
60 | the real IRQ to use; the device does not use it. */ | |
606799cc | 61 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
1da177e4 | 62 | } |