Commit 3a6b04ca authored by John Crispin's avatar John Crispin Committed by Linus Walleij

pinctrl/lantiq: add pin_config_group_set support

While converting all the boards supported by OpenWrt to OF
I noticed that this feature is missing. Adding it makes the
devicetrees more readable.
Signed-off-by: default avatarJohn Crispin <blogic@openwrt.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 7541083f
...@@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, ...@@ -64,11 +64,13 @@ static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
seq_printf(s, " %s", dev_name(pctldev->dev)); seq_printf(s, " %s", dev_name(pctldev->dev));
} }
static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, static void ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np, struct device_node *np,
struct pinctrl_map **map) struct pinctrl_map **map)
{ {
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
struct property *pins = of_find_property(np, "lantiq,pins", NULL);
struct property *groups = of_find_property(np, "lantiq,groups", NULL);
unsigned long configs[3]; unsigned long configs[3];
unsigned num_configs = 0; unsigned num_configs = 0;
struct property *prop; struct property *prop;
...@@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -76,8 +78,20 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
const char *function; const char *function;
int ret, i; int ret, i;
if (!pins && !groups) {
dev_err(pctldev->dev, "%s defines neither pins nor groups\n",
np->name);
return;
}
if (pins && groups) {
dev_err(pctldev->dev, "%s defines both pins and groups\n",
np->name);
return;
}
ret = of_property_read_string(np, "lantiq,function", &function); ret = of_property_read_string(np, "lantiq,function", &function);
if (!ret) { if (groups && !ret) {
of_property_for_each_string(np, "lantiq,groups", prop, group) { of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->type = PIN_MAP_TYPE_MUX_GROUP; (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
(*map)->name = function; (*map)->name = function;
...@@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -85,11 +99,6 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.mux.function = function; (*map)->data.mux.function = function;
(*map)++; (*map)++;
} }
if (of_find_property(np, "lantiq,pins", NULL))
dev_err(pctldev->dev,
"%s mixes pins and groups settings\n",
np->name);
return 0;
} }
for (i = 0; i < info->num_params; i++) { for (i = 0; i < info->num_params; i++) {
...@@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -103,7 +112,7 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
} }
if (!num_configs) if (!num_configs)
return -EINVAL; return;
of_property_for_each_string(np, "lantiq,pins", prop, pin) { of_property_for_each_string(np, "lantiq,pins", prop, pin) {
(*map)->data.configs.configs = kmemdup(configs, (*map)->data.configs.configs = kmemdup(configs,
...@@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev, ...@@ -115,7 +124,16 @@ static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
(*map)->data.configs.num_configs = num_configs; (*map)->data.configs.num_configs = num_configs;
(*map)++; (*map)++;
} }
return 0; of_property_for_each_string(np, "lantiq,groups", prop, group) {
(*map)->data.configs.configs = kmemdup(configs,
num_configs * sizeof(unsigned long),
GFP_KERNEL);
(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
(*map)->name = group;
(*map)->data.configs.group_or_pin = group;
(*map)->data.configs.num_configs = num_configs;
(*map)++;
}
} }
static int ltq_pinctrl_dt_subnode_size(struct device_node *np) static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
...@@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -135,23 +153,19 @@ static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
{ {
struct pinctrl_map *tmp; struct pinctrl_map *tmp;
struct device_node *np; struct device_node *np;
int ret; int max_maps = 0;
*num_maps = 0;
for_each_child_of_node(np_config, np) for_each_child_of_node(np_config, np)
*num_maps += ltq_pinctrl_dt_subnode_size(np); max_maps += ltq_pinctrl_dt_subnode_size(np);
*map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL); *map = kzalloc(max_maps * sizeof(struct pinctrl_map) * 2, GFP_KERNEL);
if (!*map) if (!*map)
return -ENOMEM; return -ENOMEM;
tmp = *map; tmp = *map;
for_each_child_of_node(np_config, np) { for_each_child_of_node(np_config, np)
ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp); ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
if (ret < 0) { *num_maps = ((int)(tmp - *map));
ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
return ret;
}
}
return 0; return 0;
} }
......
...@@ -522,9 +522,24 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -522,9 +522,24 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
return 0; return 0;
} }
int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned selector,
unsigned long config)
{
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
int i, ret = 0;
for (i = 0; i < info->grps[selector].npins && !ret; i++)
ret = xway_pinconf_set(pctldev,
info->grps[selector].pins[i], config);
return ret;
}
static struct pinconf_ops xway_pinconf_ops = { static struct pinconf_ops xway_pinconf_ops = {
.pin_config_get = xway_pinconf_get, .pin_config_get = xway_pinconf_get,
.pin_config_set = xway_pinconf_set, .pin_config_set = xway_pinconf_set,
.pin_config_group_set = xway_pinconf_group_set,
}; };
static struct pinctrl_desc xway_pctrl_desc = { static struct pinctrl_desc xway_pctrl_desc = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment