All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Sverdlin <alexander.sverdlin@nsn.com>
To: ext Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
	Grant Likely <grant.likely@secretlab.ca>,
	Ionut Nicu <ioan.nicu.ext@nsn.com>
Cc: Rob Herring <robherring2@gmail.com>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Matt Porter <matt.porter@linaro.org>,
	Koen Kooi <koen@dominion.thruhere.net>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Alison Chaiken <Alison_Chaiken@mentor.com>,
	Dinh Nguyen <dinh.linux@gmail.com>, Jan Lubbe <jluebbe@lasnet.de>,
	Michael Stickel <ms@mycable.de>,
	Guenter Roeck <linux@roeck-us.net>,
	Dirk Behme <dirk.behme@gmail.com>,
	Alan Tull <delicious.quinoa@gmail.com>,
	Sascha Hauer <s.hauer@pengutronix.de>,
	Michael Bohan <mbohan@codeaurora.org>,
	Michal Simek <monstr@monstr.eu>,
	Matt Ranostay <mranostay@gmail.com>,
	Joel Becker <jlbec@evilplan.org>,
	devicetree@vger.kernel.org, Wolfram Sang <wsa@the-dreams.de>,
	linux-i2c@vger.kernel.org, Mark Brown <broonie@kernel.org>,
	linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org,
	Pete Popov <pete.popov@konsulko.com>,
	Dan Malek <dan.malek@konsulko.com>,
	Georgi Vlaev <georgi.vlaev@konsulko.com>,
	Pantelis Antoniou <panto@antoniou-consulting.com>
Subject: Re: [PATCH 5/6] OF: Utility helper functions for dynamic nodes
Date: Mon, 23 Jun 2014 18:26:49 +0200	[thread overview]
Message-ID: <53A85549.7040809@nsn.com> (raw)
In-Reply-To: <1403430039-15085-6-git-send-email-pantelis.antoniou@konsulko.com>

Hello Pantelis!

On 22/06/14 11:40, ext Pantelis Antoniou wrote:
> Introduce helper functions for working with the live DT tree,
> all of them related to dynamically adding/removing nodes and
> properties.
> 
> __of_copy_property() copies a property dynamically
> __of_create_empty_node() creates an empty node
> 
> Bug fix about prop->len == 0 by Ionut Nicu <ioan.nicu.ext@nsn.com>

