All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wolfram Sang <w.sang@pengutronix.de>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: sfr@canb.auug.org.au, monstr@monstr.eu,
	devicetree-discuss@lists.ozlabs.org,
	microblaze-uclinux@itee.uq.edu.au, sparclinux@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
Subject: Re: [PATCH 07/11] of/flattree: Merge unflatten_dt_node
Date: Thu, 5 Nov 2009 09:59:59 +0100	[thread overview]
Message-ID: <20091105085959.GD3478@pengutronix.de> (raw)
In-Reply-To: <20091105074631.10460.97676.stgit@angua>


[-- Attachment #1.1: Type: text/plain, Size: 7202 bytes --]

On Thu, Nov 05, 2009 at 12:46:38AM -0700, Grant Likely wrote:
> Merge common code between PowerPC and MicroBlaze
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

[...]

> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 01a7f5f..df1ac8d 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -167,3 +167,203 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  	return 0;
>  }
>  
> +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +				       unsigned long align)
> +{
> +	void *res;
> +
> +	*mem = _ALIGN(*mem, align);
> +	res = (void *)*mem;
> +	*mem += size;
> +
> +	return res;
> +}
> +
> +/**
> + * unflatten_dt_node - Alloc and populate a device_node from the flat tree
> + * @p: pointer to node in flat tree
> + * @dad: Parent struct device_node
> + * @allnextpp: pointer to ->allnext from last allocated device_node
> + * @fpsize: Size of the node path up at the current depth.
> + */
> +unsigned long __init unflatten_dt_node(unsigned long mem,
> +					unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize)
> +{
> +	struct device_node *np;
> +	struct property *pp, **prev_pp = NULL;
> +	char *pathp;
> +	u32 tag;
> +	unsigned int l, allocl;
> +	int has_name = 0;
> +	int new_format = 0;
> +
> +	tag = *((u32 *)(*p));
> +	if (tag != OF_DT_BEGIN_NODE) {
> +		printk("Weird tag at start of node: %x\n", tag);

Loglevel missing -> pr_info?

> +		return mem;
> +	}
> +	*p += 4;
> +	pathp = (char *)*p;
> +	l = allocl = strlen(pathp) + 1;
> +	*p = _ALIGN(*p + l, 4);
> +
> +	/* version 0x10 has a more compact unit name here instead of the full
> +	 * path. we accumulate the full path size using "fpsize", we'll rebuild
> +	 * it later. We detect this because the first character of the name is
> +	 * not '/'.
> +	 */
> +	if ((*pathp) != '/') {
> +		new_format = 1;
> +		if (fpsize == 0) {
> +			/* root node: special case. fpsize accounts for path
> +			 * plus terminating zero. root node only has '/', so
> +			 * fpsize should be 2, but we want to avoid the first
> +			 * level nodes to have two '/' so we use fpsize 1 here
> +			 */
> +			fpsize = 1;
> +			allocl = 2;
> +		} else {
> +			/* account for '/' and path size minus terminal 0
> +			 * already in 'l'
> +			 */
> +			fpsize += l;
> +			allocl = fpsize;
> +		}
> +	}
> +
> +	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
> +				__alignof__(struct device_node));
> +	if (allnextpp) {
> +		memset(np, 0, sizeof(*np));
> +		np->full_name = ((char *)np) + sizeof(struct device_node);
> +		if (new_format) {
> +			char *fn = np->full_name;
> +			/* rebuild full path for new format */
> +			if (dad && dad->parent) {
> +				strcpy(fn, dad->full_name);
> +#ifdef DEBUG
> +				if ((strlen(fn) + l + 1) != allocl) {
> +					pr_debug("%s: p: %d, l: %d, a: %d\n",
> +						pathp, (int)strlen(fn),
> +						l, allocl);
> +				}
> +#endif
> +				fn += strlen(fn);
> +			}
> +			*(fn++) = '/';
> +			memcpy(fn, pathp, l);
> +		} else
> +			memcpy(np->full_name, pathp, l);
> +		prev_pp = &np->properties;
> +		**allnextpp = np;
> +		*allnextpp = &np->allnext;
> +		if (dad != NULL) {
> +			np->parent = dad;
> +			/* we temporarily use the next field as `last_child'*/
> +			if (dad->next == NULL)
> +				dad->child = np;
> +			else
> +				dad->next->sibling = np;
> +			dad->next = np;
> +		}
> +		kref_init(&np->kref);
> +	}
> +	while (1) {
> +		u32 sz, noff;
> +		char *pname;
> +
> +		tag = *((u32 *)(*p));
> +		if (tag == OF_DT_NOP) {
> +			*p += 4;
> +			continue;
> +		}
> +		if (tag != OF_DT_PROP)
> +			break;
> +		*p += 4;
> +		sz = *((u32 *)(*p));
> +		noff = *((u32 *)((*p) + 4));
> +		*p += 8;
> +		if (initial_boot_params->version < 0x10)
> +			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
> +
> +		pname = find_flat_dt_string(noff);
> +		if (pname == NULL) {
> +			pr_info("Can't find property name in list !\n");
> +			break;
> +		}
> +		if (strcmp(pname, "name") == 0)
> +			has_name = 1;
> +		l = strlen(pname) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			if (strcmp(pname, "linux,phandle") == 0) {
> +				np->node = *((u32 *)*p);
> +				if (np->linux_phandle == 0)
> +					np->linux_phandle = np->node;
> +			}
> +			if (strcmp(pname, "ibm,phandle") == 0)
> +				np->linux_phandle = *((u32 *)*p);
> +			pp->name = pname;
> +			pp->length = sz;
> +			pp->value = (void *)*p;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +		}
> +		*p = _ALIGN((*p) + sz, 4);
> +	}
> +	/* with version 0x10 we may not have the name property, recreate
> +	 * it here from the unit name if absent
> +	 */
> +	if (!has_name) {
> +		char *p1 = pathp, *ps = pathp, *pa = NULL;
> +		int sz;
> +
> +		while (*p1) {
> +			if ((*p1) == '@')
> +				pa = p1;
> +			if ((*p1) == '/')
> +				ps = p1 + 1;
> +			p1++;
> +		}
> +		if (pa < ps)
> +			pa = p1;
> +		sz = (pa - ps) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			pp->name = "name";
> +			pp->length = sz;
> +			pp->value = pp + 1;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +			memcpy(pp->value, ps, sz - 1);
> +			((char *)pp->value)[sz - 1] = 0;
> +			pr_debug("fixed up name for %s -> %s\n", pathp,
> +				(char *)pp->value);
> +		}
> +	}
> +	if (allnextpp) {
> +		*prev_pp = NULL;
> +		np->name = of_get_property(np, "name", NULL);
> +		np->type = of_get_property(np, "device_type", NULL);
> +
> +		if (!np->name)
> +			np->name = "<NULL>";
> +		if (!np->type)
> +			np->type = "<NULL>";
> +	}
> +	while (tag == OF_DT_BEGIN_NODE) {
> +		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +		tag = *((u32 *)(*p));
> +	}
> +	if (tag != OF_DT_END_NODE) {
> +		printk("Weird tag at end of node: %x\n", tag);

Ditto (microblaze had KERN_INFO, too).

> +		return mem;
> +	}
> +	*p += 4;
> +	return mem;
> +}
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 81231e0..ace9068 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -69,6 +69,10 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size);
>  extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
>  extern unsigned long of_get_flat_dt_root(void);
> +extern unsigned long unflatten_dt_node(unsigned long mem, unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize);
>  
>  /* Other Prototypes */
>  extern void finish_device_tree(void);
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

