of_pci.c 1019 B

12345678910111213141516171819202122232425262728293031323334353637383940
  1. #include <linux/kernel.h>
  2. #include <linux/of_pci.h>
  3. #include <asm/prom.h>
  4. static inline int __of_pci_pci_compare(struct device_node *node,
  5. unsigned int devfn)
  6. {
  7. unsigned int size;
  8. const __be32 *reg = of_get_property(node, "reg", &size);
  9. if (!reg || size < 5 * sizeof(__be32))
  10. return 0;
  11. return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn;
  12. }
  13. struct device_node *of_pci_find_child_device(struct device_node *parent,
  14. unsigned int devfn)
  15. {
  16. struct device_node *node, *node2;
  17. for_each_child_of_node(parent, node) {
  18. if (__of_pci_pci_compare(node, devfn))
  19. return node;
  20. /*
  21. * Some OFs create a parent node "multifunc-device" as
  22. * a fake root for all functions of a multi-function
  23. * device we go down them as well.
  24. */
  25. if (!strcmp(node->name, "multifunc-device")) {
  26. for_each_child_of_node(node, node2) {
  27. if (__of_pci_pci_compare(node2, devfn)) {
  28. of_node_put(node);
  29. return node2;
  30. }
  31. }
  32. }
  33. }
  34. return NULL;
  35. }
  36. EXPORT_SYMBOL_GPL(of_pci_find_child_device);