of/address: Handle #address-cells > 2 specially
authorThierry Reding <thierry.reding@avionic-design.de>
Thu, 26 Jul 2012 19:55:10 +0000 (21:55 +0200)
committerRob Herring <rob.herring@calxeda.com>
Fri, 7 Sep 2012 16:31:23 +0000 (11:31 -0500)
When a bus specifies #address-cells > 2, of_bus_default_map() now
assumes that the mapping isn't for a physical address but rather an
identifier that needs to match exactly.

This is required by bindings that use multiple cells to translate a
resource to the parent bus (device index, type, ...).

See here for the discussion:

https://lists.ozlabs.org/pipermail/devicetree-discuss/2012-June/016577.html

Originally-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
drivers/of/address.c

index 7a07751428de44c06a75389749d6bfa7d8ad2ac3..72e496f1e9b082d576f439c442a07721330f1928 100644 (file)
@@ -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;