[-- Attachment #2: Type: text/plain, Size: 150 bytes --]

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

WARNING: multiple messages have this Message-ID (diff)
From: Wolfram Sang <w.sang@pengutronix.de>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: sfr@canb.auug.org.au, monstr@monstr.eu,
	devicetree-discuss@lists.ozlabs.org,
	microblaze-uclinux@itee.uq.edu.au, sparclinux@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
Subject: Re: [PATCH 07/11] of/flattree: Merge unflatten_dt_node
Date: Thu, 05 Nov 2009 08:59:59 +0000	[thread overview]
Message-ID: <20091105085959.GD3478@pengutronix.de> (raw)
In-Reply-To: <20091105074631.10460.97676.stgit@angua>

[-- Attachment #1: Type: text/plain, Size: 7202 bytes --]

On Thu, Nov 05, 2009 at 12:46:38AM -0700, Grant Likely wrote:
> Merge common code between PowerPC and MicroBlaze
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

[...]

> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 01a7f5f..df1ac8d 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -167,3 +167,203 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  	return 0;
>  }
>  
> +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +				       unsigned long align)
> +{
> +	void *res;
> +
> +	*mem = _ALIGN(*mem, align);
> +	res = (void *)*mem;
> +	*mem += size;
> +
> +	return res;
> +}
> +
> +/**
> + * unflatten_dt_node - Alloc and populate a device_node from the flat tree
> + * @p: pointer to node in flat tree
> + * @dad: Parent struct device_node
> + * @allnextpp: pointer to ->allnext from last allocated device_node
> + * @fpsize: Size of the node path up at the current depth.
> + */
> +unsigned long __init unflatten_dt_node(unsigned long mem,
> +					unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize)
> +{
> +	struct device_node *np;
> +	struct property *pp, **prev_pp = NULL;
> +	char *pathp;
> +	u32 tag;
> +	unsigned int l, allocl;
> +	int has_name = 0;
> +	int new_format = 0;
> +
> +	tag = *((u32 *)(*p));
> +	if (tag != OF_DT_BEGIN_NODE) {
> +		printk("Weird tag at start of node: %x\n", tag);

Loglevel missing -> pr_info?

> +		return mem;
> +	}
> +	*p += 4;
> +	pathp = (char *)*p;
> +	l = allocl = strlen(pathp) + 1;
> +	*p = _ALIGN(*p + l, 4);
> +
> +	/* version 0x10 has a more compact unit name here instead of the full
> +	 * path. we accumulate the full path size using "fpsize", we'll rebuild
> +	 * it later. We detect this because the first character of the name is
> +	 * not '/'.
> +	 */
> +	if ((*pathp) != '/') {
> +		new_format = 1;
> +		if (fpsize == 0) {
> +			/* root node: special case. fpsize accounts for path
> +			 * plus terminating zero. root node only has '/', so
> +			 * fpsize should be 2, but we want to avoid the first
> +			 * level nodes to have two '/' so we use fpsize 1 here
> +			 */
> +			fpsize = 1;
> +			allocl = 2;
> +		} else {
> +			/* account for '/' and path size minus terminal 0
> +			 * already in 'l'
> +			 */
> +			fpsize += l;
> +			allocl = fpsize;
> +		}
> +	}
> +
> +	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
> +				__alignof__(struct device_node));
> +	if (allnextpp) {
> +		memset(np, 0, sizeof(*np));
> +		np->full_name = ((char *)np) + sizeof(struct device_node);
> +		if (new_format) {
> +			char *fn = np->full_name;
> +			/* rebuild full path for new format */
> +			if (dad && dad->parent) {
> +				strcpy(fn, dad->full_name);
> +#ifdef DEBUG
> +				if ((strlen(fn) + l + 1) != allocl) {
> +					pr_debug("%s: p: %d, l: %d, a: %d\n",
> +						pathp, (int)strlen(fn),
> +						l, allocl);
> +				}
> +#endif
> +				fn += strlen(fn);
> +			}
> +			*(fn++) = '/';
> +			memcpy(fn, pathp, l);
> +		} else
> +			memcpy(np->full_name, pathp, l);
> +		prev_pp = &np->properties;
> +		**allnextpp = np;
> +		*allnextpp = &np->allnext;
> +		if (dad != NULL) {
> +			np->parent = dad;
> +			/* we temporarily use the next field as `last_child'*/
> +			if (dad->next == NULL)
> +				dad->child = np;
> +			else
> +				dad->next->sibling = np;
> +			dad->next = np;
> +		}
> +		kref_init(&np->kref);
> +	}
> +	while (1) {
> +		u32 sz, noff;
> +		char *pname;
> +
> +		tag = *((u32 *)(*p));
> +		if (tag == OF_DT_NOP) {
> +			*p += 4;
> +			continue;
> +		}
> +		if (tag != OF_DT_PROP)
> +			break;
> +		*p += 4;
> +		sz = *((u32 *)(*p));
> +		noff = *((u32 *)((*p) + 4));
> +		*p += 8;
> +		if (initial_boot_params->version < 0x10)
> +			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
> +
> +		pname = find_flat_dt_string(noff);
> +		if (pname == NULL) {
> +			pr_info("Can't find property name in list !\n");
> +			break;
> +		}
> +		if (strcmp(pname, "name") == 0)
> +			has_name = 1;
> +		l = strlen(pname) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			if (strcmp(pname, "linux,phandle") == 0) {
> +				np->node = *((u32 *)*p);
> +				if (np->linux_phandle == 0)
> +					np->linux_phandle = np->node;
> +			}
> +			if (strcmp(pname, "ibm,phandle") == 0)
> +				np->linux_phandle = *((u32 *)*p);
> +			pp->name = pname;
> +			pp->length = sz;
> +			pp->value = (void *)*p;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +		}
> +		*p = _ALIGN((*p) + sz, 4);
> +	}
> +	/* with version 0x10 we may not have the name property, recreate
> +	 * it here from the unit name if absent
> +	 */
> +	if (!has_name) {
> +		char *p1 = pathp, *ps = pathp, *pa = NULL;
> +		int sz;
> +
> +		while (*p1) {
> +			if ((*p1) == '@')
> +				pa = p1;
> +			if ((*p1) == '/')
> +				ps = p1 + 1;
> +			p1++;
> +		}
> +		if (pa < ps)
> +			pa = p1;
> +		sz = (pa - ps) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			pp->name = "name";
> +			pp->length = sz;
> +			pp->value = pp + 1;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +			memcpy(pp->value, ps, sz - 1);
> +			((char *)pp->value)[sz - 1] = 0;
> +			pr_debug("fixed up name for %s -> %s\n", pathp,
> +				(char *)pp->value);
> +		}
> +	}
> +	if (allnextpp) {
> +		*prev_pp = NULL;
> +		np->name = of_get_property(np, "name", NULL);
> +		np->type = of_get_property(np, "device_type", NULL);
> +
> +		if (!np->name)
> +			np->name = "<NULL>";
> +		if (!np->type)
> +			np->type = "<NULL>";
> +	}
> +	while (tag == OF_DT_BEGIN_NODE) {
> +		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +		tag = *((u32 *)(*p));
> +	}
> +	if (tag != OF_DT_END_NODE) {
> +		printk("Weird tag at end of node: %x\n", tag);

Ditto (microblaze had KERN_INFO, too).

> +		return mem;
> +	}
> +	*p += 4;
> +	return mem;
> +}
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 81231e0..ace9068 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -69,6 +69,10 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size);
>  extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
>  extern unsigned long of_get_flat_dt_root(void);
> +extern unsigned long unflatten_dt_node(unsigned long mem, unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize);
>  
>  /* Other Prototypes */
>  extern void finish_device_tree(void);
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