Are you sure about this? (see below...)
 
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
> ---
>  drivers/of/Makefile |   2 +-
>  drivers/of/util.c   | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of.h  |  42 ++++++++++++++++
>  3 files changed, 184 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/of/util.c
> 
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 099b1fb..734d3e2 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -1,4 +1,4 @@
> -obj-y = base.o device.o platform.o
> +obj-y = base.o device.o platform.o util.o
>  obj-$(CONFIG_OF_FLATTREE) += fdt.o
>  obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
>  obj-$(CONFIG_OF_PROMTREE) += pdt.o
> diff --git a/drivers/of/util.c b/drivers/of/util.c
> new file mode 100644
> index 0000000..f4211f8
> --- /dev/null
> +++ b/drivers/of/util.c
> @@ -0,0 +1,141 @@
> +/*
> + * Utility functions for working with device tree(s)
> + *
> + * Copyright (C) 2012 Pantelis Antoniou <panto@antoniou-consulting.com>
> + * Copyright (C) 2012 Texas Instruments Inc.
> + *
> + * 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/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/string.h>
> +#include <linux/ctype.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +
> +/**
> + * __of_copy_property - Copy a property dynamically.
> + * @prop:	Property to copy
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @propflags:	Property flags
> + *
> + * Copy a property by dynamically allocating the memory of both the
> + * property stucture and the property name & contents. The property's
> + * flags have the OF_DYNAMIC bit set so that we can differentiate between
> + * dynamically allocated properties and not.
> + * Returns the newly allocated property or NULL on out of memory error.
> + */
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	struct property *propn;
> +
> +	propn = kzalloc(sizeof(*prop), allocflags);
> +	if (propn == NULL)
> +		return NULL;
> +
> +	propn->_flags = propflags;
> +
> +	if (of_property_check_flag(propn, OF_ALLOCNAME)) {
> +		propn->name = kstrdup(prop->name, allocflags);
> +		if (propn->name == NULL)
> +			goto err_fail_name;
> +	} else
> +		propn->name = prop->name;
> +
> +	if (prop->length > 0) {
        ^^^^^^^^^^^^^^^^^^^^^
Seems, that length==0 case will still produce value==NULL results,
which will brake some checks in the kernel... Or am I missing something in
the new version?


> +		if (of_property_check_flag(propn, OF_ALLOCVALUE)) {
> +			propn->value = kmalloc(prop->length, allocflags);
> +			if (propn->value == NULL)
> +				goto err_fail_value;
> +			memcpy(propn->value, prop->value, prop->length);
> +		} else
> +			propn->value = prop->value;
> +
> +		propn->length = prop->length;
> +	}
> +
> +	/* mark the property as dynamic */
> +	of_property_set_flag(propn, OF_DYNAMIC);
> +
> +	return propn;
> +
> +err_fail_value:
> +	if (of_property_check_flag(propn, OF_ALLOCNAME))
> +		kfree(propn->name);
> +err_fail_name:
> +	kfree(propn);
> +	return NULL;
> +}
> +
> +/**
> + * __of_create_empty_node - Create an empty device node dynamically.
> + * @name:	Name of the new device node
> + * @type:	Type of the new device node
> + * @full_name:	Full name of the new device node
> + * @phandle:	Phandle of the new device node
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @nodeflags:	Node flags
> + *
> + * Create an empty device tree node, suitable for further modification.
> + * The node data are dynamically allocated and all the node flags
> + * have the OF_DYNAMIC & OF_DETACHED bits set.
> + * Returns the newly allocated node or NULL on out of memory error.
> + */
> +struct device_node *__of_create_empty_node(
> +		const char *name, const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	struct device_node *node;
> +
> +	node = kzalloc(sizeof(*node), allocflags);
> +	if (node == NULL)
> +		return NULL;
> +
> +	node->_flags = nodeflags;
> +
> +	if (of_node_check_flag(node, OF_ALLOCNAME)) {
> +		node->name = kstrdup(name, allocflags);
> +		if (node->name == NULL)
> +			goto err_free_node;
> +	} else
> +		node->name = name;
> +
> +	if (of_node_check_flag(node, OF_ALLOCTYPE)) {
> +		node->type = kstrdup(type, allocflags);
> +		if (node->type == NULL)
> +			goto err_free_name;
> +	} else
> +		node->type = type;
> +
> +	if (of_node_check_flag(node, OF_ALLOCFULL)) {
> +		node->full_name = kstrdup(full_name, allocflags);
> +		if (node->full_name == NULL)
> +			goto err_free_type;
> +	} else
> +		node->full_name = full_name;
> +
> +	node->phandle = phandle;
> +	of_node_set_flag(node, OF_DYNAMIC);
> +	of_node_set_flag(node, OF_DETACHED);
> +
> +	of_node_init(node);
> +
> +	return node;
> +err_free_type:
> +	if (of_node_check_flag(node, OF_ALLOCTYPE))
> +		kfree(node->type);
> +err_free_name:
> +	if (of_node_check_flag(node, OF_ALLOCNAME))
> +		kfree(node->name);
> +err_free_node:
> +	kfree(node);
> +	return NULL;
> +}
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 5e4e1b3..d381eb5 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -211,6 +211,15 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
>  #define OF_DYNAMIC	1 /* node and properties were allocated via kmalloc */
>  #define OF_DETACHED	2 /* node has been detached from the device tree */
>  #define OF_POPULATED	3 /* device already created for the node */
> +#define OF_ALLOCNAME	4 /* name was kmalloc-ed */
> +#define OF_ALLOCTYPE	5 /* type was kmalloc-ed */
> +#define OF_ALLOCFULL	6 /* full_name was kmalloc-ed */
> +#define OF_ALLOCVALUE	7 /* value was kmalloc-ed */
> +
> +#define OF_NODE_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCTYPE) | (1 << OF_ALLOCFULL))
> +#define OF_PROP_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCVALUE))
>  
>  #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
>  #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
> @@ -824,4 +833,37 @@ typedef void (*of_init_fn_1)(struct device_node *);
>  #define OF_DECLARE_2(table, name, compat, fn) \
>  		_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
>  
> +/**
> + * General utilities for working with live trees.
> + *
> + * All functions with two leading underscores operate
> + * without taking node references, so you either have to
> + * own the devtree lock or work on detached trees only.
> + */
> +
> +#ifdef CONFIG_OF
> +
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags);
> +struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags);
> +
> +#else /* !CONFIG_OF */
> +
> +static inline struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	return NULL;
> +}
> +
> +static inline struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	return NULL;
> +}
> +
> +#endif	/* !CONFIG_OF */
> +
>  #endif /* _LINUX_OF_H */
> 

