setup-irq.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  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 ([email protected])
  7. * David Mosberger ([email protected])
  8. * David Miller ([email protected])
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/pci.h>
  12. #include <linux/errno.h>
  13. #include <linux/ioport.h>
  14. #include <linux/cache.h>
  15. #include "pci.h"
  16. void pci_assign_irq(struct pci_dev *dev)
  17. {
  18. u8 pin;
  19. u8 slot = -1;
  20. int irq = 0;
  21. struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus);
  22. if (!(hbrg->map_irq)) {
  23. pci_dbg(dev, "runtime IRQ mapping not provided by arch\n");
  24. return;
  25. }
  26. /*
  27. * If this device is not on the primary bus, we need to figure out
  28. * which interrupt pin it will come in on. We know which slot it
  29. * will come in on because that slot is where the bridge is. Each
  30. * time the interrupt line passes through a PCI-PCI bridge we must
  31. * apply the swizzle function.
  32. */
  33. pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
  34. /* Cope with illegal. */
  35. if (pin > 4)
  36. pin = 1;
  37. if (pin) {
  38. /* Follow the chain of bridges, swizzling as we go. */
  39. if (hbrg->swizzle_irq)
  40. slot = (*(hbrg->swizzle_irq))(dev, &pin);
  41. /*
  42. * If a swizzling function is not used, map_irq() must
  43. * ignore slot.
  44. */
  45. irq = (*(hbrg->map_irq))(dev, slot, pin);
  46. if (irq == -1)
  47. irq = 0;
  48. }
  49. dev->irq = irq;
  50. pci_dbg(dev, "assign IRQ: got %d\n", dev->irq);
  51. /*
  52. * Always tell the device, so the driver knows what is the real IRQ
  53. * to use; the device does not use it.
  54. */
  55. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
  56. }