aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorJeremy Kerr <jeremy.kerr@canonical.com>2010-01-30 03:45:26 -0500
committerGrant Likely <grant.likely@secretlab.ca>2010-02-09 10:34:10 -0500
commit337148812f97368a8ec4a69f1691e4c5ce3af494 (patch)
tree3fa2e5477c657cb2ebc40db9182d0989a5d60e13 /drivers/of
parent2e89e685a8fd0e8334de967739d11e2e28c1a4dd (diff)
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')
-rw-r--r--drivers/of/base.c12
-rw-r--r--drivers/of/fdt.c45
-rw-r--r--drivers/of/gpio.c13
-rw-r--r--drivers/of/of_i2c.c4
-rw-r--r--drivers/of/of_mdio.c8
-rw-r--r--drivers/of/of_spi.c6
6 files changed, 47 insertions, 41 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 524645ab42a4..873479a21c80 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -38,7 +38,7 @@ int of_n_addr_cells(struct device_node *np)
38 np = np->parent; 38 np = np->parent;
39 ip = of_get_property(np, "#address-cells", NULL); 39 ip = of_get_property(np, "#address-cells", NULL);
40 if (ip) 40 if (ip)
41 return *ip; 41 return be32_to_cpup(ip);
42 } while (np->parent); 42 } while (np->parent);
43 /* No #address-cells property for the root node */ 43 /* No #address-cells property for the root node */
44 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 44 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
@@ -54,7 +54,7 @@ int of_n_size_cells(struct device_node *np)
54 np = np->parent; 54 np = np->parent;
55 ip = of_get_property(np, "#size-cells", NULL); 55 ip = of_get_property(np, "#size-cells", NULL);
56 if (ip) 56 if (ip)
57 return *ip; 57 return be32_to_cpup(ip);
58 } while (np->parent); 58 } while (np->parent);
59 /* No #size-cells property for the root node */ 59 /* No #size-cells property for the root node */
60 return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 60 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 const void **out_args) 696 const void **out_args)
697{ 697{
698 int ret = -EINVAL; 698 int ret = -EINVAL;
699 const u32 *list; 699 const __be32 *list;
700 const u32 *list_end; 700 const __be32 *list_end;
701 int size; 701 int size;
702 int cur_index = 0; 702 int cur_index = 0;
703 struct device_node *node = NULL; 703 struct device_node *node = NULL;
@@ -711,7 +711,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
711 list_end = list + size / sizeof(*list); 711 list_end = list + size / sizeof(*list);
712 712
713 while (list < list_end) { 713 while (list < list_end) {
714 const u32 *cells; 714 const __be32 *cells;
715 const phandle *phandle; 715 const phandle *phandle;
716 716
717 phandle = list++; 717 phandle = list++;
@@ -735,7 +735,7 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,
735 goto err1; 735 goto err1;
736 } 736 }
737 737
738 list += *cells; 738 list += be32_to_cpup(cells);
739 if (list > list_end) { 739 if (list > list_end) {
740 pr_debug("%s: insufficient arguments length\n", 740 pr_debug("%s: insufficient arguments length\n",
741 np->full_name); 741 np->full_name);
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,
51 int depth = -1; 51 int depth = -1;
52 52
53 do { 53 do {
54 u32 tag = *((u32 *)p); 54 u32 tag = be32_to_cpup((__be32 *)p);
55 char *pathp; 55 char *pathp;
56 56
57 p += 4; 57 p += 4;
@@ -64,7 +64,7 @@ int __init of_scan_flat_dt(int (*it)(unsigned long node,
64 if (tag == OF_DT_END) 64 if (tag == OF_DT_END)
65 break; 65 break;
66 if (tag == OF_DT_PROP) { 66 if (tag == OF_DT_PROP) {
67 u32 sz = *((u32 *)p); 67 u32 sz = be32_to_cpup((__be32 *)p);
68 p += 8; 68 p += 8;
69 if (initial_boot_params->version < 0x10) 69 if (initial_boot_params->version < 0x10)
70 p = _ALIGN(p, sz >= 8 ? 8 : 4); 70 p = _ALIGN(p, sz >= 8 ? 8 : 4);
@@ -103,9 +103,9 @@ unsigned long __init of_get_flat_dt_root(void)
103 unsigned long p = ((unsigned long)initial_boot_params) + 103 unsigned long p = ((unsigned long)initial_boot_params) +
104 initial_boot_params->off_dt_struct; 104 initial_boot_params->off_dt_struct;
105 105
106 while (*((u32 *)p) == OF_DT_NOP) 106 while (be32_to_cpup((__be32 *)p) == OF_DT_NOP)
107 p += 4; 107 p += 4;
108 BUG_ON(*((u32 *)p) != OF_DT_BEGIN_NODE); 108 BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE);
109 p += 4; 109 p += 4;
110 return _ALIGN(p + strlen((char *)p) + 1, 4); 110 return _ALIGN(p + strlen((char *)p) + 1, 4);
111} 111}
@@ -122,7 +122,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
122 unsigned long p = node; 122 unsigned long p = node;
123 123
124 do { 124 do {
125 u32 tag = *((u32 *)p); 125 u32 tag = be32_to_cpup((__be32 *)p);
126 u32 sz, noff; 126 u32 sz, noff;
127 const char *nstr; 127 const char *nstr;
128 128
@@ -132,8 +132,8 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name,
132 if (tag != OF_DT_PROP) 132 if (tag != OF_DT_PROP)
133 return NULL; 133 return NULL;
134 134
135 sz = *((u32 *)p); 135 sz = be32_to_cpup((__be32 *)p);
136 noff = *((u32 *)(p + 4)); 136 noff = be32_to_cpup((__be32 *)(p + 4));
137 p += 8; 137 p += 8;
138 if (initial_boot_params->version < 0x10) 138 if (initial_boot_params->version < 0x10)
139 p = _ALIGN(p, sz >= 8 ? 8 : 4); 139 p = _ALIGN(p, sz >= 8 ? 8 : 4);
@@ -210,7 +210,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
210 int has_name = 0; 210 int has_name = 0;
211 int new_format = 0; 211 int new_format = 0;
212 212
213 tag = *((u32 *)(*p)); 213 tag = be32_to_cpup((__be32 *)(*p));
214 if (tag != OF_DT_BEGIN_NODE) { 214 if (tag != OF_DT_BEGIN_NODE) {
215 pr_err("Weird tag at start of node: %x\n", tag); 215 pr_err("Weird tag at start of node: %x\n", tag);
216 return mem; 216 return mem;
@@ -285,7 +285,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
285 u32 sz, noff; 285 u32 sz, noff;
286 char *pname; 286 char *pname;
287 287
288 tag = *((u32 *)(*p)); 288 tag = be32_to_cpup((__be32 *)(*p));
289 if (tag == OF_DT_NOP) { 289 if (tag == OF_DT_NOP) {
290 *p += 4; 290 *p += 4;
291 continue; 291 continue;
@@ -293,8 +293,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
293 if (tag != OF_DT_PROP) 293 if (tag != OF_DT_PROP)
294 break; 294 break;
295 *p += 4; 295 *p += 4;
296 sz = *((u32 *)(*p)); 296 sz = be32_to_cpup((__be32 *)(*p));
297 noff = *((u32 *)((*p) + 4)); 297 noff = be32_to_cpup((__be32 *)((*p) + 4));
298 *p += 8; 298 *p += 8;
299 if (initial_boot_params->version < 0x10) 299 if (initial_boot_params->version < 0x10)
300 *p = _ALIGN(*p, sz >= 8 ? 8 : 4); 300 *p = _ALIGN(*p, sz >= 8 ? 8 : 4);
@@ -367,7 +367,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
367 } 367 }
368 while (tag == OF_DT_BEGIN_NODE) { 368 while (tag == OF_DT_BEGIN_NODE) {
369 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); 369 mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
370 tag = *((u32 *)(*p)); 370 tag = be32_to_cpup((__be32 *)(*p));
371 } 371 }
372 if (tag != OF_DT_END_NODE) { 372 if (tag != OF_DT_END_NODE) {
373 pr_err("Weird tag at end of node: %x\n", tag); 373 pr_err("Weird tag at end of node: %x\n", tag);
@@ -385,7 +385,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem,
385void __init early_init_dt_check_for_initrd(unsigned long node) 385void __init early_init_dt_check_for_initrd(unsigned long node)
386{ 386{
387 unsigned long start, end, len; 387 unsigned long start, end, len;
388 u32 *prop; 388 __be32 *prop;
389 389
390 pr_debug("Looking for initrd properties... "); 390 pr_debug("Looking for initrd properties... ");
391 391
@@ -414,17 +414,22 @@ inline void early_init_dt_check_for_initrd(unsigned long node)
414int __init early_init_dt_scan_root(unsigned long node, const char *uname, 414int __init early_init_dt_scan_root(unsigned long node, const char *uname,
415 int depth, void *data) 415 int depth, void *data)
416{ 416{
417 u32 *prop; 417 __be32 *prop;
418 418
419 if (depth != 0) 419 if (depth != 0)
420 return 0; 420 return 0;
421 421
422 dt_root_size_cells = OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
423 dt_root_addr_cells = OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
424
422 prop = of_get_flat_dt_prop(node, "#size-cells", NULL); 425 prop = of_get_flat_dt_prop(node, "#size-cells", NULL);
423 dt_root_size_cells = prop ? *prop : OF_ROOT_NODE_SIZE_CELLS_DEFAULT; 426 if (prop)
427 dt_root_size_cells = be32_to_cpup(prop);
424 pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells); 428 pr_debug("dt_root_size_cells = %x\n", dt_root_size_cells);
425 429
426 prop = of_get_flat_dt_prop(node, "#address-cells", NULL); 430 prop = of_get_flat_dt_prop(node, "#address-cells", NULL);
427 dt_root_addr_cells = prop ? *prop : OF_ROOT_NODE_ADDR_CELLS_DEFAULT; 431 if (prop)
432 dt_root_addr_cells = be32_to_cpup(prop);
428 pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells); 433 pr_debug("dt_root_addr_cells = %x\n", dt_root_addr_cells);
429 434
430 /* break now */ 435 /* break now */
@@ -549,7 +554,7 @@ void __init unflatten_device_tree(void)
549 mem = lmb_alloc(size + 4, __alignof__(struct device_node)); 554 mem = lmb_alloc(size + 4, __alignof__(struct device_node));
550 mem = (unsigned long) __va(mem); 555 mem = (unsigned long) __va(mem);
551 556
552 ((u32 *)mem)[size / 4] = 0xdeadbeef; 557 ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
553 558
554 pr_debug(" unflattening %lx...\n", mem); 559 pr_debug(" unflattening %lx...\n", mem);
555 560
@@ -557,11 +562,11 @@ void __init unflatten_device_tree(void)
557 start = ((unsigned long)initial_boot_params) + 562 start = ((unsigned long)initial_boot_params) +
558 initial_boot_params->off_dt_struct; 563 initial_boot_params->off_dt_struct;
559 unflatten_dt_node(mem, &start, NULL, &allnextp, 0); 564 unflatten_dt_node(mem, &start, NULL, &allnextp, 0);
560 if (*((u32 *)start) != OF_DT_END) 565 if (be32_to_cpup((__be32 *)start) != OF_DT_END)
561 pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); 566 pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start));
562 if (((u32 *)mem)[size / 4] != 0xdeadbeef) 567 if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef)
563 pr_warning("End of tree marker overwritten: %08x\n", 568 pr_warning("End of tree marker overwritten: %08x\n",
564 ((u32 *)mem)[size / 4]); 569 be32_to_cpu(((__be32 *)mem)[size / 4]));
565 *allnextp = NULL; 570 *allnextp = NULL;
566 571
567 /* Get pointer to OF "/chosen" node for use everywhere */ 572 /* Get pointer to OF "/chosen" node for use everywhere */
diff --git a/drivers/of/gpio.c b/drivers/of/gpio.c
index 6eea601a9204..24c3606217f8 100644
--- a/drivers/of/gpio.c
+++ b/drivers/of/gpio.c
@@ -36,7 +36,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
36 struct of_gpio_chip *of_gc = NULL; 36 struct of_gpio_chip *of_gc = NULL;
37 int size; 37 int size;
38 const void *gpio_spec; 38 const void *gpio_spec;
39 const u32 *gpio_cells; 39 const __be32 *gpio_cells;
40 40
41 ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index, 41 ret = of_parse_phandles_with_args(np, "gpios", "#gpio-cells", index,
42 &gc, &gpio_spec); 42 &gc, &gpio_spec);
@@ -55,7 +55,7 @@ int of_get_gpio_flags(struct device_node *np, int index,
55 55
56 gpio_cells = of_get_property(gc, "#gpio-cells", &size); 56 gpio_cells = of_get_property(gc, "#gpio-cells", &size);
57 if (!gpio_cells || size != sizeof(*gpio_cells) || 57 if (!gpio_cells || size != sizeof(*gpio_cells) ||
58 *gpio_cells != of_gc->gpio_cells) { 58 be32_to_cpup(gpio_cells) != of_gc->gpio_cells) {
59 pr_debug("%s: wrong #gpio-cells for %s\n", 59 pr_debug("%s: wrong #gpio-cells for %s\n",
60 np->full_name, gc->full_name); 60 np->full_name, gc->full_name);
61 ret = -EINVAL; 61 ret = -EINVAL;
@@ -127,7 +127,8 @@ EXPORT_SYMBOL(of_gpio_count);
127int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np, 127int of_gpio_simple_xlate(struct of_gpio_chip *of_gc, struct device_node *np,
128 const void *gpio_spec, enum of_gpio_flags *flags) 128 const void *gpio_spec, enum of_gpio_flags *flags)
129{ 129{
130 const u32 *gpio = gpio_spec; 130 const __be32 *gpio = gpio_spec;
131 const u32 n = be32_to_cpup(gpio);
131 132
132 /* 133 /*
133 * We're discouraging gpio_cells < 2, since that way you'll have to 134 * 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 return -EINVAL; 141 return -EINVAL;
141 } 142 }
142 143
143 if (*gpio > of_gc->gc.ngpio) 144 if (n > of_gc->gc.ngpio)
144 return -EINVAL; 145 return -EINVAL;
145 146
146 if (flags) 147 if (flags)
147 *flags = gpio[1]; 148 *flags = be32_to_cpu(gpio[1]);
148 149
149 return *gpio; 150 return n;
150} 151}
151EXPORT_SYMBOL(of_gpio_simple_xlate); 152EXPORT_SYMBOL(of_gpio_simple_xlate);
152 153
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
index fa65a2b2ae2e..a3a708e590d0 100644
--- a/drivers/of/of_i2c.c
+++ b/drivers/of/of_i2c.c
@@ -25,7 +25,7 @@ void of_register_i2c_devices(struct i2c_adapter *adap,
25 for_each_child_of_node(adap_node, node) { 25 for_each_child_of_node(adap_node, node) {
26 struct i2c_board_info info = {}; 26 struct i2c_board_info info = {};
27 struct dev_archdata dev_ad = {}; 27 struct dev_archdata dev_ad = {};
28 const u32 *addr; 28 const __be32 *addr;
29 int len; 29 int len;
30 30
31 if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) 31 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 40
41 info.irq = irq_of_parse_and_map(node, 0); 41 info.irq = irq_of_parse_and_map(node, 0);
42 42
43 info.addr = *addr; 43 info.addr = be32_to_cpup(addr);
44 44
45 dev_archdata_set_node(&dev_ad, node); 45 dev_archdata_set_node(&dev_ad, node);
46 info.archdata = &dev_ad; 46 info.archdata = &dev_ad;
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 4b22ba568b19..18ecae4a4375 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -51,7 +51,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
51 51
52 /* Loop over the child nodes and register a phy_device for each one */ 52 /* Loop over the child nodes and register a phy_device for each one */
53 for_each_child_of_node(np, child) { 53 for_each_child_of_node(np, child) {
54 const u32 *addr; 54 const __be32 *addr;
55 int len; 55 int len;
56 56
57 /* A PHY must have a reg property in the range [0-31] */ 57 /* 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 mdio->irq[*addr] = PHY_POLL; 68 mdio->irq[*addr] = PHY_POLL;
69 } 69 }
70 70
71 phy = get_phy_device(mdio, *addr); 71 phy = get_phy_device(mdio, be32_to_cpup(addr));
72 if (!phy) { 72 if (!phy) {
73 dev_err(&mdio->dev, "error probing PHY at address %i\n", 73 dev_err(&mdio->dev, "error probing PHY at address %i\n",
74 *addr); 74 *addr);
@@ -160,7 +160,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
160 struct device_node *net_np; 160 struct device_node *net_np;
161 char bus_id[MII_BUS_ID_SIZE + 3]; 161 char bus_id[MII_BUS_ID_SIZE + 3];
162 struct phy_device *phy; 162 struct phy_device *phy;
163 const u32 *phy_id; 163 const __be32 *phy_id;
164 int sz; 164 int sz;
165 165
166 if (!dev->dev.parent) 166 if (!dev->dev.parent)
@@ -174,7 +174,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev,
174 if (!phy_id || sz < sizeof(*phy_id)) 174 if (!phy_id || sz < sizeof(*phy_id))
175 return NULL; 175 return NULL;
176 176
177 sprintf(bus_id, PHY_ID_FMT, "0", phy_id[0]); 177 sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0]));
178 178
179 phy = phy_connect(dev, bus_id, hndlr, 0, iface); 179 phy = phy_connect(dev, bus_id, hndlr, 0, iface);
180 return IS_ERR(phy) ? NULL : phy; 180 return IS_ERR(phy) ? NULL : phy;
diff --git a/drivers/of/of_spi.c b/drivers/of/of_spi.c
index bed0ed6dcdc1..f65f48b98448 100644
--- a/drivers/of/of_spi.c
+++ b/drivers/of/of_spi.c
@@ -23,7 +23,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
23{ 23{
24 struct spi_device *spi; 24 struct spi_device *spi;
25 struct device_node *nc; 25 struct device_node *nc;
26 const u32 *prop; 26 const __be32 *prop;
27 int rc; 27 int rc;
28 int len; 28 int len;
29 29
@@ -54,7 +54,7 @@ void of_register_spi_devices(struct spi_master *master, struct device_node *np)
54 spi_dev_put(spi); 54 spi_dev_put(spi);
55 continue; 55 continue;
56 } 56 }
57 spi->chip_select = *prop; 57 spi->chip_select = be32_to_cpup(prop);
58 58
59 /* Mode (clock phase/polarity/etc.) */ 59 /* Mode (clock phase/polarity/etc.) */
60 if (of_find_property(nc, "spi-cpha", NULL)) 60 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 spi_dev_put(spi); 72 spi_dev_put(spi);
73 continue; 73 continue;
74 } 74 }
75 spi->max_speed_hz = *prop; 75 spi->max_speed_hz = be32_to_cpup(prop);
76 76
77 /* IRQ */ 77 /* IRQ */
78 spi->irq = irq_of_parse_and_map(nc, 0); 78 spi->irq = irq_of_parse_and_map(nc, 0);