Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * Support routines for initializing a PCI subsystem 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) 9 : */ 10 : 11 : #include <linux/kernel.h> 12 : #include <linux/pci.h> 13 : #include <linux/errno.h> 14 : #include <linux/ioport.h> 15 : #include <linux/cache.h> 16 : #include "pci.h" 17 : 18 0 : void pci_assign_irq(struct pci_dev *dev) 19 : { 20 : u8 pin; 21 0 : u8 slot = -1; 22 0 : int irq = 0; 23 0 : struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus); 24 : 25 0 : if (!(hbrg->map_irq)) { 26 : pci_dbg(dev, "runtime IRQ mapping not provided by arch\n"); 27 0 : return; 28 : } 29 : 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 because 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 0 : pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 38 : /* Cope with illegal. */ 39 0 : if (pin > 4) 40 0 : pin = 1; 41 : 42 0 : if (pin) { 43 : /* Follow the chain of bridges, swizzling as we go. */ 44 0 : if (hbrg->swizzle_irq) 45 0 : slot = (*(hbrg->swizzle_irq))(dev, &pin); 46 : 47 : /* 48 : * If a swizzling function is not used, map_irq() must 49 : * ignore slot. 50 : */ 51 0 : irq = (*(hbrg->map_irq))(dev, slot, pin); 52 0 : if (irq == -1) 53 0 : irq = 0; 54 : } 55 0 : dev->irq = irq; 56 : 57 : pci_dbg(dev, "assign IRQ: got %d\n", dev->irq); 58 : 59 : /* 60 : * Always tell the device, so the driver knows what is the real IRQ 61 : * to use; the device does not use it. 62 : */ 63 0 : pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); 64 : }