diff options
Diffstat (limited to 'drivers/pinctrl/freescale/pinctrl-imx.c')
| -rw-r--r-- | drivers/pinctrl/freescale/pinctrl-imx.c | 207 |
1 files changed, 59 insertions, 148 deletions
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index e9aef764138f..731c58ad43ee 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -14,7 +14,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/seq_file.h> #include <linux/slab.h> @@ -37,16 +37,16 @@ static inline const struct group_desc *imx_pinctrl_find_group_by_name( struct pinctrl_dev *pctldev, const char *name) { - const struct group_desc *grp = NULL; + const struct group_desc *grp; int i; for (i = 0; i < pctldev->num_groups; i++) { grp = pinctrl_generic_get_group(pctldev, i); - if (grp && !strcmp(grp->name, name)) - break; + if (grp && !strcmp(grp->grp.name, name)) + return grp; } - return grp; + return NULL; } static void imx_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, @@ -79,9 +79,9 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, } if (info->flags & IMX_USE_SCU) { - map_num += grp->num_pins; + map_num += grp->grp.npins; } else { - for (i = 0; i < grp->num_pins; i++) { + for (i = 0; i < grp->grp.npins; i++) { pin = &((struct imx_pin *)(grp->data))[i]; if (!(pin->conf.mmio.config & IMX_NO_PAD_CTL)) map_num++; @@ -109,7 +109,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, /* create config map */ new_map++; - for (i = j = 0; i < grp->num_pins; i++) { + for (i = j = 0; i < grp->grp.npins; i++) { pin = &((struct imx_pin *)(grp->data))[i]; /* @@ -245,7 +245,7 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pinctrl_soc_info *info = ipctl->info; - struct function_desc *func; + const struct function_desc *func; struct group_desc *grp; struct imx_pin *pin; unsigned int npins; @@ -263,10 +263,10 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector, if (!func) return -EINVAL; - npins = grp->num_pins; + npins = grp->grp.npins; dev_dbg(ipctl->dev, "enable function %s group %s\n", - func->name, grp->name); + func->func->name, grp->grp.name); for (i = 0; i < npins; i++) { /* @@ -292,62 +292,6 @@ struct pinmux_ops imx_pmx_ops = { .set_mux = imx_pmx_set, }; -/* decode generic config into raw register values */ -static u32 imx_pinconf_decode_generic_config(struct imx_pinctrl *ipctl, - unsigned long *configs, - unsigned int num_configs) -{ - const struct imx_pinctrl_soc_info *info = ipctl->info; - const struct imx_cfg_params_decode *decode; - enum pin_config_param param; - u32 raw_config = 0; - u32 param_val; - int i, j; - - WARN_ON(num_configs > info->num_decodes); - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - param_val = pinconf_to_config_argument(configs[i]); - decode = info->decodes; - for (j = 0; j < info->num_decodes; j++) { - if (param == decode->param) { - if (decode->invert) - param_val = !param_val; - raw_config |= (param_val << decode->shift) - & decode->mask; - break; - } - decode++; - } - } - - if (info->fixup) - info->fixup(configs, num_configs, &raw_config); - - return raw_config; -} - -static u32 imx_pinconf_parse_generic_config(struct device_node *np, - struct imx_pinctrl *ipctl) -{ - const struct imx_pinctrl_soc_info *info = ipctl->info; - struct pinctrl_dev *pctl = ipctl->pctl; - unsigned int num_configs; - unsigned long *configs; - int ret; - - if (!info->generic_pinconf) - return 0; - - ret = pinconf_generic_parse_dt_config(np, pctl, &configs, - &num_configs); - if (ret) - return 0; - - return imx_pinconf_decode_generic_config(ipctl, configs, num_configs); -} - static int imx_pinconf_get_mmio(struct pinctrl_dev *pctldev, unsigned pin_id, unsigned long *config) { @@ -479,7 +423,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, if (!grp) return; - for (i = 0; i < grp->num_pins; i++) { + for (i = 0; i < grp->grp.npins; i++) { struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; name = pin_get_name(pctldev, pin->pin); @@ -500,7 +444,6 @@ static const struct pinconf_ops imx_pinconf_ops = { /* * Each pin represented in fsl,pins consists of a number of u32 PIN_FUNC_ID * and 1 u32 CONFIG, the total size is PIN_FUNC_ID + CONFIG for each pin. - * For generic_pinconf case, there's no extra u32 CONFIG. * * PIN_FUNC_ID format: * Default: @@ -548,18 +491,12 @@ static void imx_pinctrl_parse_pin_mmio(struct imx_pinctrl *ipctl, pin_mmio->mux_mode = be32_to_cpu(*list++); pin_mmio->input_val = be32_to_cpu(*list++); - if (info->generic_pinconf) { - /* generic pin config decoded */ - pin_mmio->config = imx_pinconf_parse_generic_config(np, ipctl); - } else { - /* legacy pin config read from devicetree */ - config = be32_to_cpu(*list++); + config = be32_to_cpu(*list++); - /* SION bit is in mux register */ - if (config & IMX_PAD_SION) - pin_mmio->mux_mode |= IOMUXC_CONFIG_SION; - pin_mmio->config = config & ~IMX_PAD_SION; - } + /* SION bit is in mux register */ + if (config & IMX_PAD_SION) + pin_mmio->mux_mode |= IOMUXC_CONFIG_SION; + pin_mmio->config = config & ~IMX_PAD_SION; *list_p = list; @@ -574,6 +511,7 @@ static int imx_pinctrl_parse_groups(struct device_node *np, { const struct imx_pinctrl_soc_info *info = ipctl->info; struct imx_pin *pin; + unsigned int *pins; int size, pin_size; const __be32 *list; int i; @@ -587,11 +525,8 @@ static int imx_pinctrl_parse_groups(struct device_node *np, else pin_size = FSL_PIN_SIZE; - if (info->generic_pinconf) - pin_size -= 4; - /* Initialise group */ - grp->name = np->name; + grp->grp.name = np->name; /* * the binding format is fsl,pins = <PIN_FUNC_ID CONFIG ...>, @@ -619,24 +554,22 @@ static int imx_pinctrl_parse_groups(struct device_node *np, return -EINVAL; } - grp->num_pins = size / pin_size; - grp->data = devm_kcalloc(ipctl->dev, - grp->num_pins, sizeof(struct imx_pin), - GFP_KERNEL); - grp->pins = devm_kcalloc(ipctl->dev, - grp->num_pins, sizeof(unsigned int), - GFP_KERNEL); - if (!grp->pins || !grp->data) + grp->grp.npins = size / pin_size; + grp->data = devm_kcalloc(ipctl->dev, grp->grp.npins, sizeof(*pin), GFP_KERNEL); + if (!grp->data) + return -ENOMEM; + + pins = devm_kcalloc(ipctl->dev, grp->grp.npins, sizeof(*pins), GFP_KERNEL); + if (!pins) return -ENOMEM; + grp->grp.pins = pins; - for (i = 0; i < grp->num_pins; i++) { + for (i = 0; i < grp->grp.npins; i++) { pin = &((struct imx_pin *)(grp->data))[i]; if (info->flags & IMX_USE_SCU) - info->imx_pinctrl_parse_pin(ipctl, &grp->pins[i], - pin, &list); + info->imx_pinctrl_parse_pin(ipctl, &pins[i], pin, &list); else - imx_pinctrl_parse_pin_mmio(ipctl, &grp->pins[i], - pin, &list, np); + imx_pinctrl_parse_pin_mmio(ipctl, &pins[i], pin, &list, np); } return 0; @@ -647,45 +580,50 @@ static int imx_pinctrl_parse_functions(struct device_node *np, u32 index) { struct pinctrl_dev *pctl = ipctl->pctl; - struct device_node *child; - struct function_desc *func; + struct pinfunction *func; struct group_desc *grp; const char **group_names; + int ret; u32 i; dev_dbg(pctl->dev, "parse function(%d): %pOFn\n", index, np); - func = pinmux_generic_get_function(pctl, index); + func = devm_kzalloc(ipctl->dev, sizeof(*func), GFP_KERNEL); if (!func) - return -EINVAL; + return -ENOMEM; /* Initialise function */ func->name = np->name; - func->num_group_names = of_get_child_count(np); - if (func->num_group_names == 0) { + func->ngroups = of_get_child_count(np); + if (func->ngroups == 0) { dev_info(ipctl->dev, "no groups defined in %pOF\n", np); return -EINVAL; } - group_names = devm_kcalloc(ipctl->dev, func->num_group_names, - sizeof(char *), GFP_KERNEL); + group_names = devm_kcalloc(ipctl->dev, func->ngroups, + sizeof(*func->groups), GFP_KERNEL); if (!group_names) return -ENOMEM; i = 0; - for_each_child_of_node(np, child) + for_each_child_of_node_scoped(np, child) group_names[i++] = child->name; - func->group_names = group_names; + func->groups = group_names; + + ret = pinmux_generic_add_pinfunction(pctl, func, NULL); + if (ret < 0) + return ret; i = 0; - for_each_child_of_node(np, child) { - grp = devm_kzalloc(ipctl->dev, sizeof(struct group_desc), - GFP_KERNEL); - if (!grp) { - of_node_put(child); + for_each_child_of_node_scoped(np, child) { + grp = devm_kzalloc(ipctl->dev, sizeof(*grp), GFP_KERNEL); + if (!grp) return -ENOMEM; - } mutex_lock(&ipctl->mutex); + /* + * FIXME: This should use pinctrl_generic_add_group() and not + * access the private radix tree directly. + */ radix_tree_insert(&pctl->pin_group_tree, ipctl->group_index++, grp); mutex_unlock(&ipctl->mutex); @@ -703,21 +641,13 @@ static int imx_pinctrl_parse_functions(struct device_node *np, */ static bool imx_pinctrl_dt_is_flat_functions(struct device_node *np) { - struct device_node *function_np; - struct device_node *pinctrl_np; - - for_each_child_of_node(np, function_np) { - if (of_property_read_bool(function_np, "fsl,pins")) { - of_node_put(function_np); + for_each_child_of_node_scoped(np, function_np) { + if (of_property_present(function_np, "fsl,pins")) return true; - } - for_each_child_of_node(function_np, pinctrl_np) { - if (of_property_read_bool(pinctrl_np, "fsl,pins")) { - of_node_put(pinctrl_np); - of_node_put(function_np); + for_each_child_of_node_scoped(function_np, pinctrl_np) { + if (of_property_present(pinctrl_np, "fsl,pins")) return false; - } } } @@ -748,20 +678,6 @@ static int imx_pinctrl_probe_dt(struct platform_device *pdev, } } - for (i = 0; i < nfuncs; i++) { - struct function_desc *function; - - function = devm_kzalloc(&pdev->dev, sizeof(*function), - GFP_KERNEL); - if (!function) - return -ENOMEM; - - mutex_lock(&ipctl->mutex); - radix_tree_insert(&pctl->pin_function_tree, i, function); - mutex_unlock(&ipctl->mutex); - } - pctl->num_functions = nfuncs; - ipctl->group_index = 0; if (flat_funcs) { pctl->num_groups = of_get_child_count(np); @@ -825,7 +741,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, if (IS_ERR(ipctl->base)) return PTR_ERR(ipctl->base); - if (of_property_read_bool(dev_np, "fsl,input-sel")) { + if (of_property_present(dev_np, "fsl,input-sel")) { np = of_parse_phandle(dev_np, "fsl,input-sel", 0); if (!np) { dev_err(&pdev->dev, "iomuxc fsl,input-sel property not found\n"); @@ -855,10 +771,6 @@ int imx_pinctrl_probe(struct platform_device *pdev, imx_pinctrl_desc->confops = &imx_pinconf_ops; imx_pinctrl_desc->owner = THIS_MODULE; - /* for generic pinconf */ - imx_pinctrl_desc->custom_params = info->custom_params; - imx_pinctrl_desc->num_custom_params = info->num_custom_params; - /* platform specific callback */ imx_pmx_ops.gpio_set_direction = info->gpio_set_direction; @@ -887,14 +799,14 @@ int imx_pinctrl_probe(struct platform_device *pdev, } EXPORT_SYMBOL_GPL(imx_pinctrl_probe); -static int __maybe_unused imx_pinctrl_suspend(struct device *dev) +static int imx_pinctrl_suspend(struct device *dev) { struct imx_pinctrl *ipctl = dev_get_drvdata(dev); return pinctrl_force_sleep(ipctl->pctl); } -static int __maybe_unused imx_pinctrl_resume(struct device *dev) +static int imx_pinctrl_resume(struct device *dev) { struct imx_pinctrl *ipctl = dev_get_drvdata(dev); @@ -902,8 +814,7 @@ static int __maybe_unused imx_pinctrl_resume(struct device *dev) } const struct dev_pm_ops imx_pinctrl_pm_ops = { - SET_LATE_SYSTEM_SLEEP_PM_OPS(imx_pinctrl_suspend, - imx_pinctrl_resume) + LATE_SYSTEM_SLEEP_PM_OPS(imx_pinctrl_suspend, imx_pinctrl_resume) }; EXPORT_SYMBOL_GPL(imx_pinctrl_pm_ops); |
