blob: 051aec2a40088e6241ab75e18919e045a2c1d78b [file] [log] [blame]
/*
* 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 <net/net_namespace.h>
extern void vfree(const void *addr);
#if IS_ENABLED(CPTCFG_IEEE802154_6LOWPAN)
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)
/* the above kernel dependency is set to match the dependencies file */
struct netns_ieee802154_lowpan ieee802154_lowpan;
EXPORT_SYMBOL_GPL(ieee802154_lowpan);
struct netns_ieee802154_lowpan *net_ieee802154_lowpan(struct net *net)
{
return &ieee802154_lowpan;
}
EXPORT_SYMBOL_GPL(net_ieee802154_lowpan);
#endif
#endif /* CPTCFG_IEEE802154_6LOWPAN */
/**
* 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);