Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -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);
+25 −20
Original line number Diff line number Diff line
@@ -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 */
+7 −6
Original line number Diff line number Diff line
@@ -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);

+2 −2
Original line number Diff line number Diff line
@@ -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;
+4 −4
Original line number Diff line number Diff line
@@ -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;
Loading