diff options
Diffstat (limited to 'drivers/of/irq.c')
-rw-r--r-- | drivers/of/irq.c | 77 |
1 files changed, 31 insertions, 46 deletions
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index ab21c846eb27..ec00ae7384c2 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -59,20 +59,19 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); struct device_node *of_irq_find_parent(struct device_node *child) { struct device_node *p; - const __be32 *parp; + phandle parent; if (!of_node_get(child)) return NULL; do { - parp = of_get_property(child, "interrupt-parent", NULL); - if (parp == NULL) + if (of_property_read_u32(child, "interrupt-parent", &parent)) { p = of_get_parent(child); - else { + } else { if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) p = of_node_get(of_irq_dflt_pic); else - p = of_find_node_by_phandle(be32_to_cpup(parp)); + p = of_find_node_by_phandle(parent); } of_node_put(child); child = p; @@ -117,11 +116,8 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) * is none, we are nice and just walk up the tree */ do { - tmp = of_get_property(ipar, "#interrupt-cells", NULL); - if (tmp != NULL) { - intsize = be32_to_cpu(*tmp); + if (!of_property_read_u32(ipar, "#interrupt-cells", &intsize)) break; - } tnode = ipar; ipar = of_irq_find_parent(ipar); of_node_put(tnode); @@ -131,7 +127,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) goto fail; } - pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); + pr_debug("of_irq_parse_raw: ipar=%pOF, size=%d\n", ipar, intsize); if (out_irq->args_count != intsize) goto fail; @@ -169,8 +165,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) /* Now check if cursor is an interrupt-controller and if it is * then we are done */ - if (of_get_property(ipar, "interrupt-controller", NULL) != - NULL) { + if (of_property_read_bool(ipar, "interrupt-controller")) { pr_debug(" -> got it !\n"); return 0; } @@ -229,14 +224,14 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) /* Get #interrupt-cells and #address-cells of new * parent */ - tmp = of_get_property(newpar, "#interrupt-cells", NULL); - if (tmp == NULL) { + if (of_property_read_u32(newpar, "#interrupt-cells", + &newintsize)) { pr_debug(" -> parent lacks #interrupt-cells!\n"); goto fail; } - newintsize = be32_to_cpu(*tmp); - tmp = of_get_property(newpar, "#address-cells", NULL); - newaddrsize = (tmp == NULL) ? 0 : be32_to_cpu(*tmp); + if (of_property_read_u32(newpar, "#address-cells", + &newaddrsize)) + newaddrsize = 0; pr_debug(" -> newintsize=%d, newaddrsize=%d\n", newintsize, newaddrsize); @@ -269,7 +264,7 @@ int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) skiplevel: /* Iterate again with new parent */ out_irq->np = newpar; - pr_debug(" -> new parent: %s\n", of_node_full_name(newpar)); + pr_debug(" -> new parent: %pOF\n", newpar); of_node_put(ipar); ipar = newpar; newpar = NULL; @@ -297,11 +292,11 @@ EXPORT_SYMBOL_GPL(of_irq_parse_raw); int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) { struct device_node *p; - const __be32 *intspec, *tmp, *addr; - u32 intsize, intlen; + const __be32 *addr; + u32 intsize; int i, res; - pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); + pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index); /* OldWorld mac stuff is "special", handle out of line */ if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) @@ -316,42 +311,32 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar if (!res) return of_irq_parse_raw(addr, out_irq); - /* Get the interrupts property */ - intspec = of_get_property(device, "interrupts", &intlen); - if (intspec == NULL) - return -EINVAL; - - intlen /= sizeof(*intspec); - - pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); - /* Look for the interrupt parent. */ p = of_irq_find_parent(device); if (p == NULL) return -EINVAL; /* Get size of interrupt specifier */ - tmp = of_get_property(p, "#interrupt-cells", NULL); - if (tmp == NULL) { + if (of_property_read_u32(p, "#interrupt-cells", &intsize)) { res = -EINVAL; goto out; } - intsize = be32_to_cpu(*tmp); - pr_debug(" intsize=%d intlen=%d\n", intsize, intlen); - - /* Check index */ - if ((index + 1) * intsize > intlen) { - res = -EINVAL; - goto out; - } + pr_debug(" parent=%pOF, intsize=%d\n", p, intsize); /* Copy intspec into irq structure */ - intspec += index * intsize; out_irq->np = p; out_irq->args_count = intsize; - for (i = 0; i < intsize; i++) - out_irq->args[i] = be32_to_cpup(intspec++); + for (i = 0; i < intsize; i++) { + res = of_property_read_u32_index(device, "interrupts", + (index * intsize) + i, + out_irq->args + i); + if (res) + goto out; + } + + pr_debug(" intspec=%d\n", *out_irq->args); + /* Check if there are any interrupt-map translations to process */ res = of_irq_parse_raw(addr, out_irq); @@ -508,7 +493,7 @@ void __init of_irq_init(const struct of_device_id *matches) INIT_LIST_HEAD(&intc_parent_list); for_each_matching_node_and_match(np, matches, &match) { - if (!of_find_property(np, "interrupt-controller", NULL) || + if (!of_property_read_bool(np, "interrupt-controller") || !of_device_is_available(np)) continue; @@ -555,8 +540,8 @@ void __init of_irq_init(const struct of_device_id *matches) of_node_set_flag(desc->dev, OF_POPULATED); - pr_debug("of_irq_init: init %s (%p), parent %p\n", - desc->dev->full_name, + pr_debug("of_irq_init: init %pOF (%p), parent %p\n", + desc->dev, desc->dev, desc->interrupt_parent); ret = desc->irq_init_cb(desc->dev, desc->interrupt_parent); |