diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/of/base.c | 12 | ||||
| -rw-r--r-- | drivers/of/of_reserved_mem.c | 47 |
2 files changed, 54 insertions, 5 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c index a25c95800..835e57007 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1506,15 +1506,15 @@ EXPORT_SYMBOL(__of_parse_phandle_with_args); * @list_name: property name that contains a list * @stem_name: stem of property names that specify phandles' arguments count * @index: index of a phandle to parse out - * @out_args: optional pointer to output arguments structure (will be filled) + * @_out_args: optional pointer to output arguments structure (will be filled) * * This function is useful to parse lists of phandles and their arguments. - * Returns 0 on success and fills out_args, on error returns appropriate errno + * Returns 0 on success and fills @_out_args, on error returns appropriate errno * value. The difference between this function and of_parse_phandle_with_args() * is that this API remaps a phandle if the node the phandle points to has * a <@stem_name>-map property. * - * Caller is responsible to call of_node_put() on the returned out_args->np + * Caller is responsible to call of_node_put() on the returned @_out_args->np * pointer. * * Example:: @@ -1545,7 +1545,7 @@ EXPORT_SYMBOL(__of_parse_phandle_with_args); int of_parse_phandle_with_args_map(const struct device_node *np, const char *list_name, const char *stem_name, - int index, struct of_phandle_args *out_args) + int index, struct of_phandle_args *_out_args) { char *cells_name __free(kfree) = kasprintf(GFP_KERNEL, "#%s-cells", stem_name); char *map_name __free(kfree) = kasprintf(GFP_KERNEL, "%s-map", stem_name); @@ -1555,6 +1555,8 @@ int of_parse_phandle_with_args_map(const struct device_node *np, const __be32 *map, *mask, *pass; static const __be32 dummy_mask[] = { [0 ... (MAX_PHANDLE_ARGS - 1)] = cpu_to_be32(~0) }; static const __be32 dummy_pass[] = { [0 ... (MAX_PHANDLE_ARGS - 1)] = cpu_to_be32(0) }; + struct of_phandle_args _oa = {}; + struct of_phandle_args *out_args = _out_args ? _out_args : &_oa; __be32 initial_match_array[MAX_PHANDLE_ARGS]; const __be32 *match_array = initial_match_array; int i, ret, map_len, match; @@ -1586,6 +1588,8 @@ int of_parse_phandle_with_args_map(const struct device_node *np, /* Get the <list>-map property */ map = of_get_property(cur, map_name, &map_len); if (!map) { + if (!_out_args) + of_node_put(out_args->np); return 0; } map_len /= sizeof(u32); diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 42e3e2d8a..8c9d6395d 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -641,7 +641,8 @@ static void __init fdt_init_reserved_mem_node(unsigned long node, const char *un struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; if (reserved_mem_count == total_reserved_mem_cnt) { - pr_err("not enough space for all defined regions.\n"); + pr_err("not enough space for all defined regions, skip '%s'\n", + uname); return; } @@ -795,6 +796,50 @@ void of_reserved_mem_device_release(struct device *dev) } EXPORT_SYMBOL_GPL(of_reserved_mem_device_release); +static void devm_of_reserved_mem_device_release(struct device *dev, void *res) +{ + of_reserved_mem_device_release(*(struct device **)res); +} + +static int devm_of_reserved_mem_device_init_by_idx(struct device *dev, + struct device_node *np, int idx) +{ + struct device **ptr; + int ret; + + ptr = devres_alloc(devm_of_reserved_mem_device_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = of_reserved_mem_device_init_by_idx(dev, np, idx); + if (ret) { + devres_free(ptr); + return ret; + } + + *ptr = dev; + devres_add(dev, ptr); + + return 0; +} + +/** + * devm_of_reserved_mem_device_init() - Resource managed of_reserved_mem_device_init() + * @dev: Pointer to the device to configure + * + * This is a resource managed version of of_reserved_mem_device_init(). + * The reserved memory region will be released automatically when the device + * is unbound. + * + * Returns: Negative errno on failure or zero on success. + */ +int devm_of_reserved_mem_device_init(struct device *dev) +{ + return devm_of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0); +} +EXPORT_SYMBOL_GPL(devm_of_reserved_mem_device_init); + /** * of_reserved_mem_lookup() - acquire reserved_mem from a device node * @np: node pointer of the desired reserved-memory region |
