Commit 33714881 authored by Jeremy Kerr's avatar Jeremy Kerr Committed by Grant Likely

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: default avatarJeremy Kerr <jeremy.kerr@canonical.com>
Signed-off-by: default avatarGrant Likely <grant.likely@secretlab.ca>
parent 2e89e685
...@@ -38,7 +38,7 @@ int of_n_addr_cells(struct device_node *np) ...@@ -38,7 +38,7 @@ int of_n_addr_cells(struct device_node *np)
np = np->parent; np = np->parent;
ip = of_get_property(np, "#address-cells", NULL); ip = of_get_property(np, "#address-cells", NULL);
if (ip) if (ip)
return *ip; return be32_to_cpup(ip);
} while (np->parent); } while (np->parent);
/* No #address-cells property for the root node */ /* No #address-cells property for the root node */
return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
...@@ -54,7 +54,7 @@ int of_n_size_cells(struct device_node *np) ...@@ -54,7 +54,7 @@ int of_n_size_cells(struct device_node *np)
np = np->parent; np = np->parent;
ip = of_get_property(np, "#size-cells", NULL); ip = of_get_property(np, "#size-cells", NULL);
if (ip) if (ip)
return *ip; return be32_to_cpup(ip);
} while (np->parent); } while (np->parent);
/* No #size-cells property for the root node */ /* No #size-cells property for the root node */
return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
...@@ -696,8 +696,8 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, ...@@ -696,8 +696,8 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
const void **out_args) const void **out_args)
{ {
int ret = -EINVAL; int ret = -EINVAL;
const u32 *list; const __be32 *list;
const u32 *list_end; const __be32 *list_end;
int size; int size;
int cur_index = 0; int cur_index = 0;
struct device_node *node = NULL; struct device_node *node = NULL;
...@@ -711,7 +711,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, ...@@ -711,7 +711,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
list_end = list + size / sizeof(*list); list_end = list + size / sizeof(*list);
while (list < list_end) { while (list < list_end) {
const u32 *cells; const __be32 *cells;
const phandle *phandle; const phandle *phandle;
phandle = list++; phandle = list++;
...@@ -735,7 +735,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name, ...@@ -735,7 +735,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
goto err1; goto err1;
} }
list += *cells; list += be32_to_cpup(cells);
if (list > list_end) { if (list > list_end) {
pr_debug("%s: insufficient arguments length\n", pr_debug("%s: insufficient arguments length\n",
np->full_name); np->full_name);
......
...@@ -51,7 +51,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, ...@@ -51,7 +51,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
int depth = -1; int depth = -1;
do { do {
u32 tag = *((u32 *)p); u32 tag = be32_to_cpup((__be32 *)p);
char *pathp; char *pathp;
p += 4; p += 4;
...@@ -64,7 +64,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node, ...@@ -64,7 +64,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
if (tag == OF_DT_END) if (tag == OF_DT_END)
break; break;
if (tag == OF_DT_PROP) { if (tag == OF_DT_PROP) {
u32 sz = *((u32 *)p); u32 sz = be32_to_cpup((__be32 *)p);
p += 8; p += 8;
if (initial_boot_params->version < 0x10) if (initial_boot_params->version < 0x10)
p = _ALIGN(p, sz >= 8 ? 8 : 4); p = _ALIGN(p, sz >= 8 ? 8 : 4);
...@@ -103,9 +103,9 @@ unsigned long __init of_get_flat_dt_root(void) ...@@ -103,9 +103,9 @@ unsigned long __init of_get_flat_dt_root(void)
unsigned long p = ((unsigned long)initial_boot_params) + unsigned long p = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct; initial_boot_params->off_dt_struct;
while (*((u32 *)p) == OF_DT_NOP) while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
p += 4; p += 4;
BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE); BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
p += 4; p += 4;
return _ALIGN(p + strlen((char *)p) + 1, 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, ...@@ -122,7 +122,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
unsigned long p = node; unsigned long p = node;
do { do {
u32 tag = *((u32 *)p); u32 tag = be32_to_cpup((__be32 *)p);
u32 sz, noff; u32 sz, noff;
const char *nstr; const char *nstr;
...@@ -132,8 +132,8 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, ...@@ -132,8 +132,8 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
if (tag != OF_DT_PROP) if (tag != OF_DT_PROP)
return NULL; return NULL;
sz = *((u32 *)p); sz = be32_to_cpup((__be32 *)p);
noff = *((u32 *)(p + 4)); noff = be32_to_cpup((__be32 *)(p + 4));
p += 8; p += 8;
if (initial_boot_params->version < 0x10) if (initial_boot_params->version < 0x10)
p = _ALIGN(p, sz >= 8 ? 8 : 4); p = _ALIGN(p, sz >= 8 ? 8 : 4);
...@@ -210,7 +210,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, ...@@ -210,7 +210,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
int has_name = 0; int has_name = 0;
int new_format = 0; int new_format = 0;
tag = *((u32 *)(*p)); tag = be32_to_cpup((__be32 *)(*p));
if (tag != OF_DT_BEGIN_NODE) { if (tag != OF_DT_BEGIN_NODE) {
pr_err("Weird tag at start of node: %x\n", tag); pr_err("Weird tag at start of node: %x\n", tag);
return mem; return mem;
...@@ -285,7 +285,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, ...@@ -285,7 +285,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
u32 sz, noff; u32 sz, noff;
char *pname; char *pname;
tag = *((u32 *)(*p)); tag = be32_to_cpup((__be32 *)(*p));
if (tag == OF_DT_NOP) { if (tag == OF_DT_NOP) {
*p += 4; *p += 4;
continue; continue;
...@@ -293,8 +293,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem, ...@@ -293,8 +293,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
if (tag != OF_DT_PROP) if (tag != OF_DT_PROP)
break; break;
*p += 4; *p += 4;
sz = *((u32 *)(*p)); sz = be32_to_cpup((__be32 *)(*p));
noff = *((u32 *)((*p) + 4)); noff = be32_to_cpup((__be32 *)((*p) + 4));
*p += 8; *p += 8;
if (initial_boot_params->version < 0x10) if (initial_boot_params->version < 0x10)
*p = _ALIGN(*p, sz >= 8 ? 8 : 4); *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
...@@ -367,7 +367,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, ...@@ -367,7 +367,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
} }
while (tag == OF_DT_BEGIN_NODE) { while (tag == OF_DT_BEGIN_NODE) {
mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
tag = *((u32 *)(*p)); tag = be32_to_cpup((__be32 *)(*p));
} }
if (tag != OF_DT_END_NODE) { if (tag != OF_DT_END_NODE) {
pr_err("Weird tag at end of node: %x\n", tag); pr_err("Weird tag at end of node: %x\n", tag);
...@@ -385,7 +385,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, ...@@ -385,7 +385,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
void __init early_init_dt_check_for_initrd(unsigned long node) void __init early_init_dt_check_for_initrd(unsigned long node)
{ {
unsigned long start, end, len; unsigned long start, end, len;
u32 *prop; __be32 *prop;
pr_debug("Looking for initrd properties... "); pr_debug("Looking for initrd properties... ");
...@@ -414,17 +414,22 @@ inline void early_init_dt_check_for_initrd(unsigned long node) ...@@ -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 __init early_init_dt_scan_root(unsigned long node, const char *uname,
int depth, void *data) int depth, void *data)
{ {
u32 *prop; __be32 *prop;
if (depth != 0) if (depth != 0)
return 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); 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); pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
prop = of_get_flat_dt_prop(node, "#address-cells", NULL); 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); pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
/* break now */ /* break now */
...@@ -549,7 +554,7 @@ void __init unflatten_device_tree(void) ...@@ -549,7 +554,7 @@ void __init unflatten_device_tree(void)
mem = lmb_alloc(size + 4, __alignof__(struct device_node)); mem = lmb_alloc(size + 4, __alignof__(struct device_node));
mem = (unsigned long) __va(mem); mem = (unsigned long) __va(mem);
((u32 *)mem)[size / 4] = 0xdeadbeef; ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
pr_debug(" unflattening %lx...\n", mem); pr_debug(" unflattening %lx...\n", mem);
...@@ -557,11 +562,11 @@ void __init unflatten_device_tree(void) ...@@ -557,11 +562,11 @@ void __init unflatten_device_tree(void)
start = ((unsigned long)initial_boot_params) + start = ((unsigned long)initial_boot_params) +
initial_boot_params->off_dt_struct; initial_boot_params->off_dt_struct;
unflatten_dt_node(mem, &start, NULL, &allnextp, 0); 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)); 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", pr_warning("End of tree marker overwritten: %08x\n",
((u32 *)mem)[size / 4]); be32_to_cpu(((__be32 *)mem)[size / 4]));
*allnextp = NULL; *allnextp = NULL;
/* Get pointer to OF "/chosen" node for use everywhere */ /* Get pointer to OF "/chosen" node for use everywhere */
......
...@@ -36,7 +36,7 @@ int of_get_gpio_flags(struct device_node *np, int index, ...@@ -36,7 +36,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
struct of_gpio_chip *of_gc = NULL; struct of_gpio_chip *of_gc = NULL;
int size; int size;
const void *gpio_spec; const void *gpio_spec;
const u32 *gpio_cells; const __be32 *gpio_cells;
ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
&gc, &gpio_spec); &gc, &gpio_spec);
...@@ -55,7 +55,7 @@ int of_get_gpio_flags(struct device_node *np, int index, ...@@ -55,7 +55,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
gpio_cells = of_get_property(gc, "#gpio-cells", &size); gpio_cells = of_get_property(gc, "#gpio-cells", &size);
if (!gpio_cells || size != sizeof(*gpio_cells) || if (!gpio_cells || size != sizeof(*gpio_cells) ||
*gpio_cells != of_gc->gpio_cells) { be32_to_cpup(gpio_cells) != of_gc->gpio_cells) {
pr_debug("%s: wrong #gpio-cells for %s\n", pr_debug("%s: wrong #gpio-cells for %s\n",
np->full_name, gc->full_name); np->full_name, gc->full_name);
ret = -EINVAL; ret = -EINVAL;
...@@ -127,7 +127,8 @@ EXPORT_SYMBOL(of_gpio_count); ...@@ -127,7 +127,8 @@ EXPORT_SYMBOL(of_gpio_count);
int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
const void *gpio_spec, enum of_gpio_flags *flags) const void *gpio_spec, enum of_gpio_flags *flags)
{ {
const u32 *gpio = gpio_spec; const __be32 *gpio = gpio_spec;
const u32 n = be32_to_cpup(gpio);
/* /*
* We're discouraging gpio_cells < 2, since that way you'll have to * We're discouraging gpio_cells < 2, since that way you'll have to
...@@ -140,13 +141,13 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, ...@@ -140,13 +141,13 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
return -EINVAL; return -EINVAL;
} }
if (*gpio > of_gc->gc.ngpio) if (n > of_gc->gc.ngpio)
return -EINVAL; return -EINVAL;
if (flags) if (flags)
*flags = gpio[1]; *flags = be32_to_cpu(gpio[1]);
return *gpio; return n;
} }
EXPORT_SYMBOL(of_gpio_simple_xlate); EXPORT_SYMBOL(of_gpio_simple_xlate);
......
...@@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, ...@@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
for_each_child_of_node(adap_node, node) { for_each_child_of_node(adap_node, node) {
struct i2c_board_info info = {}; struct i2c_board_info info = {};
struct dev_archdata dev_ad = {}; struct dev_archdata dev_ad = {};
const u32 *addr; const __be32 *addr;
int len; int len;
if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
...@@ -40,7 +40,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap, ...@@ -40,7 +40,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
info.irq = irq_of_parse_and_map(node, 0); info.irq = irq_of_parse_and_map(node, 0);
info.addr = *addr; info.addr = be32_to_cpup(addr);
dev_archdata_set_node(&dev_ad, node); dev_archdata_set_node(&dev_ad, node);
info.archdata = &dev_ad; info.archdata = &dev_ad;
......
...@@ -51,7 +51,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) ...@@ -51,7 +51,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
/* Loop over the child nodes and register a phy_device for each one */ /* Loop over the child nodes and register a phy_device for each one */
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
const u32 *addr; const __be32 *addr;
int len; int len;
/* A PHY must have a reg property in the range [0-31] */ /* A PHY must have a reg property in the range [0-31] */
...@@ -68,7 +68,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) ...@@ -68,7 +68,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
mdio->irq[*addr] = PHY_POLL; mdio->irq[*addr] = PHY_POLL;
} }
phy = get_phy_device(mdio, *addr); phy = get_phy_device(mdio, be32_to_cpup(addr));
if (!phy) { if (!phy) {
dev_err(&mdio->dev, "error probing PHY at address %i\n", dev_err(&mdio->dev, "error probing PHY at address %i\n",
*addr); *addr);
...@@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, ...@@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
struct device_node *net_np; struct device_node *net_np;
char bus_id[MII_BUS_ID_SIZE + 3]; char bus_id[MII_BUS_ID_SIZE + 3];
struct phy_device *phy; struct phy_device *phy;
const u32 *phy_id; const __be32 *phy_id;
int sz; int sz;
if (!dev->dev.parent) if (!dev->dev.parent)
...@@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, ...@@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
if (!phy_id || sz < sizeof(*phy_id)) if (!phy_id || sz < sizeof(*phy_id))
return NULL; return NULL;
sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]); sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0]));
phy = phy_connect(dev, bus_id, hndlr, 0, iface); phy = phy_connect(dev, bus_id, hndlr, 0, iface);
return IS_ERR(phy) ? NULL : phy; return IS_ERR(phy) ? NULL : phy;
......
...@@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) ...@@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
{ {
struct spi_device *spi; struct spi_device *spi;
struct device_node *nc; struct device_node *nc;
const u32 *prop; const __be32 *prop;
int rc; int rc;
int len; int len;
...@@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) ...@@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
spi_dev_put(spi); spi_dev_put(spi);
continue; continue;
} }
spi->chip_select = *prop; spi->chip_select = be32_to_cpup(prop);
/* Mode (clock phase/polarity/etc.) */ /* Mode (clock phase/polarity/etc.) */
if (of_find_property(nc, "spi-cpha", NULL)) if (of_find_property(nc, "spi-cpha", NULL))
...@@ -72,7 +72,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np) ...@@ -72,7 +72,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
spi_dev_put(spi); spi_dev_put(spi);
continue; continue;
} }
spi->max_speed_hz = *prop; spi->max_speed_hz = be32_to_cpup(prop);
/* IRQ */ /* IRQ */
spi->irq = irq_of_parse_and_map(nc, 0); spi->irq = irq_of_parse_and_map(nc, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment