of.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * PCI <-> OF mapping helpers
  4. *
  5. * Copyright 2011 IBM Corp.
  6. */
  7. #include <linux/irqdomain.h>
  8. #include <linux/kernel.h>
  9. #include <linux/pci.h>
  10. #include <linux/of.h>
  11. #include <linux/of_irq.h>
  12. #include <linux/of_pci.h>
  13. #include "pci.h"
  14. void pci_set_of_node(struct pci_dev *dev)
  15. {
  16. if (!dev->bus->dev.of_node)
  17. return;
  18. dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
  19. dev->devfn);
  20. }
  21. void pci_release_of_node(struct pci_dev *dev)
  22. {
  23. of_node_put(dev->dev.of_node);
  24. dev->dev.of_node = NULL;
  25. }
  26. void pci_set_bus_of_node(struct pci_bus *bus)
  27. {
  28. if (bus->self == NULL)
  29. bus->dev.of_node = pcibios_get_phb_of_node(bus);
  30. else
  31. bus->dev.of_node = of_node_get(bus->self->dev.of_node);
  32. }
  33. void pci_release_bus_of_node(struct pci_bus *bus)
  34. {
  35. of_node_put(bus->dev.of_node);
  36. bus->dev.of_node = NULL;
  37. }
  38. struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
  39. {
  40. /* This should only be called for PHBs */
  41. if (WARN_ON(bus->self || bus->parent))
  42. return NULL;
  43. /* Look for a node pointer in either the intermediary device we
  44. * create above the root bus or it's own parent. Normally only
  45. * the later is populated.
  46. */
  47. if (bus->bridge->of_node)
  48. return of_node_get(bus->bridge->of_node);
  49. if (bus->bridge->parent && bus->bridge->parent->of_node)
  50. return of_node_get(bus->bridge->parent->of_node);
  51. return NULL;
  52. }
  53. struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
  54. {
  55. #ifdef CONFIG_IRQ_DOMAIN
  56. struct irq_domain *d;
  57. if (!bus->dev.of_node)
  58. return NULL;
  59. /* Start looking for a phandle to an MSI controller. */
  60. d = of_msi_get_domain(&bus->dev, bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
  61. if (d)
  62. return d;
  63. /*
  64. * If we don't have an msi-parent property, look for a domain
  65. * directly attached to the host bridge.
  66. */
  67. d = irq_find_matching_host(bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
  68. if (d)
  69. return d;
  70. return irq_find_host(bus->dev.of_node);
  71. #else
  72. return NULL;
  73. #endif
  74. }