-- 
Best regards,
Alexander Sverdlin.

WARNING: multiple messages have this Message-ID (diff)
From: Alexander Sverdlin <alexander.sverdlin-OYasijW0DpE@public.gmane.org>
To: ext Pantelis Antoniou
	<pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>,
	Grant Likely
	<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>,
	Ionut Nicu <ioan.nicu.ext-OYasijW0DpE@public.gmane.org>
Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Matt Porter <matt.porter-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Koen Kooi
	<koen-QLwJDigV5abLmq1fohREcCpxlwaOVQ5f@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	Alison Chaiken
	<Alison_Chaiken-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>,
	Dinh Nguyen <dinh.linux-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Jan Lubbe <jluebbe-H4yykcOXDpCzQB+pC5nmwQ@public.gmane.org>,
	Michael Stickel <ms-g5CePrrZ5ROELgA04lAiVw@public.gmane.org>,
	Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>,
	Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Alan Tull
	<delicious.quinoa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	Michael Bohan <mbohan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	Michal Simek <monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>,
	Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Joel Becker <jlbec-aKy9MeLSZ9dg9hUCZPvPmw@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Pete Popov <pete.popov-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>,
	Dan Malek <dan.male>
Subject: Re: [PATCH 5/6] OF: Utility helper functions for dynamic nodes
Date: Mon, 23 Jun 2014 18:26:49 +0200	[thread overview]
Message-ID: <53A85549.7040809@nsn.com> (raw)
In-Reply-To: <1403430039-15085-6-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

Hello Pantelis!

On 22/06/14 11:40, ext Pantelis Antoniou wrote:
> Introduce helper functions for working with the live DT tree,
> all of them related to dynamically adding/removing nodes and
> properties.
> 
> __of_copy_property() copies a property dynamically
> __of_create_empty_node() creates an empty node
> 
> Bug fix about prop->len == 0 by Ionut Nicu <ioan.nicu.ext-OYasijW0DpE@public.gmane.org>