WARNING: multiple messages have this Message-ID (diff)
From: Wolfram Sang <w.sang@pengutronix.de>
To: Grant Likely <grant.likely@secretlab.ca>
Cc: sfr@canb.auug.org.au, monstr@monstr.eu,
	devicetree-discuss@lists.ozlabs.org,
	microblaze-uclinux@itee.uq.edu.au, sparclinux@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, davem@davemloft.net
Subject: Re: [PATCH 07/11] of/flattree: Merge unflatten_dt_node
Date: Thu, 5 Nov 2009 09:59:59 +0100	[thread overview]
Message-ID: <20091105085959.GD3478@pengutronix.de> (raw)
In-Reply-To: <20091105074631.10460.97676.stgit@angua>

[-- Attachment #1: Type: text/plain, Size: 7202 bytes --]

On Thu, Nov 05, 2009 at 12:46:38AM -0700, Grant Likely wrote:
> Merge common code between PowerPC and MicroBlaze
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

[...]

> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index 01a7f5f..df1ac8d 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -167,3 +167,203 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
>  	return 0;
>  }
>  
> +static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size,
> +				       unsigned long align)
> +{
> +	void *res;
> +
> +	*mem = _ALIGN(*mem, align);
> +	res = (void *)*mem;
> +	*mem += size;
> +
> +	return res;
> +}
> +
> +/**
> + * unflatten_dt_node - Alloc and populate a device_node from the flat tree
> + * @p: pointer to node in flat tree
> + * @dad: Parent struct device_node
> + * @allnextpp: pointer to ->allnext from last allocated device_node
> + * @fpsize: Size of the node path up at the current depth.
> + */
> +unsigned long __init unflatten_dt_node(unsigned long mem,
> +					unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize)
> +{
> +	struct device_node *np;
> +	struct property *pp, **prev_pp = NULL;
> +	char *pathp;
> +	u32 tag;
> +	unsigned int l, allocl;
> +	int has_name = 0;
> +	int new_format = 0;
> +
> +	tag = *((u32 *)(*p));
> +	if (tag != OF_DT_BEGIN_NODE) {
> +		printk("Weird tag at start of node: %x\n", tag);

Loglevel missing -> pr_info?

> +		return mem;
> +	}
> +	*p += 4;
> +	pathp = (char *)*p;
> +	l = allocl = strlen(pathp) + 1;
> +	*p = _ALIGN(*p + l, 4);
> +
> +	/* version 0x10 has a more compact unit name here instead of the full
> +	 * path. we accumulate the full path size using "fpsize", we'll rebuild
> +	 * it later. We detect this because the first character of the name is
> +	 * not '/'.
> +	 */
> +	if ((*pathp) != '/') {
> +		new_format = 1;
> +		if (fpsize == 0) {
> +			/* root node: special case. fpsize accounts for path
> +			 * plus terminating zero. root node only has '/', so
> +			 * fpsize should be 2, but we want to avoid the first
> +			 * level nodes to have two '/' so we use fpsize 1 here
> +			 */
> +			fpsize = 1;
> +			allocl = 2;
> +		} else {
> +			/* account for '/' and path size minus terminal 0
> +			 * already in 'l'
> +			 */
> +			fpsize += l;
> +			allocl = fpsize;
> +		}
> +	}
> +
> +	np = unflatten_dt_alloc(&mem, sizeof(struct device_node) + allocl,
> +				__alignof__(struct device_node));
> +	if (allnextpp) {
> +		memset(np, 0, sizeof(*np));
> +		np->full_name = ((char *)np) + sizeof(struct device_node);
> +		if (new_format) {
> +			char *fn = np->full_name;
> +			/* rebuild full path for new format */
> +			if (dad && dad->parent) {
> +				strcpy(fn, dad->full_name);
> +#ifdef DEBUG
> +				if ((strlen(fn) + l + 1) != allocl) {
> +					pr_debug("%s: p: %d, l: %d, a: %d\n",
> +						pathp, (int)strlen(fn),
> +						l, allocl);
> +				}
> +#endif
> +				fn += strlen(fn);
> +			}
> +			*(fn++) = '/';
> +			memcpy(fn, pathp, l);
> +		} else
> +			memcpy(np->full_name, pathp, l);
> +		prev_pp = &np->properties;
> +		**allnextpp = np;
> +		*allnextpp = &np->allnext;
> +		if (dad != NULL) {
> +			np->parent = dad;
> +			/* we temporarily use the next field as `last_child'*/
> +			if (dad->next == NULL)
> +				dad->child = np;
> +			else
> +				dad->next->sibling = np;
> +			dad->next = np;
> +		}
> +		kref_init(&np->kref);
> +	}
> +	while (1) {
> +		u32 sz, noff;
> +		char *pname;
> +
> +		tag = *((u32 *)(*p));
> +		if (tag == OF_DT_NOP) {
> +			*p += 4;
> +			continue;
> +		}
> +		if (tag != OF_DT_PROP)
> +			break;
> +		*p += 4;
> +		sz = *((u32 *)(*p));
> +		noff = *((u32 *)((*p) + 4));
> +		*p += 8;
> +		if (initial_boot_params->version < 0x10)
> +			*p = _ALIGN(*p, sz >= 8 ? 8 : 4);
> +
> +		pname = find_flat_dt_string(noff);
> +		if (pname == NULL) {
> +			pr_info("Can't find property name in list !\n");
> +			break;
> +		}
> +		if (strcmp(pname, "name") == 0)
> +			has_name = 1;
> +		l = strlen(pname) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property),
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			if (strcmp(pname, "linux,phandle") == 0) {
> +				np->node = *((u32 *)*p);
> +				if (np->linux_phandle == 0)
> +					np->linux_phandle = np->node;
> +			}
> +			if (strcmp(pname, "ibm,phandle") == 0)
> +				np->linux_phandle = *((u32 *)*p);
> +			pp->name = pname;
> +			pp->length = sz;
> +			pp->value = (void *)*p;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +		}
> +		*p = _ALIGN((*p) + sz, 4);
> +	}
> +	/* with version 0x10 we may not have the name property, recreate
> +	 * it here from the unit name if absent
> +	 */
> +	if (!has_name) {
> +		char *p1 = pathp, *ps = pathp, *pa = NULL;
> +		int sz;
> +
> +		while (*p1) {
> +			if ((*p1) == '@')
> +				pa = p1;
> +			if ((*p1) == '/')
> +				ps = p1 + 1;
> +			p1++;
> +		}
> +		if (pa < ps)
> +			pa = p1;
> +		sz = (pa - ps) + 1;
> +		pp = unflatten_dt_alloc(&mem, sizeof(struct property) + sz,
> +					__alignof__(struct property));
> +		if (allnextpp) {
> +			pp->name = "name";
> +			pp->length = sz;
> +			pp->value = pp + 1;
> +			*prev_pp = pp;
> +			prev_pp = &pp->next;
> +			memcpy(pp->value, ps, sz - 1);
> +			((char *)pp->value)[sz - 1] = 0;
> +			pr_debug("fixed up name for %s -> %s\n", pathp,
> +				(char *)pp->value);
> +		}
> +	}
> +	if (allnextpp) {
> +		*prev_pp = NULL;
> +		np->name = of_get_property(np, "name", NULL);
> +		np->type = of_get_property(np, "device_type", NULL);
> +
> +		if (!np->name)
> +			np->name = "<NULL>";
> +		if (!np->type)
> +			np->type = "<NULL>";
> +	}
> +	while (tag == OF_DT_BEGIN_NODE) {
> +		mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize);
> +		tag = *((u32 *)(*p));
> +	}
> +	if (tag != OF_DT_END_NODE) {
> +		printk("Weird tag at end of node: %x\n", tag);

Ditto (microblaze had KERN_INFO, too).

> +		return mem;
> +	}
> +	*p += 4;
> +	return mem;
> +}
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 81231e0..ace9068 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -69,6 +69,10 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
>  				 unsigned long *size);
>  extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
>  extern unsigned long of_get_flat_dt_root(void);
> +extern unsigned long unflatten_dt_node(unsigned long mem, unsigned long *p,
> +					struct device_node *dad,
> +					struct device_node ***allnextpp,
> +					unsigned long fpsize);
>  
>  /* Other Prototypes */
>  extern void finish_device_tree(void);
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

  reply	other threads:[~2009-11-05  8:59 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-05  7:45 [PATCH 00/11] More OF merge patches Grant Likely
2009-11-05  7:45 ` Grant Likely
2009-11-05  7:45 ` Grant Likely
2009-11-05  7:45 ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and initial_boot_params Grant Likely
2009-11-05  7:45   ` Grant Likely
2009-11-05  7:45   ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and Grant Likely
2009-11-05  8:39   ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and initial_boot_params Wolfram Sang
2009-11-05  8:39     ` Wolfram Sang
2009-11-05  8:39     ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and Wolfram Sang
2009-11-05  8:45     ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and initial_boot_params Grant Likely
2009-11-05  8:45       ` Grant Likely
2009-11-05  8:45       ` [PATCH 01/11] of/flattree: merge find_flat_dt_string and Grant Likely
2009-11-05  7:45 ` [PATCH 02/11] of/flattree: merge of_scan_flat_dt Grant Likely
2009-11-05  7:45   ` Grant Likely
2009-11-05  7:45   ` Grant Likely
2009-11-05  8:45   ` Wolfram Sang
2009-11-05  8:45     ` Wolfram Sang
2009-11-05  8:45     ` Wolfram Sang
2009-11-05  7:45 ` [PATCH 03/11] of/flattree: merge of_get_flat_dt_root Grant Likely
2009-11-05  7:45   ` Grant Likely
2009-11-05  7:45   ` Grant Likely
2009-11-05  7:46 ` [PATCH 04/11] of/flattree: remove __init annotations from the header file Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46   ` [PATCH 04/11] of/flattree: remove __init annotations from the header Grant Likely
2009-11-05  7:46 ` [PATCH 05/11] of/flattree: merge of_get_flat_dt_prop Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  8:49   ` Wolfram Sang
2009-11-05  8:49     ` Wolfram Sang
2009-11-05  8:49     ` Wolfram Sang
2009-11-05  7:46 ` [PATCH 06/11] of/flattree: Merge of_flat_dt_is_compatible Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46 ` [PATCH 07/11] of/flattree: Merge unflatten_dt_node Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  8:59   ` Wolfram Sang [this message]
2009-11-05  8:59     ` Wolfram Sang
2009-11-05  8:59     ` Wolfram Sang
2009-11-05  7:46 ` [PATCH 08/11] of/flattree: Merge unflatten_device_tree Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:46   ` Grant Likely
2009-11-05  7:47 ` [PATCH 09/11] of: merge prom_{add,remove,modify}_property Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-10 20:33   ` Nathan Fontenot
2009-11-10 20:33     ` Nathan Fontenot
2009-11-10 20:33     ` Nathan Fontenot
2009-11-10 21:41     ` Grant Likely
2009-11-10 21:41       ` Grant Likely
2009-11-10 21:41       ` Grant Likely
2009-11-05  7:47 ` [PATCH 10/11] of: remove special case definition of of_read_ulong() Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-05  7:47 ` [PATCH 11/11] of/flattree: Merge early_init_dt_check_for_initrd() Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-05  7:47   ` Grant Likely
2009-11-05 10:11 ` [PATCH 00/11] More OF merge patches Wolfram Sang
2009-11-05 10:11   ` Wolfram Sang
2009-11-05 10:11   ` Wolfram Sang
2009-11-09 10:35 ` [microblaze-uclinux] " Michal Simek
2009-11-09 10:35   ` Michal Simek
2009-11-09 10:35   ` Michal Simek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20091105085959.GD3478@pengutronix.de \
    --to=w.sang@pengutronix.de \
    --cc=davem@davemloft.net \
    --cc=devicetree-discuss@lists.ozlabs.org \
    --cc=grant.likely@secretlab.ca \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=microblaze-uclinux@itee.uq.edu.au \
    --cc=monstr@monstr.eu \
    --cc=sfr@canb.auug.org.au \
    --cc=sparclinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.