of: assume big-endian properties, adding conversions where necessary
authorJeremy Kerr <jeremy.kerr@canonical.com>
Sat, 30 Jan 2010 08:45:26 +0000 (01:45 -0700)
committerGrant Likely <grant.likely@secretlab.ca>
Tue, 9 Feb 2010 15:34:10 +0000 (08:34 -0700)
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>
drivers/of/base.c
drivers/of/fdt.c
drivers/of/gpio.c
drivers/of/of_i2c.c
drivers/of/of_mdio.c
drivers/of/of_spi.c

index 524645ab42a4d19cd1b7799554b2ae3741fecc3b..873479a21c804f75c6b3c6a0e2e8d2353ed6af2c 100644 (file)
@@ -38,7 +38,7 @@ int of_n_addr_cells(struct device_node *np)
                        np = np->parent;
                ip = of_get_property(np, "#address-cells", NULL);
                if (ip)
-                       return *ip;
+                       return be32_to_cpup(ip);
        } while (np->parent);
        /* No #address-cells property for the root node */
        return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
@@ -54,7 +54,7 @@ int of_n_size_cells(struct device_node *np)
                        np = np->parent;
                ip = of_get_property(np, "#size-cells", NULL);
                if (ip)
-                       return *ip;
+                       return be32_to_cpup(ip);
        } while (np->parent);
        /* No #size-cells property for the root node */
        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,
                                const void **out_args)
 {
        int ret = -EINVAL;
-       const u32 *list;
-       const u32 *list_end;
+       const __be32 *list;
+       const __be32 *list_end;
        int size;
        int cur_index = 0;
        struct device_node *node = NULL;
@@ -711,7 +711,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
        list_end = list + size / sizeof(*list);
 
        while (list < list_end) {
-               const u32 *cells;
+               const __be32 *cells;
                const phandle *phandle;
 
                phandle = list++;
@@ -735,7 +735,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
                        goto err1;
                }
 
-               list += *cells;
+               list += be32_to_cpup(cells);
                if (list > list_end) {
                        pr_debug("%s: insufficient arguments length\n",
                                 np->full_name);
index 968a86af5301619ba4c80a87a27e3cda43176f0b..5c5f03ef7f0680d146e519ca97d171c6846b83d4 100644 (file)
@@ -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 */
index 6eea601a92043b69f3c95c86aa06ae077327c03a..24c3606217f86a5db00bbf36547ba90d0489e2b2 100644 (file)
@@ -36,7 +36,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
        struct of_gpio_chip *of_gc = NULL;
        int size;
        const void *gpio_spec;
-       const u32 *gpio_cells;
+       const __be32 *gpio_cells;
 
        ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
                                          &gc, &gpio_spec);
@@ -55,7 +55,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
 
        gpio_cells = of_get_property(gc, "#gpio-cells", &size);
        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",
                         np->full_name, gc->full_name);
                ret = -EINVAL;
@@ -127,7 +127,8 @@ EXPORT_SYMBOL(of_gpio_count);
 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 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
@@ -140,13 +141,13 @@ int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
                return -EINVAL;
        }
 
-       if (*gpio > of_gc->gc.ngpio)
+       if (n > of_gc->gc.ngpio)
                return -EINVAL;
 
        if (flags)
-               *flags = gpio[1];
+               *flags = be32_to_cpu(gpio[1]);
 
-       return *gpio;
+       return n;
 }
 EXPORT_SYMBOL(of_gpio_simple_xlate);
 
index fa65a2b2ae2e44737edb5d4e19daf767e331bd9c..a3a708e590d00eabbd2ce62105d2bd4c06bbd922 100644 (file)
@@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
        for_each_child_of_node(adap_node, node) {
                struct i2c_board_info info = {};
                struct dev_archdata dev_ad = {};
-               const u32 *addr;
+               const __be32 *addr;
                int len;
 
                if (of_modalias_node(node, info.type, sizeof(info.type)) < 0)
@@ -40,7 +40,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
 
                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);
                info.archdata = &dev_ad;
index 4b22ba568b19919a1cb81c0164ba248bd90bd17d..18ecae4a4375d461957b04ee8171f1e5e1434b8c 100644 (file)
@@ -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 */
        for_each_child_of_node(np, child) {
-               const u32 *addr;
+               const __be32 *addr;
                int len;
 
                /* 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)
                                mdio->irq[*addr] = PHY_POLL;
                }
 
-               phy = get_phy_device(mdio, *addr);
+               phy = get_phy_device(mdio, be32_to_cpup(addr));
                if (!phy) {
                        dev_err(&mdio->dev, "error probing PHY at address %i\n",
                                *addr);
@@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
        struct device_node *net_np;
        char bus_id[MII_BUS_ID_SIZE + 3];
        struct phy_device *phy;
-       const u32 *phy_id;
+       const __be32 *phy_id;
        int sz;
 
        if (!dev->dev.parent)
@@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
        if (!phy_id || sz < sizeof(*phy_id))
                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);
        return IS_ERR(phy) ? NULL : phy;
index bed0ed6dcdc1329259c58a72e2b697bfbd72e091..f65f48b9844885c9708596c73aa4f7eeefba1904 100644 (file)
@@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
 {
        struct spi_device *spi;
        struct device_node *nc;
-       const u32 *prop;
+       const __be32 *prop;
        int rc;
        int len;
 
@@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
                        spi_dev_put(spi);
                        continue;
                }
-               spi->chip_select = *prop;
+               spi->chip_select = be32_to_cpup(prop);
 
                /* Mode (clock phase/polarity/etc.) */
                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)
                        spi_dev_put(spi);
                        continue;
                }
-               spi->max_speed_hz = *prop;
+               spi->max_speed_hz = be32_to_cpup(prop);
 
                /* IRQ */
                spi->irq = irq_of_parse_and_map(nc, 0);