summaryrefslogtreecommitdiff
path: root/drivers/pinctrl/pinctrl-single.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2016-12-27 20:20:03 +0300
committerLinus Walleij <linus.walleij@linaro.org>2017-01-03 11:26:19 +0300
commit571aec4df5b72a80f80d1e524da8fbd7ff525c98 (patch)
treed565a6ae231ffefd8a5d59fbc2873807c93f9a92 /drivers/pinctrl/pinctrl-single.c
parentcaeb774ea3b1bc25dc2f24681c27543aba6ca7ae (diff)
downloadlinux-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.c134
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) {