Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.12-rc5 136 lines 3.3 kB view raw
1#include <linux/kernel.h> 2#include <linux/export.h> 3#include <linux/of.h> 4#include <linux/of_pci.h> 5#include <asm/prom.h> 6 7static inline int __of_pci_pci_compare(struct device_node *node, 8 unsigned int data) 9{ 10 int devfn; 11 12 devfn = of_pci_get_devfn(node); 13 if (devfn < 0) 14 return 0; 15 16 return devfn == data; 17} 18 19struct device_node *of_pci_find_child_device(struct device_node *parent, 20 unsigned int devfn) 21{ 22 struct device_node *node, *node2; 23 24 for_each_child_of_node(parent, node) { 25 if (__of_pci_pci_compare(node, devfn)) 26 return node; 27 /* 28 * Some OFs create a parent node "multifunc-device" as 29 * a fake root for all functions of a multi-function 30 * device we go down them as well. 31 */ 32 if (!strcmp(node->name, "multifunc-device")) { 33 for_each_child_of_node(node, node2) { 34 if (__of_pci_pci_compare(node2, devfn)) { 35 of_node_put(node); 36 return node2; 37 } 38 } 39 } 40 } 41 return NULL; 42} 43EXPORT_SYMBOL_GPL(of_pci_find_child_device); 44 45/** 46 * of_pci_get_devfn() - Get device and function numbers for a device node 47 * @np: device node 48 * 49 * Parses a standard 5-cell PCI resource and returns an 8-bit value that can 50 * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device 51 * and function numbers respectively. On error a negative error code is 52 * returned. 53 */ 54int of_pci_get_devfn(struct device_node *np) 55{ 56 unsigned int size; 57 const __be32 *reg; 58 59 reg = of_get_property(np, "reg", &size); 60 61 if (!reg || size < 5 * sizeof(__be32)) 62 return -EINVAL; 63 64 return (be32_to_cpup(reg) >> 8) & 0xff; 65} 66EXPORT_SYMBOL_GPL(of_pci_get_devfn); 67 68/** 69 * of_pci_parse_bus_range() - parse the bus-range property of a PCI device 70 * @node: device node 71 * @res: address to a struct resource to return the bus-range 72 * 73 * Returns 0 on success or a negative error-code on failure. 74 */ 75int of_pci_parse_bus_range(struct device_node *node, struct resource *res) 76{ 77 const __be32 *values; 78 int len; 79 80 values = of_get_property(node, "bus-range", &len); 81 if (!values || len < sizeof(*values) * 2) 82 return -EINVAL; 83 84 res->name = node->name; 85 res->start = be32_to_cpup(values++); 86 res->end = be32_to_cpup(values); 87 res->flags = IORESOURCE_BUS; 88 89 return 0; 90} 91EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); 92 93#ifdef CONFIG_PCI_MSI 94 95static LIST_HEAD(of_pci_msi_chip_list); 96static DEFINE_MUTEX(of_pci_msi_chip_mutex); 97 98int of_pci_msi_chip_add(struct msi_chip *chip) 99{ 100 if (!of_property_read_bool(chip->of_node, "msi-controller")) 101 return -EINVAL; 102 103 mutex_lock(&of_pci_msi_chip_mutex); 104 list_add(&chip->list, &of_pci_msi_chip_list); 105 mutex_unlock(&of_pci_msi_chip_mutex); 106 107 return 0; 108} 109EXPORT_SYMBOL_GPL(of_pci_msi_chip_add); 110 111void of_pci_msi_chip_remove(struct msi_chip *chip) 112{ 113 mutex_lock(&of_pci_msi_chip_mutex); 114 list_del(&chip->list); 115 mutex_unlock(&of_pci_msi_chip_mutex); 116} 117EXPORT_SYMBOL_GPL(of_pci_msi_chip_remove); 118 119struct msi_chip *of_pci_find_msi_chip_by_node(struct device_node *of_node) 120{ 121 struct msi_chip *c; 122 123 mutex_lock(&of_pci_msi_chip_mutex); 124 list_for_each_entry(c, &of_pci_msi_chip_list, list) { 125 if (c->of_node == of_node) { 126 mutex_unlock(&of_pci_msi_chip_mutex); 127 return c; 128 } 129 } 130 mutex_unlock(&of_pci_msi_chip_mutex); 131 132 return NULL; 133} 134EXPORT_SYMBOL_GPL(of_pci_find_msi_chip_by_node); 135 136#endif /* CONFIG_PCI_MSI */