Are you sure about this? (see below...)
 
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/of/Makefile |   2 +-
>  drivers/of/util.c   | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of.h  |  42 ++++++++++++++++
>  3 files changed, 184 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/of/util.c
> 
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 099b1fb..734d3e2 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -1,4 +1,4 @@
> -obj-y = base.o device.o platform.o
> +obj-y = base.o device.o platform.o util.o
>  obj-$(CONFIG_OF_FLATTREE) += fdt.o
>  obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
>  obj-$(CONFIG_OF_PROMTREE) += pdt.o
> diff --git a/drivers/of/util.c b/drivers/of/util.c
> new file mode 100644
> index 0000000..f4211f8
> --- /dev/null
> +++ b/drivers/of/util.c
> @@ -0,0 +1,141 @@
> +/*
> + * Utility functions for working with device tree(s)
> + *
> + * Copyright (C) 2012 Pantelis Antoniou <panto-wVdstyuyKrO8r51toPun2/C9HSW9iNxf@public.gmane.org>
> + * Copyright (C) 2012 Texas Instruments Inc.
> + *
> + * 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/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/string.h>
> +#include <linux/ctype.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +
> +/**
> + * __of_copy_property - Copy a property dynamically.
> + * @prop:	Property to copy
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @propflags:	Property flags
> + *
> + * Copy a property by dynamically allocating the memory of both the
> + * property stucture and the property name & contents. The property's
> + * flags have the OF_DYNAMIC bit set so that we can differentiate between
> + * dynamically allocated properties and not.
> + * Returns the newly allocated property or NULL on out of memory error.
> + */
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	struct property *propn;
> +
> +	propn = kzalloc(sizeof(*prop), allocflags);
> +	if (propn == NULL)
> +		return NULL;
> +
> +	propn->_flags = propflags;
> +
> +	if (of_property_check_flag(propn, OF_ALLOCNAME)) {
> +		propn->name = kstrdup(prop->name, allocflags);
> +		if (propn->name == NULL)
> +			goto err_fail_name;
> +	} else
> +		propn->name = prop->name;
> +
> +	if (prop->length > 0) {
        ^^^^^^^^^^^^^^^^^^^^^
Seems, that length==0 case will still produce value==NULL results,
which will brake some checks in the kernel... Or am I missing something in
the new version?


> +		if (of_property_check_flag(propn, OF_ALLOCVALUE)) {
> +			propn->value = kmalloc(prop->length, allocflags);
> +			if (propn->value == NULL)
> +				goto err_fail_value;
> +			memcpy(propn->value, prop->value, prop->length);
> +		} else
> +			propn->value = prop->value;
> +
> +		propn->length = prop->length;
> +	}
> +
> +	/* mark the property as dynamic */
> +	of_property_set_flag(propn, OF_DYNAMIC);
> +
> +	return propn;
> +
> +err_fail_value:
> +	if (of_property_check_flag(propn, OF_ALLOCNAME))
> +		kfree(propn->name);
> +err_fail_name:
> +	kfree(propn);
> +	return NULL;
> +}
> +
> +/**
> + * __of_create_empty_node - Create an empty device node dynamically.
> + * @name:	Name of the new device node
> + * @type:	Type of the new device node
> + * @full_name:	Full name of the new device node
> + * @phandle:	Phandle of the new device node
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @nodeflags:	Node flags
> + *
> + * Create an empty device tree node, suitable for further modification.
> + * The node data are dynamically allocated and all the node flags
> + * have the OF_DYNAMIC & OF_DETACHED bits set.
> + * Returns the newly allocated node or NULL on out of memory error.
> + */
> +struct device_node *__of_create_empty_node(
> +		const char *name, const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	struct device_node *node;
> +
> +	node = kzalloc(sizeof(*node), allocflags);
> +	if (node == NULL)
> +		return NULL;
> +
> +	node->_flags = nodeflags;
> +
> +	if (of_node_check_flag(node, OF_ALLOCNAME)) {
> +		node->name = kstrdup(name, allocflags);
> +		if (node->name == NULL)
> +			goto err_free_node;
> +	} else
> +		node->name = name;
> +
> +	if (of_node_check_flag(node, OF_ALLOCTYPE)) {
> +		node->type = kstrdup(type, allocflags);
> +		if (node->type == NULL)
> +			goto err_free_name;
> +	} else
> +		node->type = type;
> +
> +	if (of_node_check_flag(node, OF_ALLOCFULL)) {
> +		node->full_name = kstrdup(full_name, allocflags);
> +		if (node->full_name == NULL)
> +			goto err_free_type;
> +	} else
> +		node->full_name = full_name;
> +
> +	node->phandle = phandle;
> +	of_node_set_flag(node, OF_DYNAMIC);
> +	of_node_set_flag(node, OF_DETACHED);
> +
> +	of_node_init(node);
> +
> +	return node;
> +err_free_type:
> +	if (of_node_check_flag(node, OF_ALLOCTYPE))
> +		kfree(node->type);
> +err_free_name:
> +	if (of_node_check_flag(node, OF_ALLOCNAME))
> +		kfree(node->name);
> +err_free_node:
> +	kfree(node);
> +	return NULL;
> +}
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 5e4e1b3..d381eb5 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -211,6 +211,15 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
>  #define OF_DYNAMIC	1 /* node and properties were allocated via kmalloc */
>  #define OF_DETACHED	2 /* node has been detached from the device tree */
>  #define OF_POPULATED	3 /* device already created for the node */
> +#define OF_ALLOCNAME	4 /* name was kmalloc-ed */
> +#define OF_ALLOCTYPE	5 /* type was kmalloc-ed */
> +#define OF_ALLOCFULL	6 /* full_name was kmalloc-ed */
> +#define OF_ALLOCVALUE	7 /* value was kmalloc-ed */
> +
> +#define OF_NODE_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCTYPE) | (1 << OF_ALLOCFULL))
> +#define OF_PROP_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCVALUE))
>  
>  #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
>  #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
> @@ -824,4 +833,37 @@ typedef void (*of_init_fn_1)(struct device_node *);
>  #define OF_DECLARE_2(table, name, compat, fn) \
>  		_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
>  
> +/**
> + * General utilities for working with live trees.
> + *
> + * All functions with two leading underscores operate
> + * without taking node references, so you either have to
> + * own the devtree lock or work on detached trees only.
> + */
> +
> +#ifdef CONFIG_OF
> +
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags);
> +struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags);
> +
> +#else /* !CONFIG_OF */
> +
> +static inline struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	return NULL;
> +}
> +
> +static inline struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	return NULL;
> +}
> +
> +#endif	/* !CONFIG_OF */
> +
>  #endif /* _LINUX_OF_H */
> 

