Re: [PATCH v4 04/16] of: changesets: Introduce changeset helper methods
On Tue, Feb 20, 2018 at 5:10 PM, Laurent Pinchart wrote: > From: Pantelis Antoniou > > Changesets are very powerful, but the lack of a helper API > makes using them cumbersome. Introduce a simple copy based > API that makes things considerably easier. > > To wit, adding a property using the raw API. > > struct property *prop; > prop = kzalloc(sizeof(*prop)), GFP_KERNEL); > prop->name = kstrdup("compatible"); > prop->value = kstrdup("foo,bar"); > prop->length = strlen(prop->value) + 1; > of_changeset_add_property(ocs, np, prop); > > while using the helper API > > of_changeset_add_property_string(ocs, np, "compatible", > "foo,bar"); > > Signed-off-by: Pantelis Antoniou > [Fixed memory leak in __of_changeset_add_update_property_copy()] > Signed-off-by: Laurent Pinchart > --- > drivers/of/dynamic.c | 222 ++ > include/linux/of.h | 328 > +++ > 2 files changed, 550 insertions(+) Other than what Geert pointed out, Reviewed-by: Rob Herring ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 04/16] of: changesets: Introduce changeset helper methods
Hi Rob, On Wed, Feb 21, 2018 at 4:23 PM, Rob Herring wrote: > On Wed, Feb 21, 2018 at 4:21 AM, Geert Uytterhoeven > wrote: >> You missed one fix I have in my topic/overlays branch >> https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/commit/?h=topic/overlays&id=150f95b9dec77ce371c229f7ac4d6dd8620bef4a > > Are you planning to try to upstream all this? If not, I'll get Frank Not really. But I do need a way to load DT overlays at runtime, for testing hardware on expansion connectors. > to keep changing the overlay API to make carrying it out of tree more > painful. :) He already did a very good job w.r.t. that in v4.15-rc1 ;^) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 04/16] of: changesets: Introduce changeset helper methods
On Wed, Feb 21, 2018 at 4:21 AM, Geert Uytterhoeven wrote: > Hi Laurent, > > On Wed, Feb 21, 2018 at 12:10 AM, Laurent Pinchart > wrote: >> From: Pantelis Antoniou >> >> Changesets are very powerful, but the lack of a helper API >> makes using them cumbersome. Introduce a simple copy based >> API that makes things considerably easier. >> >> To wit, adding a property using the raw API. >> >> struct property *prop; >> prop = kzalloc(sizeof(*prop)), GFP_KERNEL); >> prop->name = kstrdup("compatible"); >> prop->value = kstrdup("foo,bar"); >> prop->length = strlen(prop->value) + 1; >> of_changeset_add_property(ocs, np, prop); >> >> while using the helper API >> >> of_changeset_add_property_string(ocs, np, "compatible", >> "foo,bar"); >> >> Signed-off-by: Pantelis Antoniou >> [Fixed memory leak in __of_changeset_add_update_property_copy()] >> Signed-off-by: Laurent Pinchart > > You missed one fix I have in my topic/overlays branch > https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/commit/?h=topic/overlays&id=150f95b9dec77ce371c229f7ac4d6dd8620bef4a Are you planning to try to upstream all this? If not, I'll get Frank to keep changing the overlay API to make carrying it out of tree more painful. :) Rob ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 04/16] of: changesets: Introduce changeset helper methods
Hi Geert, On Wednesday, 21 February 2018 12:21:50 EET Geert Uytterhoeven wrote: > On Wed, Feb 21, 2018 at 12:10 AM, Laurent Pinchart wrote: > > From: Pantelis Antoniou > > > > Changesets are very powerful, but the lack of a helper API > > makes using them cumbersome. Introduce a simple copy based > > API that makes things considerably easier. > > > > To wit, adding a property using the raw API. > > > > struct property *prop; > > prop = kzalloc(sizeof(*prop)), GFP_KERNEL); > > prop->name = kstrdup("compatible"); > > prop->value = kstrdup("foo,bar"); > > prop->length = strlen(prop->value) + 1; > > of_changeset_add_property(ocs, np, prop); > > > > while using the helper API > > > > of_changeset_add_property_string(ocs, np, "compatible", > > > > "foo,bar"); > > > > Signed-off-by: Pantelis Antoniou > > [Fixed memory leak in __of_changeset_add_update_property_copy()] > > Signed-off-by: Laurent Pinchart > > > > You missed one fix I have in my topic/overlays branch > https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/co > mmit/?h=topic/overlays&id=150f95b9dec77ce371c229f7ac4d6dd8620bef4a > > --- a/include/linux/of.h > > +++ b/include/linux/of.h > > > > +/** > > + * of_changeset_add_property_u32 - Create a new u32 property > > + * > > + * @ocs: changeset pointer > > + * @np:device node pointer > > + * @name: name of the property > > + * @val: value in host endian format > > + * > > + * Adds a u32 property to the changeset. > > + * > > + * Returns zero on success, a negative error value otherwise. > > + */ > > +static inline int of_changeset_add_property_u32(struct of_changeset *ocs, > > + struct device_node *np, const char *name, u32 val) > > +{ > > + val = cpu_to_be32(val); > > You must use an intermediate, to avoid complaints from sparse: > > __be32 x = cpu_to_be32(val); > > > + return __of_changeset_add_update_property_copy(ocs, np, name, > > &val, > > + sizeof(val), false); > > s/val/x/ I'll fix both in the next version, thanks. > > +} > > + > > +/** > > + * of_changeset_update_property_u32 - Update u32 property > > + * > > + * @ocs: changeset pointer > > + * @np:device node pointer > > + * @name: name of the property > > + * @val: value in host endian format > > + * > > + * Updates a u32 property to the changeset. > > + * > > + * Returns zero on success, a negative error value otherwise. > > + */ > > +static inline int of_changeset_update_property_u32( > > + struct of_changeset *ocs, struct device_node *np, > > + const char *name, u32 val) > > +{ > > + val = cpu_to_be32(val); > > Oh, a new one. > > > + return __of_changeset_add_update_property_copy(ocs, np, name, > > &val, > > + sizeof(val), true); > > +} -- Regards, Laurent Pinchart ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v4 04/16] of: changesets: Introduce changeset helper methods
Hi Laurent, On Wed, Feb 21, 2018 at 12:10 AM, Laurent Pinchart wrote: > From: Pantelis Antoniou > > Changesets are very powerful, but the lack of a helper API > makes using them cumbersome. Introduce a simple copy based > API that makes things considerably easier. > > To wit, adding a property using the raw API. > > struct property *prop; > prop = kzalloc(sizeof(*prop)), GFP_KERNEL); > prop->name = kstrdup("compatible"); > prop->value = kstrdup("foo,bar"); > prop->length = strlen(prop->value) + 1; > of_changeset_add_property(ocs, np, prop); > > while using the helper API > > of_changeset_add_property_string(ocs, np, "compatible", > "foo,bar"); > > Signed-off-by: Pantelis Antoniou > [Fixed memory leak in __of_changeset_add_update_property_copy()] > Signed-off-by: Laurent Pinchart You missed one fix I have in my topic/overlays branch https://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git/commit/?h=topic/overlays&id=150f95b9dec77ce371c229f7ac4d6dd8620bef4a > --- a/include/linux/of.h > +++ b/include/linux/of.h > +/** > + * of_changeset_add_property_u32 - Create a new u32 property > + * > + * @ocs: changeset pointer > + * @np:device node pointer > + * @name: name of the property > + * @val: value in host endian format > + * > + * Adds a u32 property to the changeset. > + * > + * Returns zero on success, a negative error value otherwise. > + */ > +static inline int of_changeset_add_property_u32(struct of_changeset *ocs, > + struct device_node *np, const char *name, u32 val) > +{ > + val = cpu_to_be32(val); You must use an intermediate, to avoid complaints from sparse: __be32 x = cpu_to_be32(val); > + return __of_changeset_add_update_property_copy(ocs, np, name, &val, > + sizeof(val), false); s/val/x/ > +} > + > +/** > + * of_changeset_update_property_u32 - Update u32 property > + * > + * @ocs: changeset pointer > + * @np:device node pointer > + * @name: name of the property > + * @val: value in host endian format > + * > + * Updates a u32 property to the changeset. > + * > + * Returns zero on success, a negative error value otherwise. > + */ > +static inline int of_changeset_update_property_u32( > + struct of_changeset *ocs, struct device_node *np, > + const char *name, u32 val) > +{ > + val = cpu_to_be32(val); Oh, a new one. > + return __of_changeset_add_update_property_copy(ocs, np, name, &val, > + sizeof(val), true); > +} Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v4 04/16] of: changesets: Introduce changeset helper methods
From: Pantelis Antoniou Changesets are very powerful, but the lack of a helper API makes using them cumbersome. Introduce a simple copy based API that makes things considerably easier. To wit, adding a property using the raw API. struct property *prop; prop = kzalloc(sizeof(*prop)), GFP_KERNEL); prop->name = kstrdup("compatible"); prop->value = kstrdup("foo,bar"); prop->length = strlen(prop->value) + 1; of_changeset_add_property(ocs, np, prop); while using the helper API of_changeset_add_property_string(ocs, np, "compatible", "foo,bar"); Signed-off-by: Pantelis Antoniou [Fixed memory leak in __of_changeset_add_update_property_copy()] Signed-off-by: Laurent Pinchart --- drivers/of/dynamic.c | 222 ++ include/linux/of.h | 328 +++ 2 files changed, 550 insertions(+) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 4ffd04925fdf..85e722ed8631 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -910,3 +910,225 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, return 0; } EXPORT_SYMBOL_GPL(of_changeset_action); + +/* changeset helpers */ + +/** + * of_changeset_create_device_node - Create an empty device node + * + * @ocs: changeset pointer + * @parent:parent device node + * @fmt: format string for the node's full_name + * @args: argument list for the format string + * + * Create an empty device node, marking it as detached and allocated. + * + * Returns a device node on success, an error encoded pointer otherwise + */ +struct device_node *of_changeset_create_device_nodev( + struct of_changeset *ocs, struct device_node *parent, + const char *fmt, va_list vargs) +{ + struct device_node *node; + + node = __of_node_dupv(NULL, fmt, vargs); + if (!node) + return ERR_PTR(-ENOMEM); + + node->parent = parent; + return node; +} +EXPORT_SYMBOL_GPL(of_changeset_create_device_nodev); + +/** + * of_changeset_create_device_node - Create an empty device node + * + * @ocs: changeset pointer + * @parent:parent device node + * @fmt: Format string for the node's full_name + * ... Arguments + * + * Create an empty device node, marking it as detached and allocated. + * + * Returns a device node on success, an error encoded pointer otherwise + */ +__printf(3, 4) struct device_node * +of_changeset_create_device_node(struct of_changeset *ocs, + struct device_node *parent, const char *fmt, ...) +{ + va_list vargs; + struct device_node *node; + + va_start(vargs, fmt); + node = of_changeset_create_device_nodev(ocs, parent, fmt, vargs); + va_end(vargs); + return node; +} +EXPORT_SYMBOL_GPL(of_changeset_create_device_node); + +/** + * __of_changeset_add_property_copy - Create/update a new property copying + *name & value + * + * @ocs: changeset pointer + * @np:device node pointer + * @name: name of the property + * @value: pointer to the value data + * @length:length of the value in bytes + * @update:True on update operation + * + * Adds/updates a property to the changeset by making copies of the name & value + * entries. The @update parameter controls whether an add or update takes place. + * + * Returns zero on success, a negative error value otherwise. + */ +int __of_changeset_add_update_property_copy(struct of_changeset *ocs, + struct device_node *np, const char *name, const void *value, + int length, bool update) +{ + struct property *prop; + int ret = -ENOMEM; + + prop = kzalloc(sizeof(*prop), GFP_KERNEL); + if (!prop) + return -ENOMEM; + + prop->name = kstrdup(name, GFP_KERNEL); + if (!prop->name) + goto out_err; + + /* +* NOTE: There is no check for zero length value. +* In case of a boolean property, this will allocate a value +* of zero bytes. We do this to work around the use +* of of_get_property() calls on boolean values. +*/ + prop->value = kmemdup(value, length, GFP_KERNEL); + if (!prop->value) + goto out_err; + + of_property_set_flag(prop, OF_DYNAMIC); + + prop->length = length; + + if (!update) + ret = of_changeset_add_property(ocs, np, prop); + else + ret = of_changeset_update_property(ocs, np, prop); + + if (!ret) + return 0; + +out_err: + kfree(prop->value); + kfree(prop->name); + kfree(prop); + return ret; +} +EXPORT_SYMBOL_GPL(__of_changeset_add_update_property_copy); + +/** + * of_changeset_add_property_stringf - Create a new formatted string property + * + * @ocs: changeset pointer + * @np:devic