diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-03-01 18:48:31 -0700 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-03-02 16:12:03 +0100 |
commit | d4e3198736d9d64e4ba4d2b46ab75cbcf5d0a4e0 (patch) | |
tree | e5e06f5c3ec83949e10f5407a1020ff5e07a7934 /drivers/pinctrl | |
parent | 3eedb4372354a70ce63c9f4ec294d2eba0d79d17 (diff) | |
download | linux-d4e3198736d9d64e4ba4d2b46ab75cbcf5d0a4e0.tar.bz2 |
pinctrl: enhance pinctrl_get() to handle multiple functions
At present, pinctrl_get() assumes that all matching mapping table entries
have the same "function" value, albeit potentially applied to different
pins/groups.
This change removes this restriction; pinctrl_get() can now handle a set
of mapping tables where different functions are applied to the various
pins/groups.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/core.h | 3 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.c | 37 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.h | 1 |
3 files changed, 14 insertions, 27 deletions
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 7551611666f8..8164e7b4182b 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -53,8 +53,6 @@ struct pinctrl_dev { * to keep track of nested use cases * @pctldev: pin control device handling this pin control handle * @mutex: a lock for the pin control state holder - * @func_selector: the function selector for the pinmux device handling - * this pinmux * @groups: the group selectors for the pinmux device and * selector combination handling this pinmux, this is a list that * will be traversed on all pinmux operations such as @@ -67,7 +65,6 @@ struct pinctrl { struct pinctrl_dev *pctldev; struct mutex mutex; #ifdef CONFIG_PINMUX - unsigned func_selector; struct list_head groups; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 2a405618b448..f409f161ea1d 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -33,10 +33,13 @@ /** * struct pinmux_group - group list item for pinmux groups * @node: pinmux group list node + * @func_selector: the function selector for the pinmux device handling + * this pinmux * @group_selector: the group selector for this group */ struct pinmux_group { struct list_head node; + unsigned func_selector; unsigned group_selector; }; @@ -476,24 +479,11 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, if (ret < 0) return ret; - /* - * If the function selector is already set, it needs to be identical, - * we support several groups with one function but not several - * functions with one or several groups in the same pinmux. - */ - if (p->func_selector != UINT_MAX && - p->func_selector != func_selector) { - dev_err(pctldev->dev, - "dual function defines in the map for device %s\n", - devname); - return -EINVAL; - } - p->func_selector = func_selector; - /* Now add this group selector, we may have many of them */ grp = kmalloc(sizeof(*grp), GFP_KERNEL); if (!grp) return -ENOMEM; + grp->func_selector = func_selector; grp->group_selector = group_selector; ret = acquire_pins(pctldev, devname, group_selector); if (ret) { @@ -554,7 +544,7 @@ int pinmux_enable(struct pinctrl *p) int ret; list_for_each_entry(grp, &p->groups, node) { - ret = ops->enable(pctldev, p->func_selector, + ret = ops->enable(pctldev, grp->func_selector, grp->group_selector); if (ret) /* @@ -576,7 +566,7 @@ void pinmux_disable(struct pinctrl *p) struct pinmux_group *grp; list_for_each_entry(grp, &p->groups, node) { - ops->disable(pctldev, p->func_selector, + ops->disable(pctldev, grp->func_selector, grp->group_selector); } } @@ -654,21 +644,22 @@ void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) const struct pinmux_ops *pmxops; const struct pinctrl_ops *pctlops; struct pinmux_group *grp; + const char *sep = ""; pmxops = pctldev->desc->pmxops; pctlops = pctldev->desc->pctlops; - seq_printf(s, " function: %s (%u),", - pmxops->get_function_name(pctldev, - p->func_selector), - p->func_selector); - seq_printf(s, " groups: ["); list_for_each_entry(grp, &p->groups, node) { - seq_printf(s, " %s (%u)", + seq_printf(s, "%s%s (%u)=%s (%u)", + sep, pctlops->get_group_name(pctldev, grp->group_selector), - grp->group_selector); + grp->group_selector, + pmxops->get_function_name(pctldev, + grp->func_selector), + grp->func_selector); + sep = ", "; } seq_printf(s, " ]"); } diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 84b8fe946b5c..822febb2d968 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -23,7 +23,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, unsigned pin, bool input); static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) { - p->func_selector = UINT_MAX; INIT_LIST_HEAD(&p->groups); } int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, |