From 0d638a07d3a1e98a7598eb2812a6236324e4c55f Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 1 Jun 2017 15:50:55 -0500 Subject: of: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring --- drivers/of/address.c | 21 ++++++++-------- drivers/of/base.c | 22 ++++++++--------- drivers/of/device.c | 2 +- drivers/of/dynamic.c | 33 ++++++++++++------------- drivers/of/irq.c | 10 ++++---- drivers/of/of_mdio.c | 4 +-- drivers/of/of_pci.c | 29 +++++++++++----------- drivers/of/overlay.c | 21 ++++++++-------- drivers/of/platform.c | 32 ++++++++++++------------ drivers/of/property.c | 19 +++++++-------- drivers/of/unittest.c | 67 ++++++++++++++++++++++++++++++--------------------- 11 files changed, 133 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/of/address.c b/drivers/of/address.c index 580bbf6ca2b1..ca1c0f6301ea 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -559,7 +559,7 @@ static u64 __of_translate_address(struct device_node *dev, int na, ns, pna, pns; u64 result = OF_BAD_ADDR; - pr_debug("** translation for device %s **\n", of_node_full_name(dev)); + pr_debug("** translation for device %pOF **\n", dev); /* Increase refcount at current level */ of_node_get(dev); @@ -573,13 +573,13 @@ static u64 __of_translate_address(struct device_node *dev, /* Count address cells & copy address locally */ bus->count_cells(dev, &na, &ns); if (!OF_CHECK_COUNTS(na, ns)) { - pr_debug("Bad cell count for %s\n", of_node_full_name(dev)); + pr_debug("Bad cell count for %pOF\n", dev); goto bail; } memcpy(addr, in_addr, na * 4); - pr_debug("bus is %s (na=%d, ns=%d) on %s\n", - bus->name, na, ns, of_node_full_name(parent)); + pr_debug("bus is %s (na=%d, ns=%d) on %pOF\n", + bus->name, na, ns, parent); of_dump_addr("translating address:", addr, na); /* Translate */ @@ -600,13 +600,12 @@ static u64 __of_translate_address(struct device_node *dev, pbus = of_match_bus(parent); pbus->count_cells(dev, &pna, &pns); if (!OF_CHECK_COUNTS(pna, pns)) { - pr_err("Bad cell count for %s\n", - of_node_full_name(dev)); + pr_err("Bad cell count for %pOF\n", dev); break; } - pr_debug("parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, of_node_full_name(parent)); + pr_debug("parent bus is %s (na=%d, ns=%d) on %pOF\n", + pbus->name, pna, pns, parent); /* Apply bus translation */ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) @@ -855,7 +854,7 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz } if (!ranges) { - pr_debug("no dma-ranges found for node(%s)\n", np->full_name); + pr_debug("no dma-ranges found for node(%pOF)\n", np); ret = -ENODEV; goto out; } @@ -872,8 +871,8 @@ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *siz dmaaddr = of_read_number(ranges, naddr); *paddr = of_translate_dma_address(np, ranges); if (*paddr == OF_BAD_ADDR) { - pr_err("translation of DMA address(%pad) to CPU address failed node(%s)\n", - dma_addr, np->full_name); + pr_err("translation of DMA address(%pad) to CPU address failed node(%pOF)\n", + dma_addr, np); ret = -EINVAL; goto out; } diff --git a/drivers/of/base.c b/drivers/of/base.c index 686628d1dfa6..5551ac2a9d4c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -160,7 +160,7 @@ int __of_add_property_sysfs(struct device_node *np, struct property *pp) pp->attr.read = of_node_property_read; rc = sysfs_create_bin_file(&np->kobj, &pp->attr); - WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name); + WARN(rc, "error adding attribute %s to node %pOF\n", pp->name, np); return rc; } @@ -1122,7 +1122,7 @@ EXPORT_SYMBOL(of_find_node_by_phandle); void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) { int i; - printk("%s %s", msg, of_node_full_name(args->np)); + printk("%s %pOF", msg, args->np); for (i = 0; i < args->args_count; i++) { const char delim = i ? ',' : ':'; @@ -1184,17 +1184,17 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it) if (it->cells_name) { if (!it->node) { - pr_err("%s: could not find phandle\n", - it->parent->full_name); + pr_err("%pOF: could not find phandle\n", + it->parent); goto err; } if (of_property_read_u32(it->node, it->cells_name, &count)) { - pr_err("%s: could not get %s for %s\n", - it->parent->full_name, + pr_err("%pOF: could not get %s for %pOF\n", + it->parent, it->cells_name, - it->node->full_name); + it->node); goto err; } } else { @@ -1206,8 +1206,8 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it) * property data length */ if (it->cur + count > it->list_end) { - pr_err("%s: arguments longer than property\n", - it->parent->full_name); + pr_err("%pOF: arguments longer than property\n", + it->parent); goto err; } } @@ -1639,8 +1639,8 @@ static void of_alias_add(struct alias_prop *ap, struct device_node *np, strncpy(ap->stem, stem, stem_len); ap->stem[stem_len] = 0; list_add_tail(&ap->link, &aliases_lookup); - pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n", - ap->alias, ap->stem, ap->id, of_node_full_name(np)); + pr_debug("adding DT alias:%s: stem=%s id=%i node=%pOF\n", + ap->alias, ap->stem, ap->id, np); } /** diff --git a/drivers/of/device.c b/drivers/of/device.c index 28c38c756f92..f9f31d66f64d 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -294,7 +294,7 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) return; add_uevent_var(env, "OF_NAME=%s", dev->of_node->name); - add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name); + add_uevent_var(env, "OF_FULLNAME=%pOF", dev->of_node); if (dev->of_node->type && strcmp("", dev->of_node->type) != 0) add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 0542cf8b6e3d..301b6db2b48d 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -98,14 +98,14 @@ int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) switch (action) { case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: - pr_debug("notify %-15s %s\n", action_names[action], - pr->dn->full_name); + pr_debug("notify %-15s %pOF\n", action_names[action], + pr->dn); break; case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: - pr_debug("notify %-15s %s:%s\n", action_names[action], - pr->dn->full_name, pr->prop->name); + pr_debug("notify %-15s %pOF:%s\n", action_names[action], + pr->dn, pr->prop->name); break; } @@ -328,11 +328,10 @@ void of_node_release(struct kobject *kobj) /* We should never be releasing nodes that haven't been detached. */ if (!of_node_check_flag(node, OF_DETACHED)) { - pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name); + pr_err("ERROR: Bad of_node_put() on %pOF\n", node); dump_stack(); return; } - if (!of_node_check_flag(node, OF_DYNAMIC)) return; @@ -462,13 +461,13 @@ static void __of_changeset_entry_dump(struct of_changeset_entry *ce) case OF_RECONFIG_ADD_PROPERTY: case OF_RECONFIG_REMOVE_PROPERTY: case OF_RECONFIG_UPDATE_PROPERTY: - pr_debug("cset<%p> %-15s %s/%s\n", ce, action_names[ce->action], - ce->np->full_name, ce->prop->name); + pr_debug("cset<%p> %-15s %pOF/%s\n", ce, action_names[ce->action], + ce->np, ce->prop->name); break; case OF_RECONFIG_ATTACH_NODE: case OF_RECONFIG_DETACH_NODE: - pr_debug("cset<%p> %-15s %s\n", ce, action_names[ce->action], - ce->np->full_name); + pr_debug("cset<%p> %-15s %pOF\n", ce, action_names[ce->action], + ce->np); break; } } @@ -539,7 +538,7 @@ static void __of_changeset_entry_notify(struct of_changeset_entry *ce, bool reve } if (ret) - pr_err("changeset notifier error @%s\n", ce->np->full_name); + pr_err("changeset notifier error @%pOF\n", ce->np); } static int __of_changeset_entry_apply(struct of_changeset_entry *ce) @@ -570,8 +569,8 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) ret = __of_add_property(ce->np, ce->prop); if (ret) { - pr_err("changeset: add_property failed @%s/%s\n", - ce->np->full_name, + pr_err("changeset: add_property failed @%pOF/%s\n", + ce->np, ce->prop->name); break; } @@ -579,8 +578,8 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) case OF_RECONFIG_REMOVE_PROPERTY: ret = __of_remove_property(ce->np, ce->prop); if (ret) { - pr_err("changeset: remove_property failed @%s/%s\n", - ce->np->full_name, + pr_err("changeset: remove_property failed @%pOF/%s\n", + ce->np, ce->prop->name); break; } @@ -598,8 +597,8 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) ret = __of_update_property(ce->np, ce->prop, &old_prop); if (ret) { - pr_err("changeset: update_property failed @%s/%s\n", - ce->np->full_name, + pr_err("changeset: update_property failed @%pOF/%s\n", + ce->np, ce->prop->name); break; } diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 6ce72aa65425..9c4b32522bc2 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -131,7 +131,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; @@ -269,7 +269,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; @@ -301,7 +301,7 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar u32 intsize, intlen; 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) @@ -555,8 +555,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); diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index e0dbd6e48a98..754b9d6cd1cd 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -166,8 +166,8 @@ static bool of_mdiobus_child_is_phy(struct device_node *child) if (of_match_node(whitelist_phys, child)) { pr_warn(FW_WARN - "%s: Whitelisted compatible string. Please remove\n", - child->full_name); + "%pOF: Whitelisted compatible string. Please remove\n", + child); return true; } diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index c9d4d3a7b0fe..3d4cb7090878 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -204,15 +204,15 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, if (!bus_range) return -ENOMEM; - pr_info("host bridge %s ranges:\n", dev->full_name); + pr_info("host bridge %pOF ranges:\n", dev); err = of_pci_parse_bus_range(dev, bus_range); if (err) { bus_range->start = busno; bus_range->end = bus_max; bus_range->flags = IORESOURCE_BUS; - pr_info(" No bus range found for %s, using %pR\n", - dev->full_name, bus_range); + pr_info(" No bus range found for %pOF, using %pR\n", + dev, bus_range); } else { if (bus_range->end > bus_range->start + bus_max) bus_range->end = bus_range->start + bus_max; @@ -258,14 +258,14 @@ int of_pci_get_host_bridge_resources(struct device_node *dev, if (resource_type(res) == IORESOURCE_IO) { if (!io_base) { - pr_err("I/O range found for %s. Please provide an io_base pointer to save CPU base address\n", - dev->full_name); + pr_err("I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n", + dev); err = -EINVAL; goto conversion_failed; } if (*io_base != (resource_size_t)OF_BAD_ADDR) - pr_warn("More than one I/O resource converted for %s. CPU base address for old range lost!\n", - dev->full_name); + pr_warn("More than one I/O resource converted for %pOF. CPU base address for old range lost!\n", + dev); *io_base = range.cpu_addr; } @@ -325,7 +325,7 @@ int of_pci_map_rid(struct device_node *np, u32 rid, } if (!map_len || map_len % (4 * sizeof(*map))) { - pr_err("%s: Error: Bad %s length: %d\n", np->full_name, + pr_err("%pOF: Error: Bad %s length: %d\n", np, map_name, map_len); return -EINVAL; } @@ -349,8 +349,8 @@ int of_pci_map_rid(struct device_node *np, u32 rid, u32 rid_len = be32_to_cpup(map + 3); if (rid_base & ~map_mask) { - pr_err("%s: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", - np->full_name, map_name, map_name, + pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", + np, map_name, map_name, map_mask, rid_base); return -EFAULT; } @@ -375,14 +375,13 @@ int of_pci_map_rid(struct device_node *np, u32 rid, if (id_out) *id_out = masked_rid - rid_base + out_base; - pr_debug("%s: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n", - np->full_name, map_name, map_mask, rid_base, out_base, + pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n", + np, map_name, map_mask, rid_base, out_base, rid_len, rid, *id_out); return 0; } - pr_err("%s: Invalid %s translation - no match for rid 0x%x on %s\n", - np->full_name, map_name, rid, - target && *target ? (*target)->full_name : "any target"); + pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n", + np, map_name, rid, target && *target ? *target : NULL); return -EFAULT; } diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index c0e4ee1cd1ba..0ddffebd7838 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -141,7 +141,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, of_node_put(tchild); } else { /* create empty tree as a target */ - tchild = __of_node_dup(child, "%s/%s", target->full_name, cname); + tchild = __of_node_dup(child, "%pOF/%s", target, cname); if (!tchild) return -ENOMEM; @@ -177,8 +177,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, for_each_property_of_node(overlay, prop) { ret = of_overlay_apply_single_property(ov, target, prop); if (ret) { - pr_err("Failed to apply prop @%s/%s\n", - target->full_name, prop->name); + pr_err("Failed to apply prop @%pOF/%s\n", + target, prop->name); return ret; } } @@ -186,8 +186,8 @@ static int of_overlay_apply_one(struct of_overlay *ov, for_each_child_of_node(overlay, child) { ret = of_overlay_apply_single_device_node(ov, target, child); if (ret != 0) { - pr_err("Failed to apply single node @%s/%s\n", - target->full_name, child->name); + pr_err("Failed to apply single node @%pOF/%s\n", + target, child->name); of_node_put(child); return ret; } @@ -215,7 +215,7 @@ static int of_overlay_apply(struct of_overlay *ov) err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay); if (err != 0) { - pr_err("apply failed '%s'\n", ovinfo->target->full_name); + pr_err("apply failed '%pOF'\n", ovinfo->target); return err; } } @@ -400,8 +400,8 @@ int of_overlay_create(struct device_node *tree) /* build the overlay info structures */ err = of_build_overlay_info(ov, tree); if (err) { - pr_err("of_build_overlay_info() failed for tree@%s\n", - tree->full_name); + pr_err("of_build_overlay_info() failed for tree@%pOF\n", + tree); goto err_free_idr; } @@ -480,9 +480,8 @@ static int overlay_is_topmost(struct of_overlay *ov, struct device_node *dn) /* check against each subtree affected by this overlay */ list_for_each_entry(ce, &ovt->cset.entries, node) { if (overlay_subtree_check(ce->np, dn)) { - pr_err("%s: #%d clashes #%d @%s\n", - __func__, ov->id, ovt->id, - dn->full_name); + pr_err("%s: #%d clashes #%d @%pOF\n", + __func__, ov->id, ovt->id, dn); return 0; } } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index b19524623498..683b2e74bef7 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -228,7 +228,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, const void *prop; int i, ret; - pr_debug("Creating amba device %s\n", node->full_name); + pr_debug("Creating amba device %pOF\n", node); if (!of_device_is_available(node) || of_node_test_and_set_flag(node, OF_POPULATED)) @@ -259,15 +259,15 @@ static struct amba_device *of_amba_device_create(struct device_node *node, ret = of_address_to_resource(node, 0, &dev->res); if (ret) { - pr_err("amba: of_address_to_resource() failed (%d) for %s\n", - ret, node->full_name); + pr_err("amba: of_address_to_resource() failed (%d) for %pOF\n", + ret, node); goto err_free; } ret = amba_device_add(dev, &iomem_resource); if (ret) { - pr_err("amba_device_add() failed (%d) for %s\n", - ret, node->full_name); + pr_err("amba_device_add() failed (%d) for %pOF\n", + ret, node); goto err_free; } @@ -310,7 +310,7 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l if (!of_address_to_resource(np, 0, &res)) if (res.start != auxdata->phys_addr) continue; - pr_debug("%s: devname=%s\n", np->full_name, auxdata->name); + pr_debug("%pOF: devname=%s\n", np, auxdata->name); return auxdata; } @@ -323,7 +323,7 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l if (!of_device_is_compatible(np, auxdata->compatible)) continue; if (!auxdata->phys_addr && !auxdata->name) { - pr_debug("%s: compatible match\n", np->full_name); + pr_debug("%pOF: compatible match\n", np); return auxdata; } } @@ -356,14 +356,14 @@ static int of_platform_bus_create(struct device_node *bus, /* Make sure it has a compatible property */ if (strict && (!of_get_property(bus, "compatible", NULL))) { - pr_debug("%s() - skipping %s, no compatible prop\n", - __func__, bus->full_name); + pr_debug("%s() - skipping %pOF, no compatible prop\n", + __func__, bus); return 0; } if (of_node_check_flag(bus, OF_POPULATED_BUS)) { - pr_debug("%s() - skipping %s, already populated\n", - __func__, bus->full_name); + pr_debug("%s() - skipping %pOF, already populated\n", + __func__, bus); return 0; } @@ -387,7 +387,7 @@ static int of_platform_bus_create(struct device_node *bus, return 0; for_each_child_of_node(bus, child) { - pr_debug(" create child: %s\n", child->full_name); + pr_debug(" create child: %pOF\n", child); rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); if (rc) { of_node_put(child); @@ -419,7 +419,7 @@ int of_platform_bus_probe(struct device_node *root, return -EINVAL; pr_debug("%s()\n", __func__); - pr_debug(" starting at: %s\n", root->full_name); + pr_debug(" starting at: %pOF\n", root); /* Do a self check of bus type, if there's a match, create children */ if (of_match_node(matches, root)) { @@ -471,7 +471,7 @@ int of_platform_populate(struct device_node *root, return -EINVAL; pr_debug("%s()\n", __func__); - pr_debug(" starting at: %s\n", root->full_name); + pr_debug(" starting at: %pOF\n", root); for_each_child_of_node(root, child) { rc = of_platform_bus_create(child, matches, lookup, parent, true); @@ -660,8 +660,8 @@ static int of_platform_notify(struct notifier_block *nb, of_dev_put(pdev_parent); if (pdev == NULL) { - pr_err("%s: failed to create for '%s'\n", - __func__, rd->dn->full_name); + pr_err("%s: failed to create for '%pOF'\n", + __func__, rd->dn); /* of_platform_device_create tosses the error code */ return notifier_from_errno(-EINVAL); } diff --git a/drivers/of/property.c b/drivers/of/property.c index eda50b4be934..ab4cf1da77b5 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -55,8 +55,8 @@ int of_property_count_elems_of_size(const struct device_node *np, return -ENODATA; if (prop->length % elem_size != 0) { - pr_err("size of %s in node %s is not a multiple of %d\n", - propname, np->full_name, elem_size); + pr_err("size of %s in node %pOF is not a multiple of %d\n", + propname, np, elem_size); return -EINVAL; } @@ -537,8 +537,8 @@ int of_graph_parse_endpoint(const struct device_node *node, { struct device_node *port_node = of_get_parent(node); - WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n", - __func__, node->full_name); + WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n", + __func__, node); memset(endpoint, 0, sizeof(*endpoint)); @@ -621,14 +621,13 @@ struct device_node *of_graph_get_next_endpoint(const struct device_node *parent, of_node_put(node); if (!port) { - pr_err("graph: no port node found in %s\n", - parent->full_name); + pr_err("graph: no port node found in %pOF\n", parent); return NULL; } } else { port = of_get_parent(prev); - if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n", - __func__, prev->full_name)) + if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n", + __func__, prev)) return NULL; } @@ -784,8 +783,8 @@ struct device_node *of_graph_get_remote_node(const struct device_node *node, endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint); if (!endpoint_node) { - pr_debug("no valid endpoint (%d, %d) for node %s\n", - port, endpoint, node->full_name); + pr_debug("no valid endpoint (%d, %d) for node %pOF\n", + port, endpoint, node); return NULL; } diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 0107fc680335..0959e8cc8814 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -46,46 +46,54 @@ static struct unittest_results { static void __init of_unittest_find_node_by_name(void) { struct device_node *np; - const char *options; + const char *options, *name; np = of_find_node_by_path("/testcase-data"); - unittest(np && !strcmp("/testcase-data", np->full_name), + name = kasprintf(GFP_KERNEL, "%pOF", np); + unittest(np && !strcmp("/testcase-data", name), "find /testcase-data failed\n"); of_node_put(np); + kfree(name); /* Test if trailing '/' works */ np = of_find_node_by_path("/testcase-data/"); unittest(!np, "trailing '/' on /testcase-data/ should fail\n"); np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name), + name = kasprintf(GFP_KERNEL, "%pOF", np); + unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find /testcase-data/phandle-tests/consumer-a failed\n"); of_node_put(np); + kfree(name); np = of_find_node_by_path("testcase-alias"); - unittest(np && !strcmp("/testcase-data", np->full_name), + name = kasprintf(GFP_KERNEL, "%pOF", np); + unittest(np && !strcmp("/testcase-data", name), "find testcase-alias failed\n"); of_node_put(np); + kfree(name); /* Test if trailing '/' works on aliases */ np = of_find_node_by_path("testcase-alias/"); unittest(!np, "trailing '/' on testcase-alias/ should fail\n"); np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a"); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", np->full_name), + name = kasprintf(GFP_KERNEL, "%pOF", np); + unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find testcase-alias/phandle-tests/consumer-a failed\n"); of_node_put(np); + kfree(name); np = of_find_node_by_path("/testcase-data/missing-path"); - unittest(!np, "non-existent path returned node %s\n", np->full_name); + unittest(!np, "non-existent path returned node %pOF\n", np); of_node_put(np); np = of_find_node_by_path("missing-alias"); - unittest(!np, "non-existent alias returned node %s\n", np->full_name); + unittest(!np, "non-existent alias returned node %pOF\n", np); of_node_put(np); np = of_find_node_by_path("testcase-alias/missing-path"); - unittest(!np, "non-existent alias with relative path returned node %s\n", np->full_name); + unittest(!np, "non-existent alias with relative path returned node %pOF\n", np); of_node_put(np); np = of_find_node_opts_by_path("/testcase-data:testoption", &options); @@ -315,8 +323,8 @@ static void __init of_unittest_check_phandles(void) hash_for_each_possible(phandle_ht, nh, node, np->phandle) { if (nh->np->phandle == np->phandle) { - pr_info("Duplicate phandle! %i used by %s and %s\n", - np->phandle, nh->np->full_name, np->full_name); + pr_info("Duplicate phandle! %i used by %pOF and %pOF\n", + np->phandle, nh->np, np); dup_count++; break; } @@ -406,8 +414,8 @@ static void __init of_unittest_parse_phandle_with_args(void) passed = false; } - unittest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); } /* Check for missing list property */ @@ -590,7 +598,7 @@ static void __init of_unittest_changeset(void) /* Make sure node names are constructed correctly */ unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), - "'%s' not added\n", n21->full_name); + "'%pOF' not added\n", n21); of_node_put(np); unittest(!of_changeset_revert(&chgset), "revert failed\n"); @@ -621,8 +629,8 @@ static void __init of_unittest_parse_interrupts(void) passed &= (args.args_count == 1); passed &= (args.args[0] == (i + 1)); - unittest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); } of_node_put(np); @@ -667,8 +675,8 @@ static void __init of_unittest_parse_interrupts(void) default: passed = false; } - unittest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); } of_node_put(np); } @@ -737,8 +745,8 @@ static void __init of_unittest_parse_interrupts_extended(void) passed = false; } - unittest(passed, "index %i - data error on node %s rc=%i\n", - i, args.np->full_name, rc); + unittest(passed, "index %i - data error on node %pOF rc=%i\n", + i, args.np, rc); } of_node_put(np); } @@ -917,8 +925,11 @@ static int attach_node_and_children(struct device_node *np) { struct device_node *next, *dup, *child; unsigned long flags; + const char *full_name; - dup = of_find_node_by_path(np->full_name); + full_name = kasprintf(GFP_KERNEL, "%pOF", np); + dup = of_find_node_by_path(full_name); + kfree(full_name); if (dup) { update_node_properties(np, dup); return 0; @@ -1023,7 +1034,7 @@ static int unittest_probe(struct platform_device *pdev) } - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); of_platform_populate(np, NULL, NULL, &pdev->dev); @@ -1035,7 +1046,7 @@ static int unittest_remove(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); return 0; } @@ -1649,7 +1660,7 @@ static int unittest_i2c_bus_probe(struct platform_device *pdev) } - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); std = devm_kzalloc(dev, sizeof(*std), GFP_KERNEL); if (!std) { @@ -1687,7 +1698,7 @@ static int unittest_i2c_bus_remove(struct platform_device *pdev) struct device_node *np = dev->of_node; struct unittest_i2c_bus_data *std = platform_get_drvdata(pdev); - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); i2c_del_adapter(&std->adap); return 0; @@ -1718,7 +1729,7 @@ static int unittest_i2c_dev_probe(struct i2c_client *client, return -EINVAL; } - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); return 0; }; @@ -1728,7 +1739,7 @@ static int unittest_i2c_dev_remove(struct i2c_client *client) struct device *dev = &client->dev; struct device_node *np = client->dev.of_node; - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); return 0; } @@ -1763,7 +1774,7 @@ static int unittest_i2c_mux_probe(struct i2c_client *client, struct i2c_mux_core *muxc; u32 reg, max_reg; - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); if (!np) { dev_err(dev, "No OF node\n"); @@ -1808,7 +1819,7 @@ static int unittest_i2c_mux_remove(struct i2c_client *client) struct device_node *np = client->dev.of_node; struct i2c_mux_core *muxc = i2c_get_clientdata(client); - dev_dbg(dev, "%s for node @%s\n", __func__, np->full_name); + dev_dbg(dev, "%s for node @%pOF\n", __func__, np); i2c_mux_del_adapters(muxc); return 0; } -- cgit From 60a0004cc9d66193ad9f1443315f52ec1086e25e Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Wed, 19 Jul 2017 09:25:20 -0700 Subject: of: overlay: add overlay unittest data for node names and symbols Add nodes and properties to overlay_base and overlay dts files to test for - incorrect existing node name detection when overlay node name has a unit-address - adding overlay __symbols__ properties to live tree when an overlay is added to the live tree The following console messages will appear near the end of unittest until the code errors are corrected: OF: Duplicate name in fairway-1, renamed to "ride@100#1" ### dt-test ### FAIL of_unittest_overlay_high_level():2296 Adding overlay 'overlay_bad_symbol' failed ### dt-test ### end of unittest - 190 passed, 1 failed Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/unittest-data/Makefile | 19 ++++++++++++++----- drivers/of/unittest-data/overlay.dts | 25 ++++++++++++++++++++++++- drivers/of/unittest-data/overlay_bad_symbol.dts | 22 ++++++++++++++++++++++ drivers/of/unittest-data/overlay_base.dts | 11 +++++++++++ drivers/of/unittest.c | 10 ++++++++-- 5 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 drivers/of/unittest-data/overlay_bad_symbol.dts (limited to 'drivers') diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile index 6e00a9c69e58..2d135fba94c1 100644 --- a/drivers/of/unittest-data/Makefile +++ b/drivers/of/unittest-data/Makefile @@ -1,18 +1,27 @@ obj-y += testcases.dtb.o + +targets += testcases.dtb testcases.dtb.S + +ifdef CONFIG_OF_OVERLAY + obj-y += overlay.dtb.o obj-y += overlay_bad_phandle.dtb.o +obj-y += overlay_bad_symbol.dtb.o obj-y += overlay_base.dtb.o -targets += testcases.dtb testcases.dtb.S targets += overlay.dtb overlay.dtb.S targets += overlay_bad_phandle.dtb overlay_bad_phandle.dtb.S +targets += overlay_bad_symbol.dtb overlay_bad_symbol.dtb.S targets += overlay_base.dtb overlay_base.dtb.S -.PRECIOUS: \ - $(obj)/%.dtb.S \ - $(obj)/%.dtb - # enable creation of __symbols__ node DTC_FLAGS_overlay := -@ DTC_FLAGS_overlay_bad_phandle := -@ +DTC_FLAGS_overlay_bad_symbol := -@ DTC_FLAGS_overlay_base := -@ + +endif + +.PRECIOUS: \ + $(obj)/%.dtb.S \ + $(obj)/%.dtb diff --git a/drivers/of/unittest-data/overlay.dts b/drivers/of/unittest-data/overlay.dts index 6cd7e6a0c13e..60abf5b55cae 100644 --- a/drivers/of/unittest-data/overlay.dts +++ b/drivers/of/unittest-data/overlay.dts @@ -25,7 +25,22 @@ #size-cells = <1>; status = "ok"; - ride@200 { + ride@100 { + #address-cells = <1>; + #size-cells = <1>; + + track@30 { + incline-up = < 48 32 16 >; + }; + + track@40 { + incline-up = < 47 31 15 >; + }; + }; + + ride_200: ride@200 { + #address-cells = <1>; + #size-cells = <1>; compatible = "ot,ferris-wheel"; reg = < 0x00000200 0x100 >; hvac-provider = < &hvac_2 >; @@ -36,6 +51,14 @@ spin-rph = < 30 >; gondolas = < 16 >; gondola-capacity = < 6 >; + + ride_200_left: track@10 { + reg = < 0x00000010 0x10 >; + }; + + ride_200_right: track@20 { + reg = < 0x00000020 0x10 >; + }; }; }; }; diff --git a/drivers/of/unittest-data/overlay_bad_symbol.dts b/drivers/of/unittest-data/overlay_bad_symbol.dts new file mode 100644 index 000000000000..09261cb9a67e --- /dev/null +++ b/drivers/of/unittest-data/overlay_bad_symbol.dts @@ -0,0 +1,22 @@ +/dts-v1/; +/plugin/; + +/ { + + fragment@0 { + target = <&electric_1>; + + __overlay__ { + + // This label should cause an error when the overlay + // is applied. There is already a symbol hvac_1 + // in the base tree + hvac_1: hvac-medium-2 { + compatible = "ot,hvac-medium"; + heat-range = < 50 75 >; + cool-range = < 60 80 >; + }; + + }; + }; +}; diff --git a/drivers/of/unittest-data/overlay_base.dts b/drivers/of/unittest-data/overlay_base.dts index 5566b27fb61a..453d0bd83320 100644 --- a/drivers/of/unittest-data/overlay_base.dts +++ b/drivers/of/unittest-data/overlay_base.dts @@ -44,6 +44,8 @@ orientation = < 127 >; ride@100 { + #address-cells = <1>; + #size-cells = <1>; compatible = "ot,roller-coaster"; reg = < 0x00000100 0x100 >; hvac-provider = < &hvac_1 >; @@ -53,6 +55,15 @@ spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >; spin-controller-names = "track_1", "track_2"; queues = < 2 >; + + track@30 { + reg = < 0x00000030 0x10 >; + }; + + track@40 { + reg = < 0x00000040 0x10 >; + }; + }; }; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 0959e8cc8814..29a35cb1da64 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1994,6 +1994,8 @@ out: static inline void __init of_unittest_overlay(void) { } #endif +#ifdef CONFIG_OF_OVERLAY + /* * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb * in scripts/Makefile.lib @@ -2021,14 +2023,14 @@ struct overlay_info { OVERLAY_INFO_EXTERN(overlay_base); OVERLAY_INFO_EXTERN(overlay); OVERLAY_INFO_EXTERN(overlay_bad_phandle); - -#ifdef CONFIG_OF_OVERLAY +OVERLAY_INFO_EXTERN(overlay_bad_symbol); /* order of entries is hard-coded into users of overlays[] */ static struct overlay_info overlays[] = { OVERLAY_INFO(overlay_base, -9999), OVERLAY_INFO(overlay, 0), OVERLAY_INFO(overlay_bad_phandle, -EINVAL), + OVERLAY_INFO(overlay_bad_symbol, -EINVAL), {} }; @@ -2300,6 +2302,10 @@ static __init void of_unittest_overlay_high_level(void) unittest(overlay_data_add(2), "Adding overlay 'overlay_bad_phandle' failed\n"); + + unittest(overlay_data_add(3), + "Adding overlay 'overlay_bad_symbol' failed\n"); + return; err_unlock: -- cgit From c1cd1e01fece0c139a7946c14b788f887d8b658a Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Wed, 19 Jul 2017 09:25:21 -0700 Subject: of: overlay: correctly apply overlay node with unit-address Correct existing node name detection when overlay node name has a unit-address. Expected test result is overlay will update the nodes and properties for /testcase-data-2/fairway-1/ride@100/ after this commit. Before this commit: Console error message near end of unittest: OF: Duplicate name in fairway-1, renamed to "ride@100#1" $ cd /proc/device-tree/testcase-data-2/fairway-1/ $ # extra node: ride@100#1 $ ls #address-cells linux,phandle phandle ride@200 #size-cells name ride@100 status compatible orientation ride@100#1 $ cd /proc/device-tree/testcase-data-2/fairway-1/ride@100/ $ ls track@30/incline-up ls: track@30/incline-up: No such file or directory $ ls track@40/incline-up ls: track@40/incline-up: No such file or directory After this commit: Console error message no longer occurs $ cd /proc/device-tree/testcase-data-2/fairway-1/ $ # no extra node: ride@100#1 $ ls #address-cells compatible name phandle ride@200 #size-cells linux,phandle orientation ride@100 status $ cd /proc/device-tree/testcase-data-2/fairway-1/ride@100/ $ ls track@30/incline-up track@30/incline-up $ ls track@40/incline-up track@40/incline-up Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/overlay.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 0ddffebd7838..fbe1980accb6 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -130,7 +130,10 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, return -ENOMEM; /* NOTE: Multiple mods of created nodes not supported */ - tchild = of_get_child_by_name(target, cname); + for_each_child_of_node(target, tchild) + if (!of_node_cmp(cname, kbasename(tchild->full_name))) + break; + if (tchild != NULL) { /* new overlay phandle value conflicts with existing value */ if (child->phandle) -- cgit From d1651b03c2df75db8eda3fbcd3a07adb337ee8b0 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Wed, 19 Jul 2017 09:25:22 -0700 Subject: of: overlay: add overlay symbols to live device tree Add overlay __symbols__ properties to live tree when an overlay is added to the live tree so that the symbols are available to subsequent overlays. Expected test result is new __symbols__ entries for labels from the overlay after this commit. Before this commit: Console error message near end of unittest: ### dt-test ### FAIL of_unittest_overlay_high_level():2296 Adding overlay 'overlay_bad_symbol' failed ### dt-test ### end of unittest - 190 passed, 1 failed The new unittest "fails" because the expected result of loading the new overlay is an error instead of success. $ # node hvac-medium-2 exists because the overlay loaded $ # since the duplicate symbol was not detected $ cd /proc/device-tree/testcase-data-2/substation@100/ $ ls compatible hvac-medium-2 motor-8 reg hvac-large-1 linux,phandle name status hvac-medium-1 motor-1 phandle $ cd /proc/device-tree/__symbols__/ $ ls electric_1 lights_1 name rides_1 spin_ctrl_2 hvac_1 lights_2 retail_1 spin_ctrl_1 After this commit: Previous console error message no longer occurs, but expected error occurs: OF: overlay: Failed to apply prop @/__symbols__/hvac_1 OF: overlay: apply failed '/__symbols__' ### dt-test ### end of unittest - 191 passed, 0 failed $ # node hvac-medium-2 does not exist because the overlay $ # properly failed to load due to the duplicate symbol $ cd /proc/device-tree/testcase-data-2/substation@100/ $ ls compatible hvac-medium-1 motor-1 name reg hvac-large-1 linux,phandle motor-8 phandle status $ cd /proc/device-tree/__symbols__/ $ ls electric_1 lights_1 retail_1 ride_200_right spin_ctrl_2 hvac_1 lights_2 ride_200 rides_1 hvac_2 name ride_200_left spin_ctrl_1 $ cat ride_200; echo /testcase-data-2/fairway-1/ride@200 $ cat ride_200_left ; echo /testcase-data-2/fairway-1/ride@200/track@10 $ cat ride_200_right ; echo /testcase-data-2/fairway-1/ride@200/track@20 Signed-off-by: Frank Rowand Signed-off-by: Rob Herring --- drivers/of/overlay.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 107 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index fbe1980accb6..8ecfee31ab6d 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -35,6 +35,7 @@ struct of_overlay_info { struct device_node *target; struct device_node *overlay; + bool is_symbols_node; }; /** @@ -55,7 +56,8 @@ struct of_overlay { }; static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay); + struct device_node *target, const struct device_node *overlay, + bool is_symbols_node); static BLOCKING_NOTIFIER_HEAD(of_overlay_chain); @@ -92,10 +94,74 @@ static int of_overlay_notify(struct of_overlay *ov, return 0; } +static struct property *dup_and_fixup_symbol_prop(struct of_overlay *ov, + const struct property *prop) +{ + struct of_overlay_info *ovinfo; + struct property *new; + const char *overlay_name; + char *label_path; + char *symbol_path; + const char *target_path; + int k; + int label_path_len; + int overlay_name_len; + int target_path_len; + + if (!prop->value) + return NULL; + symbol_path = prop->value; + + new = kzalloc(sizeof(*new), GFP_KERNEL); + if (!new) + return NULL; + + for (k = 0; k < ov->count; k++) { + ovinfo = &ov->ovinfo_tab[k]; + overlay_name = ovinfo->overlay->full_name; + overlay_name_len = strlen(overlay_name); + if (!strncasecmp(symbol_path, overlay_name, overlay_name_len)) + break; + } + + if (k >= ov->count) + goto err_free; + + target_path = ovinfo->target->full_name; + target_path_len = strlen(target_path); + + label_path = symbol_path + overlay_name_len; + label_path_len = strlen(label_path); + + new->name = kstrdup(prop->name, GFP_KERNEL); + new->length = target_path_len + label_path_len + 1; + new->value = kzalloc(new->length, GFP_KERNEL); + + if (!new->name || !new->value) + goto err_free; + + strcpy(new->value, target_path); + strcpy(new->value + target_path_len, label_path); + + /* mark the property as dynamic */ + of_property_set_flag(new, OF_DYNAMIC); + + return new; + + err_free: + kfree(new->name); + kfree(new->value); + kfree(new); + return NULL; + + +} + static int of_overlay_apply_single_property(struct of_overlay *ov, - struct device_node *target, struct property *prop) + struct device_node *target, struct property *prop, + bool is_symbols_node) { - struct property *propn, *tprop; + struct property *propn = NULL, *tprop; /* NOTE: Multiple changes of single properties not supported */ tprop = of_find_property(target, prop->name, NULL); @@ -106,7 +172,15 @@ static int of_overlay_apply_single_property(struct of_overlay *ov, of_prop_cmp(prop->name, "linux,phandle") == 0) return 0; - propn = __of_prop_dup(prop, GFP_KERNEL); + if (is_symbols_node) { + /* changing a property in __symbols__ node not allowed */ + if (tprop) + return -EINVAL; + propn = dup_and_fixup_symbol_prop(ov, prop); + } else { + propn = __of_prop_dup(prop, GFP_KERNEL); + } + if (propn == NULL) return -ENOMEM; @@ -140,7 +214,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, return -EINVAL; /* apply overlay recursively */ - ret = of_overlay_apply_one(ov, tchild, child); + ret = of_overlay_apply_one(ov, tchild, child, 0); of_node_put(tchild); } else { /* create empty tree as a target */ @@ -155,7 +229,7 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, if (ret) return ret; - ret = of_overlay_apply_one(ov, tchild, child); + ret = of_overlay_apply_one(ov, tchild, child, 0); if (ret) return ret; } @@ -171,14 +245,16 @@ static int of_overlay_apply_single_device_node(struct of_overlay *ov, * by using the changeset. */ static int of_overlay_apply_one(struct of_overlay *ov, - struct device_node *target, const struct device_node *overlay) + struct device_node *target, const struct device_node *overlay, + bool is_symbols_node) { struct device_node *child; struct property *prop; int ret; for_each_property_of_node(overlay, prop) { - ret = of_overlay_apply_single_property(ov, target, prop); + ret = of_overlay_apply_single_property(ov, target, prop, + is_symbols_node); if (ret) { pr_err("Failed to apply prop @%pOF/%s\n", target, prop->name); @@ -186,6 +262,10 @@ static int of_overlay_apply_one(struct of_overlay *ov, } } + /* do not allow symbols node to have any children */ + if (is_symbols_node) + return 0; + for_each_child_of_node(overlay, child) { ret = of_overlay_apply_single_device_node(ov, target, child); if (ret != 0) { @@ -216,7 +296,8 @@ static int of_overlay_apply(struct of_overlay *ov) for (i = 0; i < ov->count; i++) { struct of_overlay_info *ovinfo = &ov->ovinfo_tab[i]; - err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay); + err = of_overlay_apply_one(ov, ovinfo->target, ovinfo->overlay, + ovinfo->is_symbols_node); if (err != 0) { pr_err("apply failed '%pOF'\n", ovinfo->target); return err; @@ -314,6 +395,9 @@ static int of_build_overlay_info(struct of_overlay *ov, for_each_child_of_node(tree, node) cnt++; + if (of_get_child_by_name(tree, "__symbols__")) + cnt++; + ovinfo = kcalloc(cnt, sizeof(*ovinfo), GFP_KERNEL); if (ovinfo == NULL) return -ENOMEM; @@ -325,6 +409,20 @@ static int of_build_overlay_info(struct of_overlay *ov, cnt++; } + node = of_get_child_by_name(tree, "__symbols__"); + if (node) { + ovinfo[cnt].overlay = node; + ovinfo[cnt].target = of_find_node_by_path("/__symbols__"); + ovinfo[cnt].is_symbols_node = 1; + + if (!ovinfo[cnt].target) { + pr_err("no symbols in root of device tree.\n"); + return -EINVAL; + } + + cnt++; + } + /* if nothing filled, return error */ if (cnt == 0) { kfree(ovinfo); -- cgit From 6a245d959c747079e88bb1c61baa61d43d460a44 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 8 Jul 2017 23:29:51 +0300 Subject: of: irq: use of_property_read_bool() for "interrupt-controller" prop The "interrupt-controller" property is boolean, i.e. has no value. The DT interrupt parsing code predates of_property_read_bool(), so it uses either of_get_property() or of_find_property() -- the former isn't quite correct for the boolean props (but works somehow). Use the modern boolean prop API instead. Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/irq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9c4b32522bc2..1f6ef2305daa 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -169,8 +169,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; } @@ -508,7 +507,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; -- cgit From fa976ff7b00c31af2b9069751cd55140d8aa30b4 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 8 Jul 2017 23:29:52 +0300 Subject: of: irq: use of_property_read_u32() The DT interrupt parsing code predates of_property_read_u32(), so it has to basically open-code it. Using the modern DT API saves several LoCs and also adds some prop sanity checks as a bonus... Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/irq.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 1f6ef2305daa..abbd252fe25b 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); @@ -228,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); @@ -296,7 +292,7 @@ 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; + const __be32 *intspec, *addr; u32 intsize, intlen; int i, res; @@ -330,12 +326,10 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar 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); -- cgit From fda9f5d4a97cedba3174641263a49d82ff3c3469 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Wed, 12 Jul 2017 17:59:06 +0800 Subject: of: remove unused pci_space variable from address.c It was never used and could be removed, otherwise we could see a warning: drivers/of/address.c: In function 'of_pci_range_parser_one': drivers/of/address.c:277:14: warning: variable 'pci_space' set but not used [-Wunused-but-set-variable] Signed-off-by: Shawn Lin Signed-off-by: Rob Herring --- drivers/of/address.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/address.c b/drivers/of/address.c index ca1c0f6301ea..792722e7d458 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -274,10 +274,9 @@ struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser, /* Now consume following elements while they are contiguous */ while (parser->range + parser->np <= parser->end) { - u32 flags, pci_space; + u32 flags; u64 pci_addr, cpu_addr, size; - pci_space = be32_to_cpup(parser->range); flags = of_bus_pci_get_flags(parser->range); pci_addr = of_read_number(parser->range + 1, ns); cpu_addr = of_translate_address(parser->node, -- cgit From 8832963d89f09e4cef6c1ec62f0082a545baf69d Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jul 2017 19:55:47 +0300 Subject: of: base: use of_property_read_u32() of_n_{addr|size}_cells() predate of_property_read_u32(), so they have to basically open-code it. Using the modern DT API saves several LoCs and also adds some prop sanity checks as a bonus... Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/base.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 5551ac2a9d4c..830f8d2f3594 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -60,14 +60,13 @@ DEFINE_RAW_SPINLOCK(devtree_lock); int of_n_addr_cells(struct device_node *np) { - const __be32 *ip; + u32 cells; do { if (np->parent) np = np->parent; - ip = of_get_property(np, "#address-cells", NULL); - if (ip) - return be32_to_cpup(ip); + if (!of_property_read_u32(np, "#address-cells", &cells)) + return cells; } while (np->parent); /* No #address-cells property for the root node */ return OF_ROOT_NODE_ADDR_CELLS_DEFAULT; @@ -76,14 +75,13 @@ EXPORT_SYMBOL(of_n_addr_cells); int of_n_size_cells(struct device_node *np) { - const __be32 *ip; + u32 cells; do { if (np->parent) np = np->parent; - ip = of_get_property(np, "#size-cells", NULL); - if (ip) - return be32_to_cpup(ip); + if (!of_property_read_u32(np, "#size-cells", &cells)) + return cells; } while (np->parent); /* No #size-cells property for the root node */ return OF_ROOT_NODE_SIZE_CELLS_DEFAULT; -- cgit From b0d9d92f9ce60cd070a62c136914e6fe9d20d49d Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jul 2017 19:55:48 +0300 Subject: of: base: use of_property_read_string() of_alias_scan() can use of_property_read_string() -- using the modern DT API adds some prop sanity checks as a bonus; it does add couple LoCs but only because the original code violated the 80-column limit... Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/base.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/of/base.c b/drivers/of/base.c index 830f8d2f3594..260d33c0f26c 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1662,11 +1662,13 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align)) if (of_chosen) { /* linux,stdout-path and /aliases/stdout are for legacy compatibility */ - const char *name = of_get_property(of_chosen, "stdout-path", NULL); - if (!name) - name = of_get_property(of_chosen, "linux,stdout-path", NULL); + const char *name = NULL; + + if (of_property_read_string(of_chosen, "stdout-path", &name)) + of_property_read_string(of_chosen, "linux,stdout-path", + &name); if (IS_ENABLED(CONFIG_PPC) && !name) - name = of_get_property(of_aliases, "stdout", NULL); + of_property_read_string(of_aliases, "stdout", &name); if (name) of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); } -- cgit From 56134e3c649b97085df50fe85ae479e3d3a87d7f Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jul 2017 22:41:45 +0300 Subject: of_pci: use of_property_read_u32() of_get_pci_domain_nr() somehow didn't use of_property_read_u32() though it was long available, basically open-coding it. Using the modern DT API saves several LoCs/bytes and also adds some prop sanity checks as a bonus... Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/of_pci.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 3d4cb7090878..0162e4ba30e2 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -105,17 +105,14 @@ EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); */ int of_get_pci_domain_nr(struct device_node *node) { - const __be32 *value; - int len; - u16 domain; - - value = of_get_property(node, "linux,pci-domain", &len); - if (!value || len < sizeof(*value)) - return -EINVAL; + u32 domain; + int error; - domain = (u16)be32_to_cpup(value); + error = of_property_read_u32(node, "linux,pci-domain", &domain); + if (error) + return error; - return domain; + return (u16)domain; } EXPORT_SYMBOL_GPL(of_get_pci_domain_nr); -- cgit From e2af1f561168897de43b179e5b9d513392721eff Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 23 Jul 2017 22:41:46 +0300 Subject: of_pci: use of_property_read_u32_array() of_pci_get_devfn() and of_pci_parse_bus_range() somehow didn't use of_property_read_u32_array() though it was long available, basically open-coding it. Using the modern DT API saves several bytes and also adds some prop sanity checks as a bonus... Signed-off-by: Sergei Shtylyov Signed-off-by: Rob Herring --- drivers/of/of_pci.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index 0162e4ba30e2..e9ec931f5b9a 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c @@ -57,15 +57,14 @@ EXPORT_SYMBOL_GPL(of_pci_find_child_device); */ int of_pci_get_devfn(struct device_node *np) { - unsigned int size; - const __be32 *reg; - - reg = of_get_property(np, "reg", &size); + u32 reg[5]; + int error; - if (!reg || size < 5 * sizeof(__be32)) - return -EINVAL; + error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg)); + if (error) + return error; - return (be32_to_cpup(reg) >> 8) & 0xff; + return (reg[0] >> 8) & 0xff; } EXPORT_SYMBOL_GPL(of_pci_get_devfn); @@ -78,16 +77,17 @@ EXPORT_SYMBOL_GPL(of_pci_get_devfn); */ int of_pci_parse_bus_range(struct device_node *node, struct resource *res) { - const __be32 *values; - int len; + u32 bus_range[2]; + int error; - values = of_get_property(node, "bus-range", &len); - if (!values || len < sizeof(*values) * 2) - return -EINVAL; + error = of_property_read_u32_array(node, "bus-range", bus_range, + ARRAY_SIZE(bus_range)); + if (error) + return error; res->name = node->name; - res->start = be32_to_cpup(values++); - res->end = be32_to_cpup(values); + res->start = bus_range[0]; + res->end = bus_range[1]; res->flags = IORESOURCE_BUS; return 0; -- cgit From bc575064d688c8933a6ca51429bea9bc63628d3b Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Jul 2017 15:45:32 -0500 Subject: of/device: use of_property_for_each_string to parse compatible strings Instead of directly parsing the compatible property, use the of_property_for_each_string() helper to iterate over each compatible string. This reduces the LoC and makes the functions easier to understand. Signed-off-by: Rob Herring --- drivers/of/device.c | 66 +++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/of/device.c b/drivers/of/device.c index f9f31d66f64d..9d0895fb53b5 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -195,9 +195,10 @@ EXPORT_SYMBOL(of_device_get_match_data); static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { - const char *compat; - int cplen, i; - ssize_t tsize, csize, repend; + const char *compat, *start = str; + char *c; + struct property *p; + ssize_t csize; if ((!dev) || (!dev->of_node)) return -ENODEV; @@ -205,42 +206,24 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len /* Name & Type */ csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, dev->of_node->type); - - /* Get compatible property if any */ - compat = of_get_property(dev->of_node, "compatible", &cplen); - if (!compat) - return csize; - - /* Find true end (we tolerate multiple \0 at the end */ - for (i = (cplen - 1); i >= 0 && !compat[i]; i--) - cplen--; - if (!cplen) - return csize; - cplen++; - - /* Check space (need cplen+1 chars including final \0) */ - tsize = csize + cplen; - repend = tsize; - - if (csize >= len) /* @ the limit, all is already filled */ - return tsize; - - if (tsize >= len) { /* limit compat list */ - cplen = len - csize - 1; - repend = len; - } - - /* Copy and do char replacement */ - memcpy(&str[csize + 1], compat, cplen); - for (i = csize; i < repend; i++) { - char c = str[i]; - if (c == '\0') - str[i] = 'C'; - else if (c == ' ') - str[i] = '_'; + len -= csize; + str += csize; + + of_property_for_each_string(dev->of_node, "compatible", p, compat) { + if (strlen(compat) + 2 > len) + break; + + csize = snprintf(str, len, "C%s", compat); + for (c = str; c; ) { + c = strchr(c, ' '); + if (c) + *c++ = '_'; + } + len -= csize; + str += csize; } - return repend; + return str - start; } int of_device_request_module(struct device *dev) @@ -288,7 +271,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) { const char *compat; struct alias_prop *app; - int seen = 0, cplen, sl; + struct property *p; + int seen = 0; if ((!dev) || (!dev->of_node)) return; @@ -301,12 +285,8 @@ void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(dev->of_node, "compatible", &cplen); - while (compat && *compat && cplen > 0) { + of_property_for_each_string(dev->of_node, "compatible", p, compat) { add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); - sl = strlen(compat) + 1; - compat += sl; - cplen -= sl; seen++; } add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); -- cgit From b47fe22d82e39551a5049f4bd02eb71f7d497762 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 21 Jul 2017 16:56:12 -0500 Subject: of/irq: use of_property_read_u32_index to parse interrupts property Convert the interrupts property parsing to use the OF property API instead of open coding the parsing of the raw property value. This saves a number of LoC, and the result is easier to read. Signed-off-by: Rob Herring --- drivers/of/irq.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/of/irq.c b/drivers/of/irq.c index abbd252fe25b..aa2a60c8868e 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -292,8 +292,8 @@ 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, *addr; - u32 intsize, intlen; + const __be32 *addr; + u32 intsize; int i, res; pr_debug("of_irq_parse_one: dev=%pOF, index=%d\n", device, index); @@ -311,15 +311,6 @@ 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) @@ -331,20 +322,21 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar goto out; } - 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); -- cgit From 358155ede4fbd047d055a0ffee95d042b02872ae Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 10 Aug 2017 04:38:16 +0000 Subject: device property: use of_graph_get_remote_endpoint() for of_fwnode Now, we can use of_graph_get_remote_endpoint(). Let's use it. Signed-off-by: Kuninori Morimoto Signed-off-by: Rob Herring --- drivers/of/property.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/property.c b/drivers/of/property.c index ab4cf1da77b5..9eb45f69db2f 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -899,8 +899,8 @@ of_fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode, static struct fwnode_handle * of_fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode) { - return of_fwnode_handle(of_parse_phandle(to_of_node(fwnode), - "remote-endpoint", 0)); + return of_fwnode_handle( + of_graph_get_remote_endpoint(to_of_node(fwnode))); } static struct fwnode_handle * -- cgit From 08ab58d9de3eb8498ae0585001d0975e46217a39 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 23 Aug 2017 18:04:04 -0700 Subject: of/device: Prevent buffer overflow in of_device_modalias() As of_device_get_modalias() returns the number of bytes that would have been written to the target string, regardless of how much did fit in the buffer, it's possible that the returned index points beyond the buffer passed to of_device_modalias() - causing memory beyond the buffer to be null terminated. Fixes: 0634c2958927 ("of: Add function for generating a DT modalias with a newline") Cc: Rob Herring Cc: stable@vger.kernel.org Signed-off-by: Bjorn Andersson Signed-off-by: Rob Herring --- drivers/of/device.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/of/device.c b/drivers/of/device.c index 9d0895fb53b5..c5c06997fdd2 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -257,6 +257,8 @@ ssize_t of_device_modalias(struct device *dev, char *str, ssize_t len) ssize_t sl = of_device_get_modalias(dev, str, len - 2); if (sl < 0) return sl; + if (sl > len - 2) + return -ENOMEM; str[sl++] = '\n'; str[sl] = 0; -- cgit From 8c2a75e5687e0137ddbb35454c7a1a468079f790 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Wed, 23 Aug 2017 18:03:52 -0700 Subject: of/device: Fix of_device_get_modalias() buffer handling of_device_request_module() calls of_device_get_modalias() with "len" 0, to calculate the size of the buffer needed to store the result, but due to integer promotion the ssize_t "len" will be compared as unsigned with strlen(compat) and the loop will generally never break. This results in a call to snprintf() with a negative len, which triggers below warning, followed by a dereference of a invalid pointer: [ 3.060067] WARNING: CPU: 0 PID: 51 at lib/vsprintf.c:2122 vsnprintf+0x348/0x6d8 ... [ 3.060301] [] vsnprintf+0x348/0x6d8 [ 3.060308] [] snprintf+0x48/0x50 [ 3.060316] [] of_device_get_modalias+0x108/0x160 [ 3.060322] [] of_device_request_module+0x20/0x88 ... Further more of_device_get_modalias() is supposed to return the number of bytes needed to store the entire modalias, so the loop needs to continue accumulate the total size even though the buffer is full. Finally the function is not expected to ensure space for the NUL, nor include it in the returned size, so only 1 should be added to the length of "compat" in the loop (to account for the character 'C'). Fixes: bc575064d688 ("of/device: use of_property_for_each_string to parse compatible strings") Cc: Rob Herring Signed-off-by: Bjorn Andersson Signed-off-by: Rob Herring --- drivers/of/device.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/of/device.c b/drivers/of/device.c index c5c06997fdd2..11a17582e568 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -195,10 +195,11 @@ EXPORT_SYMBOL(of_device_get_match_data); static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) { - const char *compat, *start = str; + const char *compat; char *c; struct property *p; ssize_t csize; + ssize_t tsize; if ((!dev) || (!dev->of_node)) return -ENODEV; @@ -206,12 +207,16 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len /* Name & Type */ csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name, dev->of_node->type); + tsize = csize; len -= csize; - str += csize; + if (str) + str += csize; of_property_for_each_string(dev->of_node, "compatible", p, compat) { - if (strlen(compat) + 2 > len) - break; + csize = strlen(compat) + 1; + tsize += csize; + if (csize > len) + continue; csize = snprintf(str, len, "C%s", compat); for (c = str; c; ) { @@ -223,7 +228,7 @@ static ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len str += csize; } - return str - start; + return tsize; } int of_device_request_module(struct device *dev) -- cgit From 6d7e3bf8d12c0ae8b297de428e67301df1b95c5f Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 25 Aug 2017 18:33:13 +0300 Subject: of: Use PLATFORM_DEVID_NONE definition Use dedicated definition instead of plain -1 where it's appropriate. No functional change intended. Signed-off-by: Andy Shevchenko Signed-off-by: Rob Herring --- drivers/of/device.c | 2 +- drivers/of/platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/of/device.c b/drivers/of/device.c index 11a17582e568..af31e6b9ac74 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -58,7 +58,7 @@ int of_device_add(struct platform_device *ofdev) /* name and id have to be set so that the platform bus doesn't get * confused on matching */ ofdev->name = dev_name(&ofdev->dev); - ofdev->id = -1; + ofdev->id = PLATFORM_DEVID_NONE; /* * If this device has not binding numa node in devicetree, that is diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 683b2e74bef7..ac15d0e3d27d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -118,7 +118,7 @@ struct platform_device *of_device_alloc(struct device_node *np, int rc, i, num_reg = 0, num_irq; struct resource *res, temp_res; - dev = platform_device_alloc("", -1); + dev = platform_device_alloc("", PLATFORM_DEVID_NONE); if (!dev) return NULL; -- cgit From 066cf01dbf7a970796b6cb9532a5b9bf7380d5d7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Jun 2017 16:24:43 -0500 Subject: ide: pmac: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Acked-by: David S. Miller Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: linux-ide@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org --- drivers/ide/pmac.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 0c5d3a99468e..c5b902b86b44 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c @@ -1145,8 +1145,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, return -ENOMEM; if (macio_resource_count(mdev) == 0) { - printk(KERN_WARNING "ide-pmac: no address for %s\n", - mdev->ofdev.dev.of_node->full_name); + printk(KERN_WARNING "ide-pmac: no address for %pOF\n", + mdev->ofdev.dev.of_node); rc = -ENXIO; goto out_free_pmif; } @@ -1154,7 +1154,7 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, /* Request memory resource for IO ports */ if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) { printk(KERN_ERR "ide-pmac: can't request MMIO resource for " - "%s!\n", mdev->ofdev.dev.of_node->full_name); + "%pOF!\n", mdev->ofdev.dev.of_node); rc = -EBUSY; goto out_free_pmif; } @@ -1165,8 +1165,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, * where that happens though... */ if (macio_irq_count(mdev) == 0) { - printk(KERN_WARNING "ide-pmac: no intrs for device %s, using " - "13\n", mdev->ofdev.dev.of_node->full_name); + printk(KERN_WARNING "ide-pmac: no intrs for device %pOF, using " + "13\n", mdev->ofdev.dev.of_node); irq = irq_create_mapping(NULL, 13); } else irq = macio_irq(mdev, 0); @@ -1183,8 +1183,8 @@ static int pmac_ide_macio_attach(struct macio_dev *mdev, if (macio_resource_count(mdev) >= 2) { if (macio_request_resource(mdev, 1, "ide-pmac (dma)")) printk(KERN_WARNING "ide-pmac: can't request DMA " - "resource for %s!\n", - mdev->ofdev.dev.of_node->full_name); + "resource for %pOF!\n", + mdev->ofdev.dev.of_node); else pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000); } else @@ -1274,7 +1274,7 @@ static int pmac_ide_pci_attach(struct pci_dev *pdev, if (pci_enable_device(pdev)) { printk(KERN_WARNING "ide-pmac: Can't enable PCI device for " - "%s\n", np->full_name); + "%pOF\n", np); rc = -ENXIO; goto out_free_pmif; } @@ -1282,7 +1282,7 @@ static int pmac_ide_pci_attach(struct pci_dev *pdev, if (pci_request_regions(pdev, "Kauai ATA")) { printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources for " - "%s\n", np->full_name); + "%pOF\n", np); rc = -ENXIO; goto out_free_pmif; } -- cgit From 985541f6c01e67bcdce433847d1b56fe8f523bf0 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Jun 2017 16:28:24 -0500 Subject: macintosh: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring Cc: Benjamin Herrenschmidt Cc: linuxppc-dev@lists.ozlabs.org --- drivers/macintosh/macio_sysfs.c | 2 +- drivers/macintosh/rack-meter.c | 4 ++-- drivers/macintosh/smu.c | 8 ++++---- drivers/macintosh/via-cuda.c | 4 ++-- drivers/macintosh/windfarm_fcu_controls.c | 4 ++-- drivers/macintosh/windfarm_lm87_sensor.c | 4 ++-- drivers/macintosh/windfarm_smu_sat.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 2445274f7e4b..281f5345661e 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -52,7 +52,7 @@ static ssize_t devspec_show(struct device *dev, struct platform_device *ofdev; ofdev = to_platform_device(dev); - return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); + return sprintf(buf, "%pOF\n", ofdev->dev.of_node); } static DEVICE_ATTR_RO(modalias); static DEVICE_ATTR_RO(devspec); diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index e199fd6c71ce..e9da80ceb7c8 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -431,8 +431,8 @@ static int rackmeter_probe(struct macio_dev* mdev, of_address_to_resource(i2s, 0, &ri2s) || of_address_to_resource(i2s, 1, &rdma)) { printk(KERN_ERR - "rackmeter: found match but lacks resources: %s", - mdev->ofdev.dev.of_node->full_name); + "rackmeter: found match but lacks resources: %pOF", + mdev->ofdev.dev.of_node); rc = -ENXIO; goto bail_free; } diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 1ac66421877a..ea9bdc85a21d 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -589,14 +589,14 @@ static int smu_late_init(void) if (smu->db_node) { smu->db_irq = irq_of_parse_and_map(smu->db_node, 0); if (!smu->db_irq) - printk(KERN_ERR "smu: failed to map irq for node %s\n", - smu->db_node->full_name); + printk(KERN_ERR "smu: failed to map irq for node %pOF\n", + smu->db_node); } if (smu->msg_node) { smu->msg_irq = irq_of_parse_and_map(smu->msg_node, 0); if (!smu->msg_irq) - printk(KERN_ERR "smu: failed to map irq for node %s\n", - smu->msg_node->full_name); + printk(KERN_ERR "smu: failed to map irq for node %pOF\n", + smu->msg_node); } /* diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c index c60415958dfe..147da4edd021 100644 --- a/drivers/macintosh/via-cuda.c +++ b/drivers/macintosh/via-cuda.c @@ -297,8 +297,8 @@ static int __init via_cuda_start(void) #else cuda_irq = irq_of_parse_and_map(vias, 0); if (!cuda_irq) { - printk(KERN_ERR "via-cuda: can't map interrupts for %s\n", - vias->full_name); + printk(KERN_ERR "via-cuda: can't map interrupts for %pOF\n", + vias); return -ENODEV; } #endif diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c index 0226b796a21c..fab7a21e9577 100644 --- a/drivers/macintosh/windfarm_fcu_controls.c +++ b/drivers/macintosh/windfarm_fcu_controls.c @@ -470,8 +470,8 @@ static void wf_fcu_lookup_fans(struct wf_fcu_priv *pv) id = ((*reg) - 0x30) / 2; if (id > 7) { pr_warning("wf_fcu: Can't parse " - "fan ID in device-tree for %s\n", - np->full_name); + "fan ID in device-tree for %pOF\n", + np); break; } wf_fcu_add_fan(pv, name, type, id); diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c index c071aab79dd1..913c4bfeef94 100644 --- a/drivers/macintosh/windfarm_lm87_sensor.c +++ b/drivers/macintosh/windfarm_lm87_sensor.c @@ -126,8 +126,8 @@ static int wf_lm87_probe(struct i2c_client *client, } } if (!name) { - pr_warning("wf_lm87: Unsupported sensor %s\n", - client->dev.of_node->full_name); + pr_warning("wf_lm87: Unsupported sensor %pOF\n", + client->dev.of_node); return -ENODEV; } diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index ad6223e88340..e9c828bf171b 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -248,7 +248,7 @@ static int wf_sat_probe(struct i2c_client *client, core = loc[5] - '0'; if (chip > 1 || core > 1) { printk(KERN_ERR "wf_sat_create: don't understand " - "location %s for %s\n", loc, child->full_name); + "location %s for %pOF\n", loc, child); continue; } cpu = 2 * chip + core; -- cgit From 55e18b18335132cb21d815e09c376fca891f5af2 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 6 Jun 2017 16:45:15 -0500 Subject: virt: Convert to using %pOF instead of full_name Now that we have a custom printf format specifier, convert users of full_name to use %pOF instead. This is preparation to remove storing of the full path string for each node. Signed-off-by: Rob Herring --- drivers/virt/fsl_hypervisor.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index d3eca879a0a8..d993df5586c0 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -841,8 +841,8 @@ static int __init fsl_hypervisor_init(void) handle = of_get_property(np, "interrupts", NULL); irq = irq_of_parse_and_map(np, 0); if (!handle || (irq == NO_IRQ)) { - pr_err("fsl-hv: no 'interrupts' property in %s node\n", - np->full_name); + pr_err("fsl-hv: no 'interrupts' property in %pOF node\n", + np); continue; } @@ -869,8 +869,8 @@ static int __init fsl_hypervisor_init(void) */ dbisr->partition = ret = get_parent_handle(np); if (ret < 0) { - pr_err("fsl-hv: node %s has missing or " - "malformed parent\n", np->full_name); + pr_err("fsl-hv: node %pOF has missing or " + "malformed parent\n", np); kfree(dbisr); continue; } @@ -881,8 +881,8 @@ static int __init fsl_hypervisor_init(void) ret = request_irq(irq, fsl_hv_isr, 0, np->name, dbisr); if (ret < 0) { - pr_err("fsl-hv: could not request irq %u for node %s\n", - irq, np->full_name); + pr_err("fsl-hv: could not request irq %u for node %pOF\n", + irq, np); kfree(dbisr); continue; } -- cgit From 84024468cf1612783e6ab317da5b72fa41487ac6 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sat, 2 Sep 2017 03:44:07 -0400 Subject: devicetree: Adjust status "ok" -> "okay" under drivers/of/ Tweak a small number of status "ok" lines in a single file under /drivers/of/ to use the proper DTSpec 0.1 spelling of "okay". Signed-off-by: Robert P. J. Day Signed-off-by: Rob Herring --- drivers/of/unittest-data/overlay.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/unittest-data/overlay.dts b/drivers/of/unittest-data/overlay.dts index 60abf5b55cae..9e791fcf05dd 100644 --- a/drivers/of/unittest-data/overlay.dts +++ b/drivers/of/unittest-data/overlay.dts @@ -7,7 +7,7 @@ target = <&electric_1>; __overlay__ { - status = "ok"; + status = "okay"; hvac_2: hvac-large-1 { compatible = "ot,hvac-large"; @@ -23,7 +23,7 @@ __overlay__ { #address-cells = <1>; #size-cells = <1>; - status = "ok"; + status = "okay"; ride@100 { #address-cells = <1>; @@ -67,7 +67,7 @@ target = <&lights_2>; __overlay__ { - status = "ok"; + status = "okay"; color = "purple", "white", "red", "green"; rate = < 3 256 >; }; -- cgit