-- 
Best regards,
Alexander Sverdlin.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

WARNING: multiple messages have this Message-ID (diff)
From: Alexander Sverdlin <alexander.sverdlin-OYasijW0DpE@public.gmane.org>
To: ext Pantelis Antoniou
	<pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>,
	Grant Likely
	<grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org>,
	Ionut Nicu <ioan.nicu.ext-OYasijW0DpE@public.gmane.org>
Cc: Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	Matt Porter <matt.porter-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	Koen Kooi
	<koen-QLwJDigV5abLmq1fohREcCpxlwaOVQ5f@public.gmane.org>,
	Greg Kroah-Hartman
	<gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>,
	Alison Chaiken
	<Alison_Chaiken-nmGgyN9QBj3QT0dZR+AlfA@public.gmane.org>,
	Dinh Nguyen <dinh.linux-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Jan Lubbe <jluebbe-H4yykcOXDpCzQB+pC5nmwQ@public.gmane.org>,
	Michael Stickel <ms-g5CePrrZ5ROELgA04lAiVw@public.gmane.org>,
	Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>,
	Dirk Behme <dirk.behme-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Alan Tull
	<delicious.quinoa-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Sascha Hauer <s.hauer-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>,
	Michael Bohan <mbohan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	Michal Simek <monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>,
	Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Joel Becker <jlbec-aKy9MeLSZ9dg9hUCZPvPmw@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Wolfram Sang <wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org>,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Pete Popov <pete.popov-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>,
	Dan Malek <dan.male
Subject: Re: [PATCH 5/6] OF: Utility helper functions for dynamic nodes
Date: Mon, 23 Jun 2014 18:26:49 +0200	[thread overview]
Message-ID: <53A85549.7040809@nsn.com> (raw)
In-Reply-To: <1403430039-15085-6-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

Hello Pantelis!

On 22/06/14 11:40, ext Pantelis Antoniou wrote:
> Introduce helper functions for working with the live DT tree,
> all of them related to dynamically adding/removing nodes and
> properties.
> 
> __of_copy_property() copies a property dynamically
> __of_create_empty_node() creates an empty node
> 
> Bug fix about prop->len == 0 by Ionut Nicu <ioan.nicu.ext-OYasijW0DpE@public.gmane.org>

Are you sure about this? (see below...)
 
> Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/of/Makefile |   2 +-
>  drivers/of/util.c   | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/of.h  |  42 ++++++++++++++++
>  3 files changed, 184 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/of/util.c
> 
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 099b1fb..734d3e2 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -1,4 +1,4 @@
> -obj-y = base.o device.o platform.o
> +obj-y = base.o device.o platform.o util.o
>  obj-$(CONFIG_OF_FLATTREE) += fdt.o
>  obj-$(CONFIG_OF_EARLY_FLATTREE) += fdt_address.o
>  obj-$(CONFIG_OF_PROMTREE) += pdt.o
> diff --git a/drivers/of/util.c b/drivers/of/util.c
> new file mode 100644
> index 0000000..f4211f8
> --- /dev/null
> +++ b/drivers/of/util.c
> @@ -0,0 +1,141 @@
> +/*
> + * Utility functions for working with device tree(s)
> + *
> + * Copyright (C) 2012 Pantelis Antoniou <panto-wVdstyuyKrO8r51toPun2/C9HSW9iNxf@public.gmane.org>
> + * Copyright (C) 2012 Texas Instruments Inc.
> + *
> + * 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/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/string.h>
> +#include <linux/ctype.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +
> +/**
> + * __of_copy_property - Copy a property dynamically.
> + * @prop:	Property to copy
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @propflags:	Property flags
> + *
> + * Copy a property by dynamically allocating the memory of both the
> + * property stucture and the property name & contents. The property's
> + * flags have the OF_DYNAMIC bit set so that we can differentiate between
> + * dynamically allocated properties and not.
> + * Returns the newly allocated property or NULL on out of memory error.
> + */
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	struct property *propn;
> +
> +	propn = kzalloc(sizeof(*prop), allocflags);
> +	if (propn == NULL)
> +		return NULL;
> +
> +	propn->_flags = propflags;
> +
> +	if (of_property_check_flag(propn, OF_ALLOCNAME)) {
> +		propn->name = kstrdup(prop->name, allocflags);
> +		if (propn->name == NULL)
> +			goto err_fail_name;
> +	} else
> +		propn->name = prop->name;
> +
> +	if (prop->length > 0) {
        ^^^^^^^^^^^^^^^^^^^^^
Seems, that length==0 case will still produce value==NULL results,
which will brake some checks in the kernel... Or am I missing something in
the new version?


> +		if (of_property_check_flag(propn, OF_ALLOCVALUE)) {
> +			propn->value = kmalloc(prop->length, allocflags);
> +			if (propn->value == NULL)
> +				goto err_fail_value;
> +			memcpy(propn->value, prop->value, prop->length);
> +		} else
> +			propn->value = prop->value;
> +
> +		propn->length = prop->length;
> +	}
> +
> +	/* mark the property as dynamic */
> +	of_property_set_flag(propn, OF_DYNAMIC);
> +
> +	return propn;
> +
> +err_fail_value:
> +	if (of_property_check_flag(propn, OF_ALLOCNAME))
> +		kfree(propn->name);
> +err_fail_name:
> +	kfree(propn);
> +	return NULL;
> +}
> +
> +/**
> + * __of_create_empty_node - Create an empty device node dynamically.
> + * @name:	Name of the new device node
> + * @type:	Type of the new device node
> + * @full_name:	Full name of the new device node
> + * @phandle:	Phandle of the new device node
> + * @allocflags:	Allocation flags (typically pass GFP_KERNEL)
> + * @nodeflags:	Node flags
> + *
> + * Create an empty device tree node, suitable for further modification.
> + * The node data are dynamically allocated and all the node flags
> + * have the OF_DYNAMIC & OF_DETACHED bits set.
> + * Returns the newly allocated node or NULL on out of memory error.
> + */
> +struct device_node *__of_create_empty_node(
> +		const char *name, const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	struct device_node *node;
> +
> +	node = kzalloc(sizeof(*node), allocflags);
> +	if (node == NULL)
> +		return NULL;
> +
> +	node->_flags = nodeflags;
> +
> +	if (of_node_check_flag(node, OF_ALLOCNAME)) {
> +		node->name = kstrdup(name, allocflags);
> +		if (node->name == NULL)
> +			goto err_free_node;
> +	} else
> +		node->name = name;
> +
> +	if (of_node_check_flag(node, OF_ALLOCTYPE)) {
> +		node->type = kstrdup(type, allocflags);
> +		if (node->type == NULL)
> +			goto err_free_name;
> +	} else
> +		node->type = type;
> +
> +	if (of_node_check_flag(node, OF_ALLOCFULL)) {
> +		node->full_name = kstrdup(full_name, allocflags);
> +		if (node->full_name == NULL)
> +			goto err_free_type;
> +	} else
> +		node->full_name = full_name;
> +
> +	node->phandle = phandle;
> +	of_node_set_flag(node, OF_DYNAMIC);
> +	of_node_set_flag(node, OF_DETACHED);
> +
> +	of_node_init(node);
> +
> +	return node;
> +err_free_type:
> +	if (of_node_check_flag(node, OF_ALLOCTYPE))
> +		kfree(node->type);
> +err_free_name:
> +	if (of_node_check_flag(node, OF_ALLOCNAME))
> +		kfree(node->name);
> +err_free_node:
> +	kfree(node);
> +	return NULL;
> +}
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 5e4e1b3..d381eb5 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -211,6 +211,15 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size)
>  #define OF_DYNAMIC	1 /* node and properties were allocated via kmalloc */
>  #define OF_DETACHED	2 /* node has been detached from the device tree */
>  #define OF_POPULATED	3 /* device already created for the node */
> +#define OF_ALLOCNAME	4 /* name was kmalloc-ed */
> +#define OF_ALLOCTYPE	5 /* type was kmalloc-ed */
> +#define OF_ALLOCFULL	6 /* full_name was kmalloc-ed */
> +#define OF_ALLOCVALUE	7 /* value was kmalloc-ed */
> +
> +#define OF_NODE_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCTYPE) | (1 << OF_ALLOCFULL))
> +#define OF_PROP_ALLOCALL \
> +	((1 << OF_ALLOCNAME) | (1 << OF_ALLOCVALUE))
>  
>  #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags)
>  #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags)
> @@ -824,4 +833,37 @@ typedef void (*of_init_fn_1)(struct device_node *);
>  #define OF_DECLARE_2(table, name, compat, fn) \
>  		_OF_DECLARE(table, name, compat, fn, of_init_fn_2)
>  
> +/**
> + * General utilities for working with live trees.
> + *
> + * All functions with two leading underscores operate
> + * without taking node references, so you either have to
> + * own the devtree lock or work on detached trees only.
> + */
> +
> +#ifdef CONFIG_OF
> +
> +struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags);
> +struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags);
> +
> +#else /* !CONFIG_OF */
> +
> +static inline struct property *__of_copy_property(const struct property *prop,
> +		gfp_t allocflags, unsigned long propflags)
> +{
> +	return NULL;
> +}
> +
> +static inline struct device_node *__of_create_empty_node(const char *name,
> +		const char *type, const char *full_name,
> +		phandle phandle, gfp_t allocflags, unsigned long nodeflags)
> +{
> +	return NULL;
> +}
> +
> +#endif	/* !CONFIG_OF */
> +
>  #endif /* _LINUX_OF_H */
> 

