diff options
author | Tony Lindgren <tony@atomide.com> | 2016-12-27 20:20:03 +0300 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2017-01-03 11:26:19 +0300 |
commit | 571aec4df5b72a80f80d1e524da8fbd7ff525c98 (patch) | |
tree | d565a6ae231ffefd8a5d59fbc2873807c93f9a92 /drivers/pinctrl/pinctrl-single.c | |
parent | caeb774ea3b1bc25dc2f24681c27543aba6ca7ae (diff) | |
download | linux-571aec4df5b72a80f80d1e524da8fbd7ff525c98.tar.xz |
pinctrl: single: Use generic pinmux helpers for managing functions
We can now drop the driver specific code for managing functions.
Signed-off-by: Tony Lindgren <tony@atomide.com>
[Replaces GENERIC_PINMUX with GENERIC_PINMUX_FUNCTIONS]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-single.c')
-rw-r--r-- | drivers/pinctrl/pinctrl-single.c | 134 |
1 files changed, 18 insertions, 116 deletions
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 5e7a37ddef8e..8408263de466 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -33,6 +33,7 @@ #include "core.h" #include "devicetree.h" #include "pinconf.h" +#include "pinmux.h" #define DRIVER_NAME "pinctrl-single" #define PCS_OFF_DISABLED ~0U @@ -160,13 +161,10 @@ struct pcs_soc_data { * @bits_per_mux: number of bits per mux * @bits_per_pin: number of bits per pin * @pins: physical pins on the SoC - * @ftree: function index radix tree - * @functions: list of functions * @gpiofuncs: list of gpio functions * @irqs: list of interrupt registers * @chip: chip container for this instance * @domain: IRQ domain for this instance - * @nfuncs: number of functions * @desc: pin controller descriptor * @read: register read function to use * @write: register write function to use @@ -194,13 +192,10 @@ struct pcs_device { bool bits_per_mux; unsigned bits_per_pin; struct pcs_data pins; - struct radix_tree_root ftree; - struct list_head functions; struct list_head gpiofuncs; struct list_head irqs; struct irq_chip chip; struct irq_domain *domain; - unsigned nfuncs; struct pinctrl_desc desc; unsigned (*read)(void __iomem *reg); void (*write)(unsigned val, void __iomem *reg); @@ -307,59 +302,13 @@ static const struct pinctrl_ops pcs_pinctrl_ops = { .dt_free_map = pcs_dt_free_map, }; -static int pcs_get_functions_count(struct pinctrl_dev *pctldev) -{ - struct pcs_device *pcs; - - pcs = pinctrl_dev_get_drvdata(pctldev); - - return pcs->nfuncs; -} - -static const char *pcs_get_function_name(struct pinctrl_dev *pctldev, - unsigned fselector) -{ - struct pcs_device *pcs; - struct pcs_function *func; - - pcs = pinctrl_dev_get_drvdata(pctldev); - func = radix_tree_lookup(&pcs->ftree, fselector); - if (!func) { - dev_err(pcs->dev, "%s could not find function%i\n", - __func__, fselector); - return NULL; - } - - return func->name; -} - -static int pcs_get_function_groups(struct pinctrl_dev *pctldev, - unsigned fselector, - const char * const **groups, - unsigned * const ngroups) -{ - struct pcs_device *pcs; - struct pcs_function *func; - - pcs = pinctrl_dev_get_drvdata(pctldev); - func = radix_tree_lookup(&pcs->ftree, fselector); - if (!func) { - dev_err(pcs->dev, "%s could not find function%i\n", - __func__, fselector); - return -EINVAL; - } - *groups = func->pgnames; - *ngroups = func->npgnames; - - return 0; -} - static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin, struct pcs_function **func) { struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); struct pin_desc *pdesc = pin_desc_get(pctldev, pin); const struct pinctrl_setting_mux *setting; + struct function_desc *function; unsigned fselector; /* If pin is not described in DTS & enabled, mux_setting is NULL. */ @@ -367,7 +316,8 @@ static int pcs_get_function(struct pinctrl_dev *pctldev, unsigned pin, if (!setting) return -ENOTSUPP; fselector = setting->func; - *func = radix_tree_lookup(&pcs->ftree, fselector); + function = pinmux_generic_get_function(pctldev, fselector); + *func = function->data; if (!(*func)) { dev_err(pcs->dev, "%s could not find function%i\n", __func__, fselector); @@ -380,6 +330,7 @@ static int pcs_set_mux(struct pinctrl_dev *pctldev, unsigned fselector, unsigned group) { struct pcs_device *pcs; + struct function_desc *function; struct pcs_function *func; int i; @@ -387,7 +338,8 @@ static int pcs_set_mux(struct pinctrl_dev *pctldev, unsigned fselector, /* If function mask is null, needn't enable it. */ if (!pcs->fmask) return 0; - func = radix_tree_lookup(&pcs->ftree, fselector); + function = pinmux_generic_get_function(pctldev, fselector); + func = function->data; if (!func) return -EINVAL; @@ -445,9 +397,9 @@ static int pcs_request_gpio(struct pinctrl_dev *pctldev, } static const struct pinmux_ops pcs_pinmux_ops = { - .get_functions_count = pcs_get_functions_count, - .get_function_name = pcs_get_function_name, - .get_function_groups = pcs_get_function_groups, + .get_functions_count = pinmux_generic_get_function_count, + .get_function_name = pinmux_generic_get_function_name, + .get_function_groups = pinmux_generic_get_function_groups, .set_mux = pcs_set_mux, .gpio_request_enable = pcs_request_gpio, }; @@ -789,43 +741,24 @@ static struct pcs_function *pcs_add_function(struct pcs_device *pcs, unsigned npgnames) { struct pcs_function *function; + int res; function = devm_kzalloc(pcs->dev, sizeof(*function), GFP_KERNEL); if (!function) return NULL; - function->name = name; function->vals = vals; function->nvals = nvals; - function->pgnames = pgnames; - function->npgnames = npgnames; - mutex_lock(&pcs->mutex); - list_add_tail(&function->node, &pcs->functions); - radix_tree_insert(&pcs->ftree, pcs->nfuncs, function); - pcs->nfuncs++; - mutex_unlock(&pcs->mutex); + res = pinmux_generic_add_function(pcs->pctl, name, + pgnames, npgnames, + function); + if (res) + return NULL; return function; } -static void pcs_remove_function(struct pcs_device *pcs, - struct pcs_function *function) -{ - int i; - - mutex_lock(&pcs->mutex); - for (i = 0; i < pcs->nfuncs; i++) { - struct pcs_function *found; - - found = radix_tree_lookup(&pcs->ftree, i); - if (found == function) - radix_tree_delete(&pcs->ftree, i); - } - list_del(&function->node); - mutex_unlock(&pcs->mutex); -} - /** * pcs_get_pin_by_offset() - get a pin index based on the register offset * @pcs: pcs driver instance @@ -1103,7 +1036,7 @@ free_pingroups: pinctrl_generic_remove_last_group(pcs->pctl); *num_maps = 1; free_function: - pcs_remove_function(pcs, function); + pinmux_generic_remove_last_function(pcs->pctl); free_pins: devm_kfree(pcs->dev, pins); @@ -1235,8 +1168,7 @@ free_pingroups: pinctrl_generic_remove_last_group(pcs->pctl); *num_maps = 1; free_function: - pcs_remove_function(pcs, function); - + pinmux_generic_remove_last_function(pcs->pctl); free_pins: devm_kfree(pcs->dev, pins); @@ -1304,33 +1236,6 @@ free_map: } /** - * pcs_free_funcs() - free memory used by functions - * @pcs: pcs driver instance - */ -static void pcs_free_funcs(struct pcs_device *pcs) -{ - struct list_head *pos, *tmp; - int i; - - mutex_lock(&pcs->mutex); - for (i = 0; i < pcs->nfuncs; i++) { - struct pcs_function *func; - - func = radix_tree_lookup(&pcs->ftree, i); - if (!func) - continue; - radix_tree_delete(&pcs->ftree, i); - } - list_for_each_safe(pos, tmp, &pcs->functions) { - struct pcs_function *function; - - function = list_entry(pos, struct pcs_function, node); - list_del(&function->node); - } - mutex_unlock(&pcs->mutex); -} - -/** * pcs_irq_free() - free interrupt * @pcs: pcs driver instance */ @@ -1358,7 +1263,6 @@ static void pcs_free_resources(struct pcs_device *pcs) { pcs_irq_free(pcs); pinctrl_unregister(pcs->pctl); - pcs_free_funcs(pcs); #if IS_BUILTIN(CONFIG_PINCTRL_SINGLE) if (pcs->missing_nr_pinctrl_cells) @@ -1753,7 +1657,6 @@ static int pcs_probe(struct platform_device *pdev) pcs->np = np; raw_spin_lock_init(&pcs->lock); mutex_init(&pcs->mutex); - INIT_LIST_HEAD(&pcs->functions); INIT_LIST_HEAD(&pcs->gpiofuncs); soc = match->data; pcs->flags = soc->flags; @@ -1814,7 +1717,6 @@ static int pcs_probe(struct platform_device *pdev) return -ENODEV; } - INIT_RADIX_TREE(&pcs->ftree, GFP_KERNEL); platform_set_drvdata(pdev, pcs); switch (pcs->width) { |