summaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
authorJeremy Kerr <jeremy.kerr@canonical.com>2010-01-30 09:45:26 +0100
committerGrant Likely <grant.likely@secretlab.ca>2010-02-09 16:34:10 +0100
commit337148812f97368a8ec4a69f1691e4c5ce3af494 (patch)
tree3fa2e5477c657cb2ebc40db9182d0989a5d60e13 /drivers/of/fdt.c
parentof: use __be32 for cell value accessors (diff)
downloadlinux-337148812f97368a8ec4a69f1691e4c5ce3af494.tar.xz
linux-337148812f97368a8ec4a69f1691e4c5ce3af494.zip
of: assume big-endian properties, adding conversions where necessary
Properties in the device tree are specified as big-endian. At present, the only platforms to support device trees are also big-endian, so we've been acessing the properties as raw values. We'd like to add device tree support to little-endian platforms too, so add endian conversion to the sites where we access property values in the common of code. Compiled on powerpc (ppc44x_defconfig & ppc64_defconfig) and arm (fdt support only for now). Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 968a86af5301..5c5f03ef7f06 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -51,7 +51,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
int depth = -1;
do {
- u32 tag = *((u32 *)p);
+ u32 tag = be32_to_cpup((__be32 *)p);
char *pathp;
p += 4;
@@ -64,7 +64,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
if (tag == OF_DT_END)
break;
if (tag == OF_DT_PROP) {
- u32 sz = *((u32 *)p);
+ u32 sz = be32_to_cpup((__be32 *)p);
p += 8;
if (initial_boot_params->version < 0x10)
p = _ALIGN(p, sz >= 8 ? 8 : 4);
@@ -103,9 +103,9 @@ unsigned long __init of_get_flat_dt_root(void)
unsigned long p = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct;
- while (*((u32 *)p) == OF_DT_NOP)
+ while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
p += 4;
- BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE);
+ BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
p += 4;
return _ALIGN(p + strlen((char *)p) + 1, 4);
}
@@ -122,7 +122,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
unsigned long p = node;
do {
- u32 tag = *((u32 *)p);
+ u32 tag = be32_to_cpup((__be32 *)p);
u32 sz, noff;
const char *nstr;
@@ -132,8 +132,8 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
if (tag != OF_DT_PROP)
return NULL;
- sz = *((u32 *)p);
- noff = *((u32 *)(p + 4));
+ sz = be32_to_cpup((__be32 *)p);
+ noff = be32_to_cpup((__be32 *)(p + 4));
p += 8;
if (initial_boot_params->version < 0x10)
p = _ALIGN(p, sz >= 8 ? 8 : 4);
@@ -210,7 +210,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
int has_name = 0;
int new_format = 0;
- tag = *((u32 *)(*p));
+ tag = be32_to_cpup((__be32 *)(*p));
if (tag != OF_DT_BEGIN_NODE) {
pr_err("Weird tag at start of node: %x\n", tag);
return mem;
@@ -285,7 +285,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
u32 sz, noff;
char *pname;
- tag = *((u32 *)(*p));
+ tag = be32_to_cpup((__be32 *)(*p));
if (tag == OF_DT_NOP) {
*p += 4;
continue;
@@ -293,8 +293,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
if (tag != OF_DT_PROP)
break;
*p += 4;
- sz = *((u32 *)(*p));
- noff = *((u32 *)((*p) + 4));
+ sz = be32_to_cpup((__be32 *)(*p));
+ noff = be32_to_cpup((__be32 *)((*p) + 4));
*p += 8;
if (initial_boot_params->version < 0x10)
*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
@@ -367,7 +367,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
}
while (tag == OF_DT_BEGIN_NODE) {
mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
- tag = *((u32 *)(*p));
+ tag = be32_to_cpup((__be32 *)(*p));
}
if (tag != OF_DT_END_NODE) {
pr_err("Weird tag at end of node: %x\n", tag);
@@ -385,7 +385,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
void __init early_init_dt_check_for_initrd(unsigned long node)
{
unsigned long start, end, len;
- u32 *prop;
+ __be32 *prop;
pr_debug("Looking for initrd properties... ");
@@ -414,17 +414,22 @@ inline void early_init_dt_check_for_initrd(unsigned long node)
int __init early_init_dt_scan_root(unsigned long node, const char *uname,
int depth, void *data)
{
- u32 *prop;
+ __be32 *prop;
if (depth != 0)
return 0;
+ dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+ dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+
prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
- dt_root_size_cells = prop ? *prop : OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
+ if (prop)
+ dt_root_size_cells = be32_to_cpup(prop);
pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
- dt_root_addr_cells = prop ? *prop : OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
+ if (prop)
+ dt_root_addr_cells = be32_to_cpup(prop);
pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
/* break now */
@@ -549,7 +554,7 @@ void __init unflatten_device_tree(void)
mem = lmb_alloc(size + 4, __alignof__(struct device_node));
mem = (unsigned long) __va(mem);
- ((u32 *)mem)[size / 4] = 0xdeadbeef;
+ ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
pr_debug(" unflattening %lx...\n", mem);
@@ -557,11 +562,11 @@ void __init unflatten_device_tree(void)
start = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct;
unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
- if (*((u32 *)start) != OF_DT_END)
+ if (be32_to_cpup((__be32 *)start) != OF_DT_END)
pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
- if (((u32 *)mem)[size / 4] != 0xdeadbeef)
+ if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
pr_warning("End of tree marker overwritten: %08x\n",
- ((u32 *)mem)[size / 4]);
+ be32_to_cpu(((__be32 *)mem)[size / 4]));
*allnextp = NULL;
/* Get pointer to OF "/chosen" node for use everywhere */