-- 
Best regards,
Alexander Sverdlin.
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2014-06-23 16:53 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-22  9:40 [PATCH 0/6] OF: Fixes preparing transactions/overlays Pantelis Antoniou
2014-06-22  9:40 ` [PATCH 1/6] of: Do not free memory at of_node_release Pantelis Antoniou
2014-06-24 14:10   ` Grant Likely
2014-06-24 14:23     ` Pantelis Antoniou
2014-06-24 20:21       ` Grant Likely
2014-06-24 20:23         ` Pantelis Antoniou
2014-06-24 20:33           ` Guenter Roeck
2014-06-24 21:02             ` Pantelis Antoniou
2014-06-24 23:20               ` Guenter Roeck
2014-06-25 19:24           ` Grant Likely
2014-06-24 14:53     ` Guenter Roeck
2014-06-22  9:40 ` [PATCH 2/6] OF: Add [__]of_find_node_by_full_name Pantelis Antoniou
2014-06-23 17:58   ` Guenter Roeck
2014-06-23 18:00     ` Pantelis Antoniou
2014-06-24 13:55       ` Grant Likely
2014-06-24 13:55         ` Grant Likely
2014-06-24 13:55         ` Grant Likely
2014-06-24 14:12   ` Grant Likely
2014-06-24 14:23     ` Pantelis Antoniou
2014-06-22  9:40 ` [PATCH 3/6] of: platform: Fix and export of_platform_device_destroy Pantelis Antoniou
2014-06-24 14:23   ` Grant Likely
2014-06-24 15:13   ` Grant Likely
2014-06-22  9:40 ` [PATCH 4/6] OF: Export a number of __of_* methods Pantelis Antoniou
2014-06-24 19:27   ` Grant Likely
2014-06-24 19:38     ` Pantelis Antoniou
2014-06-24 20:19       ` Grant Likely
2014-06-22  9:40 ` [PATCH 5/6] OF: Utility helper functions for dynamic nodes Pantelis Antoniou
2014-06-23 16:26   ` Alexander Sverdlin [this message]
2014-06-23 16:26     ` Alexander Sverdlin
2014-06-23 16:26     ` Alexander Sverdlin
2014-06-23 16:57     ` Pantelis Antoniou
2014-06-23 18:33       ` Ioan Nicu
2014-06-23 19:13         ` Pantelis Antoniou
2014-06-23 19:48           ` Guenter Roeck
2014-06-23 19:48             ` Guenter Roeck
2014-06-23 19:48             ` Guenter Roeck
2014-06-23 20:39             ` Ioan Nicu
2014-06-24  9:08             ` Pantelis Antoniou
2014-06-24 13:46               ` Rob Herring
2014-06-24 13:53                 ` Alexander Sverdlin
2014-06-24 14:49                   ` Rob Herring
2014-06-24 15:43                     ` Alexander Sverdlin
2014-06-24 15:59                       ` Pantelis Antoniou
2014-06-24 18:23                         ` Ioan Nicu
2014-06-24 18:31                           ` Ioan Nicu
2014-06-24 18:43                           ` Pantelis Antoniou
2014-06-24  8:12           ` Alexander Sverdlin
2014-06-24  8:12             ` Alexander Sverdlin
2014-06-24  8:12             ` Alexander Sverdlin
2014-06-24  8:19             ` Pantelis Antoniou
2014-06-24  8:38               ` Alexander Sverdlin
2014-06-24  8:54                 ` Pantelis Antoniou
2014-06-24  9:00                   ` Alexander Sverdlin
2014-06-24  9:09                     ` Pantelis Antoniou
2014-06-24  8:10         ` Alexander Sverdlin
2014-06-24  8:10           ` Alexander Sverdlin
2014-06-24  8:10           ` Alexander Sverdlin
2014-06-25  9:09           ` Grant Likely
2014-06-25  9:09             ` Grant Likely
2014-06-25  9:09             ` Grant Likely
2014-06-25 11:14   ` Grant Likely
2014-06-25 11:22     ` Pantelis Antoniou
2014-06-22  9:40 ` [PATCH 6/6] of: Introduce tree change __foo_post methods Pantelis Antoniou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53A85549.7040809@nsn.com \
    --to=alexander.sverdlin@nsn.com \
    --cc=Alison_Chaiken@mentor.com \
    --cc=broonie@kernel.org \
    --cc=dan.malek@konsulko.com \
    --cc=delicious.quinoa@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dinh.linux@gmail.com \
    --cc=dirk.behme@gmail.com \
    --cc=georgi.vlaev@konsulko.com \
    --cc=grant.likely@secretlab.ca \
    --cc=gregkh@linuxfoundation.org \
    --cc=ioan.nicu.ext@nsn.com \
    --cc=jlbec@evilplan.org \
    --cc=jluebbe@lasnet.de \
    --cc=koen@dominion.thruhere.net \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=matt.porter@linaro.org \
    --cc=mbohan@codeaurora.org \
    --cc=monstr@monstr.eu \
    --cc=mranostay@gmail.com \
    --cc=ms@mycable.de \
    --cc=pantelis.antoniou@konsulko.com \
    --cc=panto@antoniou-consulting.com \
    --cc=pete.popov@konsulko.com \
    --cc=robherring2@gmail.com \
    --cc=s.hauer@pengutronix.de \
    --cc=swarren@wwwdotorg.org \
    --cc=wsa@the-dreams.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.