forked from rrcarlosr/Jetpack
89 lines
2.4 KiB
C
89 lines
2.4 KiB
C
|
/*
|
||
|
* 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);
|