summaryrefslogtreecommitdiff
path: root/drivers/of
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/Kconfig3
-rw-r--r--drivers/of/Makefile3
-rw-r--r--drivers/of/address.c75
-rw-r--r--drivers/of/base.c12
-rw-r--r--drivers/of/fdt.c2
-rw-r--r--drivers/of/of_pci.c59
-rw-r--r--drivers/of/pdt.c2
7 files changed, 136 insertions, 20 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index d37bfcf5a3a2..80e5c13b930d 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -48,9 +48,6 @@ config OF_IRQ
def_bool y
depends on !SPARC
-config OF_DEVICE
- def_bool y
-
config OF_I2C
def_tristate I2C
depends on I2C
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index e027f444d10c..1f9c0c492ef9 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,9 +1,8 @@
-obj-y = base.o
+obj-y = base.o device.o platform.o
obj-$(CONFIG_OF_FLATTREE) += fdt.o
obj-$(CONFIG_OF_PROMTREE) += pdt.o
obj-$(CONFIG_OF_ADDRESS) += address.o
obj-$(CONFIG_OF_IRQ) += irq.o
-obj-$(CONFIG_OF_DEVICE) += device.o platform.o
obj-$(CONFIG_OF_I2C) += of_i2c.o
obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_SELFTEST) += selftest.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 04da786c84d2..b55c21890760 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -106,8 +106,12 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
static int of_bus_pci_match(struct device_node *np)
{
- /* "vci" is for the /chaos bridge on 1st-gen PCI powermacs */
- return !strcmp(np->type, "pci") || !strcmp(np->type, "vci");
+ /*
+ * "vci" is for the /chaos bridge on 1st-gen PCI powermacs
+ * "ht" is hypertransport
+ */
+ return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") ||
+ !strcmp(np->type, "ht");
}
static void of_bus_pci_count_cells(struct device_node *np,
@@ -227,6 +231,73 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
}
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
+
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ const int na = 3, ns = 2;
+ int rlen;
+
+ parser->node = node;
+ parser->pna = of_n_addr_cells(node);
+ parser->np = parser->pna + na + ns;
+
+ parser->range = of_get_property(node, "ranges", &rlen);
+ if (parser->range == NULL)
+ return -ENOENT;
+
+ parser->end = parser->range + rlen / sizeof(__be32);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ const int na = 3, ns = 2;
+
+ if (!range)
+ return NULL;
+
+ if (!parser->range || parser->range + parser->np > parser->end)
+ return NULL;
+
+ range->pci_space = parser->range[0];
+ range->flags = of_bus_pci_get_flags(parser->range);
+ range->pci_addr = of_read_number(parser->range + 1, ns);
+ range->cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+ parser->range += parser->np;
+
+ /* Now consume following elements while they are contiguous */
+ while (parser->range + parser->np <= parser->end) {
+ u32 flags, pci_space;
+ u64 pci_addr, cpu_addr, size;
+
+ pci_space = be32_to_cpup(parser->range);
+ flags = of_bus_pci_get_flags(parser->range);
+ pci_addr = of_read_number(parser->range + 1, ns);
+ cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ size = of_read_number(parser->range + parser->pna + na, ns);
+
+ if (flags != range->flags)
+ break;
+ if (pci_addr != range->pci_addr + range->size ||
+ cpu_addr != range->cpu_addr + range->size)
+ break;
+
+ range->size += size;
+ parser->range += parser->np;
+ }
+
+ return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+
#endif /* CONFIG_PCI */
/*
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a6f584a7f4a1..5c5427918eb2 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -812,7 +812,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
- * @out_value: pointer to return value, modified only if return value is 0.
+ * @out_values: pointer to return value, modified only if return value is 0.
* @sz: number of array elements to read
*
* Search for a property in a device node and read 8-bit value(s) from
@@ -823,7 +823,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
* dts entry of array should be like:
* property = /bits/ 8 <0x50 0x60 0x70>;
*
- * The out_value is modified only if a valid u8 value can be decoded.
+ * The out_values is modified only if a valid u8 value can be decoded.
*/
int of_property_read_u8_array(const struct device_node *np,
const char *propname, u8 *out_values, size_t sz)
@@ -845,7 +845,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u8_array);
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
- * @out_value: pointer to return value, modified only if return value is 0.
+ * @out_values: pointer to return value, modified only if return value is 0.
* @sz: number of array elements to read
*
* Search for a property in a device node and read 16-bit value(s) from
@@ -856,7 +856,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u8_array);
* dts entry of array should be like:
* property = /bits/ 16 <0x5000 0x6000 0x7000>;
*
- * The out_value is modified only if a valid u16 value can be decoded.
+ * The out_values is modified only if a valid u16 value can be decoded.
*/
int of_property_read_u16_array(const struct device_node *np,
const char *propname, u16 *out_values, size_t sz)
@@ -879,7 +879,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u16_array);
*
* @np: device node from which the property value is to be read.
* @propname: name of the property to be searched.
- * @out_value: pointer to return value, modified only if return value is 0.
+ * @out_values: pointer to return value, modified only if return value is 0.
* @sz: number of array elements to read
*
* Search for a property in a device node and read 32-bit value(s) from
@@ -887,7 +887,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u16_array);
* -ENODATA if property does not have a value, and -EOVERFLOW if the
* property data isn't large enough.
*
- * The out_value is modified only if a valid u32 value can be decoded.
+ * The out_values is modified only if a valid u32 value can be decoded.
*/
int of_property_read_u32_array(const struct device_node *np,
const char *propname, u32 *out_values,
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 808be06bb67e..6bb7cf2de556 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -709,7 +709,7 @@ void __init unflatten_device_tree(void)
__unflatten_device_tree(initial_boot_params, &of_allnodes,
early_init_dt_alloc_memory_arch);
- /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
+ /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
of_alias_scan(early_init_dt_alloc_memory_arch);
}
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
index 13e37e2d8ec1..42c687a820ac 100644
--- a/drivers/of/of_pci.c
+++ b/drivers/of/of_pci.c
@@ -5,14 +5,15 @@
#include <asm/prom.h>
static inline int __of_pci_pci_compare(struct device_node *node,
- unsigned int devfn)
+ unsigned int data)
{
- unsigned int size;
- const __be32 *reg = of_get_property(node, "reg", &size);
+ int devfn;
- if (!reg || size < 5 * sizeof(__be32))
+ devfn = of_pci_get_devfn(node);
+ if (devfn < 0)
return 0;
- return ((be32_to_cpup(&reg[0]) >> 8) & 0xff) == devfn;
+
+ return devfn == data;
}
struct device_node *of_pci_find_child_device(struct device_node *parent,
@@ -40,3 +41,51 @@ struct device_node *of_pci_find_child_device(struct device_node *parent,
return NULL;
}
EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+ unsigned int size;
+ const __be32 *reg;
+
+ reg = of_get_property(np, "reg", &size);
+
+ if (!reg || size < 5 * sizeof(__be32))
+ return -EINVAL;
+
+ return (be32_to_cpup(reg) >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+ const __be32 *values;
+ int len;
+
+ values = of_get_property(node, "bus-range", &len);
+ if (!values || len < sizeof(*values) * 2)
+ return -EINVAL;
+
+ res->name = node->name;
+ res->start = be32_to_cpup(values++);
+ res->end = be32_to_cpup(values);
+ res->flags = IORESOURCE_BUS;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c
index 37b56fd716e6..4ec19cbee57f 100644
--- a/drivers/of/pdt.c
+++ b/drivers/of/pdt.c
@@ -251,6 +251,6 @@ void __init of_pdt_build_devicetree(phandle root_node, struct of_pdt_ops *ops)
of_allnodes->child = of_pdt_build_tree(of_allnodes,
of_pdt_prom_ops->getchild(of_allnodes->phandle), &nextp);
- /* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */
+ /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
of_alias_scan(kernel_tree_alloc);
}