[PATCH 1/8] pinctrl: Add new function pinctrl_generic_set_state_prefix()
Stefan Roese
sr at denx.de
Thu Jul 28 08:25:37 CEST 2022
On 25.07.22 13:56, Pali Rohár wrote:
> This new function pinctrl_generic_set_state_prefix() behaves like
> pinctrl_generic_set_state() but it takes third string argument which is
> used as the prefix for each device tree string property.
>
> This is needed for Marvell pinctrl drivers, becase Linux device tree files
> have pinmux properties prefixed by "marvell," string.
>
> This change allows to use generic U-Boot pinctrl functions for Armada 38x
> pinctrl driver without need to copy+paste of the majority U-Boot pinctrl
> code.
>
> Signed-off-by: Pali Rohár <pali at kernel.org>
Reviewed-by: Stefan Roese <sr at denx.de>
Thanks,
Stefan
> ---
> drivers/pinctrl/pinctrl-generic.c | 100 +++++++++++++++++++++++++-----
> include/dm/pinctrl.h | 2 +
> 2 files changed, 85 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
> index 3c8e24088ce4..ec21d4ff8387 100644
> --- a/drivers/pinctrl/pinctrl-generic.c
> +++ b/drivers/pinctrl/pinctrl-generic.c
> @@ -234,6 +234,24 @@ enum pinmux_subnode_type {
> PST_PINMUX,
> };
>
> +static const char *alloc_name_with_prefix(const char *name, const char *prefix)
> +{
> + if (prefix) {
> + char *name_with_prefix = malloc(strlen(prefix) + sizeof("pins"));
> + if (name_with_prefix)
> + sprintf(name_with_prefix, "%s%s", prefix, name);
> + return name_with_prefix;
> + } else {
> + return name;
> + }
> +}
> +
> +static void free_name_with_prefix(const char *name_with_prefix, const char *prefix)
> +{
> + if (prefix)
> + free((char *)name_with_prefix);
> +}
> +
> /**
> * pinctrl_generic_set_state_one() - set state for a certain pin/group
> * Apply all pin multiplexing and pin configurations specified by @config
> @@ -248,9 +266,11 @@ enum pinmux_subnode_type {
> */
> static int pinctrl_generic_set_state_one(struct udevice *dev,
> struct udevice *config,
> + const char *prefix,
> enum pinmux_subnode_type subnode_type,
> unsigned selector)
> {
> + const char *function_propname;
> const char *propname;
> const void *value;
> struct ofprop property;
> @@ -259,18 +279,26 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
>
> assert(subnode_type != PST_NONE);
>
> + function_propname = alloc_name_with_prefix("function", prefix);
> + if (!function_propname)
> + return -ENOMEM;
> +
> dev_for_each_property(property, config) {
> value = dev_read_prop_by_prop(&property, &propname, &len);
> - if (!value)
> + if (!value) {
> + free_name_with_prefix(function_propname, prefix);
> return -EINVAL;
> + }
>
> /* pinmux subnodes already have their muxing set */
> if (subnode_type != PST_PINMUX &&
> - !strcmp(propname, "function")) {
> + !strcmp(propname, function_propname)) {
> func_selector = pinmux_func_name_to_selector(dev,
> value);
> - if (func_selector < 0)
> + if (func_selector < 0) {
> + free_name_with_prefix(function_propname, prefix);
> return func_selector;
> + }
> ret = pinmux_enable_setting(dev,
> subnode_type == PST_GROUP,
> selector,
> @@ -291,10 +319,13 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
> selector, param, arg);
> }
>
> - if (ret)
> + if (ret) {
> + free_name_with_prefix(function_propname, prefix);
> return ret;
> + }
> }
>
> + free_name_with_prefix(function_propname, prefix);
> return 0;
> }
>
> @@ -309,20 +340,34 @@ static int pinctrl_generic_set_state_one(struct udevice *dev,
> */
> static enum pinmux_subnode_type pinctrl_generic_get_subnode_type(struct udevice *dev,
> struct udevice *config,
> + const char *prefix,
> int *count)
> {
> const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
> + const char *propname;
>
> - *count = dev_read_string_count(config, "pins");
> + propname = alloc_name_with_prefix("pins", prefix);
> + if (!propname)
> + return -ENOMEM;
> + *count = dev_read_string_count(config, propname);
> + free_name_with_prefix(propname, prefix);
> if (*count >= 0)
> return PST_PIN;
>
> - *count = dev_read_string_count(config, "groups");
> + propname = alloc_name_with_prefix("groups", prefix);
> + if (!propname)
> + return -ENOMEM;
> + *count = dev_read_string_count(config, propname);
> + free_name_with_prefix(propname, prefix);
> if (*count >= 0)
> return PST_GROUP;
>
> if (ops->pinmux_property_set) {
> - *count = dev_read_size(config, "pinmux");
> + propname = alloc_name_with_prefix("pinmux", prefix);
> + if (!propname)
> + return -ENOMEM;
> + *count = dev_read_size(config, propname);
> + free_name_with_prefix(propname, prefix);
> if (*count >= 0 && !(*count % sizeof(u32))) {
> *count /= sizeof(u32);
> return PST_PINMUX;
> @@ -338,23 +383,30 @@ static enum pinmux_subnode_type pinctrl_generic_get_subnode_type(struct udevice
> *
> * @dev: pin controller device
> * @config: pseudo device pointing to config node
> + * @prefix: device tree property prefix (e.g. vendor specific)
> * @return: 0 on success, or negative error code on failure
> */
> static int pinctrl_generic_set_state_subnode(struct udevice *dev,
> - struct udevice *config)
> + struct udevice *config,
> + const char *prefix)
> {
> enum pinmux_subnode_type subnode_type;
> + const char *propname;
> const char *name;
> int count, selector, i, ret, scratch;
> const u32 *pinmux_groups = NULL; /* prevent use-uninitialized warning */
>
> - subnode_type = pinctrl_generic_get_subnode_type(dev, config, &count);
> + subnode_type = pinctrl_generic_get_subnode_type(dev, config, prefix, &count);
>
> debug("%s(%s, %s): count=%d\n", __func__, dev->name, config->name,
> count);
>
> if (subnode_type == PST_PINMUX) {
> - pinmux_groups = dev_read_prop(config, "pinmux", &scratch);
> + propname = alloc_name_with_prefix("pinmux", prefix);
> + if (!propname)
> + return -ENOMEM;
> + pinmux_groups = dev_read_prop(config, propname, &scratch);
> + free_name_with_prefix(propname, prefix);
> if (!pinmux_groups)
> return -EINVAL;
> }
> @@ -362,13 +414,21 @@ static int pinctrl_generic_set_state_subnode(struct udevice *dev,
> for (i = 0; i < count; i++) {
> switch (subnode_type) {
> case PST_PIN:
> - ret = dev_read_string_index(config, "pins", i, &name);
> + propname = alloc_name_with_prefix("pins", prefix);
> + if (!propname)
> + return -ENOMEM;
> + ret = dev_read_string_index(config, propname, i, &name);
> + free_name_with_prefix(propname, prefix);
> if (ret)
> return ret;
> selector = pinctrl_pin_name_to_selector(dev, name);
> break;
> case PST_GROUP:
> - ret = dev_read_string_index(config, "groups", i, &name);
> + propname = alloc_name_with_prefix("groups", prefix);
> + if (!propname)
> + return -ENOMEM;
> + ret = dev_read_string_index(config, propname, i, &name);
> + free_name_with_prefix(propname, prefix);
> if (ret)
> return ret;
> selector = pinctrl_group_name_to_selector(dev, name);
> @@ -390,8 +450,8 @@ static int pinctrl_generic_set_state_subnode(struct udevice *dev,
> if (selector < 0)
> return selector;
>
> - ret = pinctrl_generic_set_state_one(dev, config, subnode_type,
> - selector);
> + ret = pinctrl_generic_set_state_one(dev, config, prefix,
> + subnode_type, selector);
> if (ret)
> return ret;
> }
> @@ -399,22 +459,28 @@ static int pinctrl_generic_set_state_subnode(struct udevice *dev,
> return 0;
> }
>
> -int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
> +int pinctrl_generic_set_state_prefix(struct udevice *dev, struct udevice *config,
> + const char *prefix)
> {
> struct udevice *child;
> int ret;
>
> - ret = pinctrl_generic_set_state_subnode(dev, config);
> + ret = pinctrl_generic_set_state_subnode(dev, config, prefix);
> if (ret)
> return ret;
>
> for (device_find_first_child(config, &child);
> child;
> device_find_next_child(&child)) {
> - ret = pinctrl_generic_set_state_subnode(dev, child);
> + ret = pinctrl_generic_set_state_subnode(dev, child, prefix);
> if (ret)
> return ret;
> }
>
> return 0;
> }
> +
> +int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
> +{
> + return pinctrl_generic_set_state_prefix(dev, config, NULL);
> +}
> diff --git a/include/dm/pinctrl.h b/include/dm/pinctrl.h
> index a09b242fd990..5436dc4a9a71 100644
> --- a/include/dm/pinctrl.h
> +++ b/include/dm/pinctrl.h
> @@ -491,6 +491,8 @@ enum pin_config_param {
> * Return: 0 on success, or negative error code on failure
> */
> int pinctrl_generic_set_state(struct udevice *pctldev, struct udevice *config);
> +int pinctrl_generic_set_state_prefix(struct udevice *pctldev, struct udevice *config,
> + const char *prefix);
> #else
> static inline int pinctrl_generic_set_state(struct udevice *pctldev,
> struct udevice *config)
Viele Grüße,
Stefan Roese
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de
More information about the U-Boot
mailing list