of: Fix phandle endian issues
PATCH v2 1/2 of: Fix phandle endian issues
The flat tree code wasn't fixing the endianness on phandle values when unflattening the tree, and the code in drivers/of wasn't always doing a be32_to_cpu before trying to dereference the phandle values. This patch fixes them.
Signed-off-by Grant Likely <grant.likely-s3s/[email protected]>
---
changed in v2: fixed up reference in drivers/of/irq.c too
drivers/of/base.c | 12 ++++++------ drivers/of/fdt.c | 4 ++-- drivers/of/irq.c | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-)
drivers/of/base.c +6 -6
@@ -605,14 +605,14 @@ EXPORT_SYMBOL(of_find_node_by_phandle);struct device_node *of_parse_phandle (struct device_node *np,const char *phandle_name,int index) { -const phandle *phandle; +const __be32 *phandle;int size; phandle =of_get_property (np, phandle_name, &size);if ((!phandle) || (size <sizeof (*phandle) * (index +1 )))return NULL ; -return of_find_node_by_phandle (phandle[index]); +return of_find_node_by_phandle (be32_to_cpup (phandle + index)); }EXPORT_SYMBOL (of_parse_phandle);
@@ -668,16 +668,16 @@ int of_parse_phandles_with_args(struct device_node *np, const char *list_name,while (list < list_end) {const __be32 *cells; -const phandle *phandle; +phandle phandle; - phandle = list++; + phandle =be32_to_cpup (list++); args = list;/* one cell hole in the list = <>; */ -if (!*phandle) +if (!phandle) goto next; - node =of_find_node_by_phandle (*phandle); + node =of_find_node_by_phandle (phandle);if (!node) {pr_debug ("%s: could not find phandle\n" , np->full_name);
drivers/of/fdt.c +2 -2
@@ -320,13 +320,13 @@ unsigned long __init unflatten_dt_node(unsigned long mem,if ((strcmp (pname,"phandle" ) ==0 ) || (strcmp (pname,"linux,phandle" ) ==0 )) {if (np->phandle ==0 ) - np->phandle = *((u32 *)*p); + np->phandle =be32_to_cpup ((__be32 *)*p); }/* And we process the "ibm,phandle" property * used in pSeries dynamic device tree * stuff */ if (strcmp (pname,"ibm,phandle" ) ==0 ) - np->phandle = *((u32 *)*p); + np->phandle =be32_to_cpup ((__be32 *)*p); pp->name = pname; pp->length = sz; pp->value = (void *)*p;
drivers/of/irq.c +3 -3
@@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);static struct device_node *of_irq_find_parent (struct device_node *child) {struct device_node *p; -const phandle *parp; +const __be32 *parp;if (!of_node_get (child))return NULL ;
@@ -67,7 +67,7 @@ static struct device_node *of_irq_find_parent(struct device_node *child)if (of_irq_workarounds &OF_IMAP_NO_PHANDLE ) p =of_node_get (of_irq_dflt_pic);else - p =of_find_node_by_phandle (*parp); + p =of_find_node_by_phandle (be32_to_cpup (parp)); }of_node_put (child); child = p;
@@ -206,7 +206,7 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,if (of_irq_workarounds &OF_IMAP_NO_PHANDLE ) newpar =of_node_get (of_irq_dflt_pic);else - newpar =of_find_node_by_phandle ((phandle)*imap); + newpar =of_find_node_by_phandle (be32_to_cpup (imap)); imap++; --imaplen;
PATCH v2 2/2 of/irq: Fix endian issues in parsing interrupt specifiers
This patch fixes some instances where interrupt specifiers are dereferenced directly instead of doing a be32_to_cpu() conversion first.
Signed-off-by Grant Likely <grant.likely-s3s/[email protected]>
--- drivers/of/irq.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-)
drivers/of/irq.c +7 -6
@@ -91,8 +91,8 @@ static struct device_node *of_irq_find_parent(struct device_node *child)* properties, for example when resolving PCI interrupts when no device * node exist for the parent. */ -int of_irq_map_raw (struct device_node *parent,const u32 *intspec,u32 ointsize, -const u32 *addr,struct of_irq *out_irq) +int of_irq_map_raw (struct device_node *parent,const __be32 *intspec, +u32 ointsize,const __be32 *addr,struct of_irq *out_irq) {struct device_node *ipar, *tnode, *old =NULL , *newpar =NULL ;const __be32 *tmp, *imap, *imask;
@@ -100,7 +100,8 @@ int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,int imaplen, match, i;pr_debug ("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n" , - parent->full_name, intspec[0 ], intspec[1 ], ointsize); + parent->full_name,be32_to_cpup (intspec), +be32_to_cpu (intspec +1 ), ointsize); ipar =of_node_get (parent);
@@ -278,7 +279,7 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);int of_irq_map_one (struct device_node *device,int index,struct of_irq *out_irq) {struct device_node *p; -const u32 *intspec, *tmp, *addr; +const __be32 *intspec, *tmp, *addr;u32 intsize, intlen;int res = -EINVAL ;
@@ -292,9 +293,9 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq intspec =of_get_property (device,"interrupts" , &intlen);if (intspec ==NULL )return -EINVAL ; - intlen /=sizeof (u32); + intlen /=sizeof (*intspec); -pr_debug (" intspec=%d intlen=%d\n" , *intspec, intlen); +pr_debug (" intspec=%d intlen=%d\n" ,be32_to_cpup (intspec), intlen);/* Get the reg property (if any) */ addr =of_get_property (device,"reg" ,NULL );