summaryrefslogtreecommitdiffstats
path: root/drivers/of/address.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 09:44:08 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-03 09:44:08 -0700
commita54dfb1a845c38a97686268d8c4086a63d9493aa (patch)
tree3b31c81672fa89102aae929cc6c1e48e6e9382f4 /drivers/of/address.c
parenteb0ad9c06d51edb5d18a7007fd4d77a8805b2ba7 (diff)
parent36165f55055781a0e4bf32d775241796414504b0 (diff)
downloadop-kernel-dev-a54dfb1a845c38a97686268d8c4086a63d9493aa.zip
op-kernel-dev-a54dfb1a845c38a97686268d8c4086a63d9493aa.tar.gz
Merge tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux
Pull devicetree updates from Rob Herring: - Import of latest upstream device tree compiler (dtc) - New function of_get_child_by_name - Support for #size-cells of 0 and #addr-cells of >2 - Couple of DT binding documentation updates Fix up trivial conflicts due to of_get_child_by_name() having been added next to the new of_get_next_available_child(). * tag 'dt-for-3.7' of git://sources.calxeda.com/kernel/linux: MAINTAINERS: add scripts/dtc under Devicetree maintainers dtc: import latest upstream dtc dt: Document general interrupt controller bindings dt/s3c64xx/spi: Use of_get_child_by_name to get a named child dt: introduce of_get_child_by_name to get child node by name of: i2c: add support for wakeup-source property of/address: Handle #address-cells > 2 specially DT: export of_irq_to_resource_table() devicetree: serial: Add documentation for imx serial devicetree: pwm: mxs-pwm.txt: Fix reg field annotation of: Allow busses with #size-cells=0
Diffstat (limited to 'drivers/of/address.c')
-rw-r--r--drivers/of/address.c35
1 files changed, 31 insertions, 4 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 7e262a6..72e496f 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -9,8 +9,8 @@
/* Max address size we deal with */
#define OF_MAX_ADDR_CELLS 4
-#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
- (ns) > 0)
+#define OF_CHECK_ADDR_COUNT(na) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS)
+#define OF_CHECK_COUNTS(na, ns) (OF_CHECK_ADDR_COUNT(na) && (ns) > 0)
static struct of_bus *of_match_bus(struct device_node *np);
static int __of_address_to_resource(struct device_node *dev,
@@ -69,6 +69,14 @@ static u64 of_bus_default_map(u32 *addr, const __be32 *range,
(unsigned long long)cp, (unsigned long long)s,
(unsigned long long)da);
+ /*
+ * If the number of address cells is larger than 2 we assume the
+ * mapping doesn't specify a physical address. Rather, the address
+ * specifies an identifier that must match exactly.
+ */
+ if (na > 2 && memcmp(range, addr, na * 4) != 0)
+ return OF_BAD_ADDR;
+
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
return da - cp;
@@ -182,7 +190,7 @@ const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
}
bus->count_cells(dev, &na, &ns);
of_node_put(parent);
- if (!OF_CHECK_COUNTS(na, ns))
+ if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
/* Get "reg" or "assigned-addresses" property */
@@ -490,6 +498,25 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
}
EXPORT_SYMBOL(of_translate_dma_address);
+bool of_can_translate_address(struct device_node *dev)
+{
+ struct device_node *parent;
+ struct of_bus *bus;
+ int na, ns;
+
+ parent = of_get_parent(dev);
+ if (parent == NULL)
+ return false;
+
+ bus = of_match_bus(parent);
+ bus->count_cells(dev, &na, &ns);
+
+ of_node_put(parent);
+
+ return OF_CHECK_COUNTS(na, ns);
+}
+EXPORT_SYMBOL(of_can_translate_address);
+
const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
unsigned int *flags)
{
@@ -506,7 +533,7 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
bus = of_match_bus(parent);
bus->count_cells(dev, &na, &ns);
of_node_put(parent);
- if (!OF_CHECK_COUNTS(na, ns))
+ if (!OF_CHECK_ADDR_COUNT(na))
return NULL;
/* Get "reg" or "assigned-addresses" property */
OpenPOWER on IntegriCloud