aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <thierry.reding@avionic-design.de>2013-05-16 11:55:18 -0400
committerJason Cooper <jason@lakedaemon.net>2013-05-19 16:30:10 -0400
commit45ab9702fb47d18dca116b3a0509efa19fbcb27a (patch)
tree60b73d1c507a8432318e832b5c008e7896ef4e62
parent29b635c00f3ebcdaf7a52c4948f6d948ad3757d3 (diff)
of/pci: Add of_pci_get_devfn() function
This function can be used to parse the device and function number from a standard 5-cell PCI resource. PCI_SLOT() and PCI_FUNC() can be used on the returned value obtain the device and function numbers respectively. Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r--drivers/of/of_pci.c34
-rw-r--r--include/linux/of_pci.h1
2 files changed, 30 insertions, 5 deletions
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 13e37e2d8ec1..4dd7b9b80076 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -5,14 +5,15 @@
5#include <asm/prom.h> 5#include <asm/prom.h>
6 6
7static inline int __of_pci_pci_compare(struct device_node *node, 7static inline int __of_pci_pci_compare(struct device_node *node,
8 unsigned int devfn) 8 unsigned int data)
9{ 9{
10 unsigned int size; 10 int devfn;
11 const __be32 *reg = of_get_property(node, "reg", &size);
12 11
13 if (!reg || size < 5 * sizeof(__be32)) 12 devfn = of_pci_get_devfn(node);
13 if (devfn < 0)
14 return 0; 14 return 0;
15 return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn; 15
16 return devfn == data;
16} 17}
17 18
18struct device_node *of_pci_find_child_device(struct device_node *parent, 19struct device_node *of_pci_find_child_device(struct device_node *parent,
@@ -40,3 +41,26 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
40 return NULL; 41 return NULL;
41} 42}
42EXPORT_SYMBOL_GPL(of_pci_find_child_device); 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);
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index bb115deb7612..91ec484e0045 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -10,5 +10,6 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq);
10struct device_node; 10struct device_node;
11struct device_node *of_pci_find_child_device(struct device_node *parent, 11struct device_node *of_pci_find_child_device(struct device_node *parent,
12 unsigned int devfn); 12 unsigned int devfn);
13int of_pci_get_devfn(struct device_node *np);
13 14
14#endif 15#endif