Commit 16ccaf5b authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Linus Walleij

pinctrl: sh-pfc: Accept standard function, pins and groups properties

The "function", "pins" and "groups" pinmux and pinctrl properties have
been standardized. Support them in addition to the custom "renesas,*"
properties. New-style and old-style properties can't be mixed in DT.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 583facb6
...@@ -58,12 +58,12 @@ are parsed through phandles and processed purely based on their content. ...@@ -58,12 +58,12 @@ are parsed through phandles and processed purely based on their content.
Pin Configuration Node Properties: Pin Configuration Node Properties:
- renesas,pins : An array of strings, each string containing the name of a pin. - pins : An array of strings, each string containing the name of a pin.
- renesas,groups : An array of strings, each string containing the name of a pin - groups : An array of strings, each string containing the name of a pin
group. group.
- renesas,function: A string containing the name of the function to mux to the - function: A string containing the name of the function to mux to the pin
pin group(s) specified by the renesas,groups property group(s) specified by the groups property.
Valid values for pin, group and function names can be found in the group and Valid values for pin, group and function names can be found in the group and
function arrays of the PFC data file corresponding to the SoC function arrays of the PFC data file corresponding to the SoC
...@@ -141,19 +141,19 @@ Example 3: KZM-A9-GT (SH-Mobile AG5) default pin state hog and pin control maps ...@@ -141,19 +141,19 @@ Example 3: KZM-A9-GT (SH-Mobile AG5) default pin state hog and pin control maps
mmcif_pins: mmcif { mmcif_pins: mmcif {
mux { mux {
renesas,groups = "mmc0_data8_0", "mmc0_ctrl_0"; groups = "mmc0_data8_0", "mmc0_ctrl_0";
renesas,function = "mmc0"; function = "mmc0";
}; };
cfg { cfg {
renesas,groups = "mmc0_data8_0"; groups = "mmc0_data8_0";
renesas,pins = "PORT279"; pins = "PORT279";
bias-pull-up; bias-pull-up;
}; };
}; };
scifa4_pins: scifa4 { scifa4_pins: scifa4 {
renesas,groups = "scifa4_data", "scifa4_ctrl"; groups = "scifa4_data", "scifa4_ctrl";
renesas,function = "scifa4"; function = "scifa4";
}; };
}; };
......
...@@ -40,6 +40,10 @@ struct sh_pfc_pinctrl { ...@@ -40,6 +40,10 @@ struct sh_pfc_pinctrl {
struct pinctrl_pin_desc *pins; struct pinctrl_pin_desc *pins;
struct sh_pfc_pin_config *configs; struct sh_pfc_pin_config *configs;
const char *func_prop_name;
const char *groups_prop_name;
const char *pins_prop_name;
}; };
static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)
...@@ -96,10 +100,13 @@ static int sh_pfc_map_add_config(struct pinctrl_map *map, ...@@ -96,10 +100,13 @@ static int sh_pfc_map_add_config(struct pinctrl_map *map,
return 0; return 0;
} }
static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, static int sh_pfc_dt_subnode_to_map(struct pinctrl_dev *pctldev,
struct device_node *np,
struct pinctrl_map **map, struct pinctrl_map **map,
unsigned int *num_maps, unsigned int *index) unsigned int *num_maps, unsigned int *index)
{ {
struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
struct device *dev = pmx->pfc->dev;
struct pinctrl_map *maps = *map; struct pinctrl_map *maps = *map;
unsigned int nmaps = *num_maps; unsigned int nmaps = *num_maps;
unsigned int idx = *index; unsigned int idx = *index;
...@@ -113,10 +120,27 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, ...@@ -113,10 +120,27 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
const char *pin; const char *pin;
int ret; int ret;
/* Support both the old Renesas-specific properties and the new standard
* properties. Mixing old and new properties isn't allowed, neither
* inside a subnode nor across subnodes.
*/
if (!pmx->func_prop_name) {
if (of_find_property(np, "groups", NULL) ||
of_find_property(np, "pins", NULL)) {
pmx->func_prop_name = "function";
pmx->groups_prop_name = "groups";
pmx->pins_prop_name = "pins";
} else {
pmx->func_prop_name = "renesas,function";
pmx->groups_prop_name = "renesas,groups";
pmx->pins_prop_name = "renesas,pins";
}
}
/* Parse the function and configuration properties. At least a function /* Parse the function and configuration properties. At least a function
* or one configuration must be specified. * or one configuration must be specified.
*/ */
ret = of_property_read_string(np, "renesas,function", &function); ret = of_property_read_string(np, pmx->func_prop_name, &function);
if (ret < 0 && ret != -EINVAL) { if (ret < 0 && ret != -EINVAL) {
dev_err(dev, "Invalid function in DT\n"); dev_err(dev, "Invalid function in DT\n");
return ret; return ret;
...@@ -129,11 +153,12 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, ...@@ -129,11 +153,12 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
if (!function && num_configs == 0) { if (!function && num_configs == 0) {
dev_err(dev, dev_err(dev,
"DT node must contain at least a function or config\n"); "DT node must contain at least a function or config\n");
ret = -ENODEV;
goto done; goto done;
} }
/* Count the number of pins and groups and reallocate mappings. */ /* Count the number of pins and groups and reallocate mappings. */
ret = of_property_count_strings(np, "renesas,pins"); ret = of_property_count_strings(np, pmx->pins_prop_name);
if (ret == -EINVAL) { if (ret == -EINVAL) {
num_pins = 0; num_pins = 0;
} else if (ret < 0) { } else if (ret < 0) {
...@@ -143,7 +168,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, ...@@ -143,7 +168,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
num_pins = ret; num_pins = ret;
} }
ret = of_property_count_strings(np, "renesas,groups"); ret = of_property_count_strings(np, pmx->groups_prop_name);
if (ret == -EINVAL) { if (ret == -EINVAL) {
num_groups = 0; num_groups = 0;
} else if (ret < 0) { } else if (ret < 0) {
...@@ -174,7 +199,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, ...@@ -174,7 +199,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
*num_maps = nmaps; *num_maps = nmaps;
/* Iterate over pins and groups and create the mappings. */ /* Iterate over pins and groups and create the mappings. */
of_property_for_each_string(np, "renesas,groups", prop, group) { of_property_for_each_string(np, pmx->groups_prop_name, prop, group) {
if (function) { if (function) {
maps[idx].type = PIN_MAP_TYPE_MUX_GROUP; maps[idx].type = PIN_MAP_TYPE_MUX_GROUP;
maps[idx].data.mux.group = group; maps[idx].data.mux.group = group;
...@@ -198,7 +223,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np, ...@@ -198,7 +223,7 @@ static int sh_pfc_dt_subnode_to_map(struct device *dev, struct device_node *np,
goto done; goto done;
} }
of_property_for_each_string(np, "renesas,pins", prop, pin) { of_property_for_each_string(np, pmx->pins_prop_name, prop, pin) {
ret = sh_pfc_map_add_config(&maps[idx], pin, ret = sh_pfc_map_add_config(&maps[idx], pin,
PIN_MAP_TYPE_CONFIGS_PIN, PIN_MAP_TYPE_CONFIGS_PIN,
configs, num_configs); configs, num_configs);
...@@ -246,7 +271,7 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -246,7 +271,7 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,
index = 0; index = 0;
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
ret = sh_pfc_dt_subnode_to_map(dev, child, map, num_maps, ret = sh_pfc_dt_subnode_to_map(pctldev, child, map, num_maps,
&index); &index);
if (ret < 0) if (ret < 0)
goto done; goto done;
...@@ -254,7 +279,8 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev, ...@@ -254,7 +279,8 @@ static int sh_pfc_dt_node_to_map(struct pinctrl_dev *pctldev,
/* If no mapping has been found in child nodes try the config node. */ /* If no mapping has been found in child nodes try the config node. */
if (*num_maps == 0) { if (*num_maps == 0) {
ret = sh_pfc_dt_subnode_to_map(dev, np, map, num_maps, &index); ret = sh_pfc_dt_subnode_to_map(pctldev, np, map, num_maps,
&index);
if (ret < 0) if (ret < 0)
goto done; goto done;
} }
......
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