| /* |
| * Copyright (c) 2014 Hauke Mehrtens <hauke@hauke-m.de> |
| * Copyright (c) 2015 Luis R. Rodriguez <mcgrof@do-not-panic.com> |
| * |
| * Backport functionality introduced in Linux 3.15. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| */ |
| #include <linux/version.h> |
| #include <linux/kernel.h> |
| #include <linux/device.h> |
| #include <linux/of.h> |
| #include <linux/string.h> |
| #include <linux/mm.h> |
| #include <linux/slab.h> |
| #include <linux/vmalloc.h> |
| #include <net/net_namespace.h> |
| |
| /** |
| * devm_kstrdup - Allocate resource managed space and |
| * copy an existing string into that. |
| * @dev: Device to allocate memory for |
| * @s: the string to duplicate |
| * @gfp: the GFP mask used in the devm_kmalloc() call when |
| * allocating memory |
| * RETURNS: |
| * Pointer to allocated string on success, NULL on failure. |
| */ |
| char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) |
| { |
| size_t size; |
| char *buf; |
| |
| if (!s) |
| return NULL; |
| |
| size = strlen(s) + 1; |
| buf = devm_kmalloc(dev, size, gfp); |
| if (buf) |
| memcpy(buf, s, size); |
| return buf; |
| } |
| EXPORT_SYMBOL_GPL(devm_kstrdup); |
| |
| #ifdef CONFIG_OF |
| /** |
| * of_property_count_elems_of_size - Count the number of elements in a property |
| * |
| * @np: device node from which the property value is to be read. |
| * @propname: name of the property to be searched. |
| * @elem_size: size of the individual element |
| * |
| * Search for a property in a device node and count the number of elements of |
| * size elem_size in it. Returns number of elements on sucess, -EINVAL if the |
| * property does not exist or its length does not match a multiple of elem_size |
| * and -ENODATA if the property does not have a value. |
| */ |
| int of_property_count_elems_of_size(const struct device_node *np, |
| const char *propname, int elem_size) |
| { |
| struct property *prop = of_find_property(np, propname, NULL); |
| |
| if (!prop) |
| return -EINVAL; |
| if (!prop->value) |
| 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); |
| return -EINVAL; |
| } |
| |
| return prop->length / elem_size; |
| } |
| EXPORT_SYMBOL_GPL(of_property_count_elems_of_size); |
| #endif |
| |
| void kvfree(const void *addr) |
| { |
| if (is_vmalloc_addr(addr)) |
| vfree(addr); |
| else |
| kfree(addr); |
| } |
| EXPORT_SYMBOL_GPL(kvfree); |