Commit d4e31987 authored by Stephen Warren's avatar Stephen Warren Committed by Linus Walleij

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: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent 3eedb437
...@@ -53,8 +53,6 @@ struct pinctrl_dev { ...@@ -53,8 +53,6 @@ struct pinctrl_dev {
* to keep track of nested use cases * to keep track of nested use cases
* @pctldev: pin control device handling this pin control handle * @pctldev: pin control device handling this pin control handle
* @mutex: a lock for the pin control state holder * @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 * @groups: the group selectors for the pinmux device and
* selector combination handling this pinmux, this is a list that * selector combination handling this pinmux, this is a list that
* will be traversed on all pinmux operations such as * will be traversed on all pinmux operations such as
...@@ -67,7 +65,6 @@ struct pinctrl { ...@@ -67,7 +65,6 @@ struct pinctrl {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
struct mutex mutex; struct mutex mutex;
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
unsigned func_selector;
struct list_head groups; struct list_head groups;
#endif #endif
}; };
......
...@@ -33,10 +33,13 @@ ...@@ -33,10 +33,13 @@
/** /**
* struct pinmux_group - group list item for pinmux groups * struct pinmux_group - group list item for pinmux groups
* @node: pinmux group list node * @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 * @group_selector: the group selector for this group
*/ */
struct pinmux_group { struct pinmux_group {
struct list_head node; struct list_head node;
unsigned func_selector;
unsigned group_selector; unsigned group_selector;
}; };
...@@ -476,24 +479,11 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, ...@@ -476,24 +479,11 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
if (ret < 0) if (ret < 0)
return ret; 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 */ /* Now add this group selector, we may have many of them */
grp = kmalloc(sizeof(*grp), GFP_KERNEL); grp = kmalloc(sizeof(*grp), GFP_KERNEL);
if (!grp) if (!grp)
return -ENOMEM; return -ENOMEM;
grp->func_selector = func_selector;
grp->group_selector = group_selector; grp->group_selector = group_selector;
ret = acquire_pins(pctldev, devname, group_selector); ret = acquire_pins(pctldev, devname, group_selector);
if (ret) { if (ret) {
...@@ -554,7 +544,7 @@ int pinmux_enable(struct pinctrl *p) ...@@ -554,7 +544,7 @@ int pinmux_enable(struct pinctrl *p)
int ret; int ret;
list_for_each_entry(grp, &p->groups, node) { 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); grp->group_selector);
if (ret) if (ret)
/* /*
...@@ -576,7 +566,7 @@ void pinmux_disable(struct pinctrl *p) ...@@ -576,7 +566,7 @@ void pinmux_disable(struct pinctrl *p)
struct pinmux_group *grp; struct pinmux_group *grp;
list_for_each_entry(grp, &p->groups, node) { list_for_each_entry(grp, &p->groups, node) {
ops->disable(pctldev, p->func_selector, ops->disable(pctldev, grp->func_selector,
grp->group_selector); grp->group_selector);
} }
} }
...@@ -654,21 +644,22 @@ void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) ...@@ -654,21 +644,22 @@ void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p)
const struct pinmux_ops *pmxops; const struct pinmux_ops *pmxops;
const struct pinctrl_ops *pctlops; const struct pinctrl_ops *pctlops;
struct pinmux_group *grp; struct pinmux_group *grp;
const char *sep = "";
pmxops = pctldev->desc->pmxops; pmxops = pctldev->desc->pmxops;
pctlops = pctldev->desc->pctlops; 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: ["); seq_printf(s, " groups: [");
list_for_each_entry(grp, &p->groups, node) { 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, pctlops->get_group_name(pctldev,
grp->group_selector), grp->group_selector),
grp->group_selector); grp->group_selector,
pmxops->get_function_name(pctldev,
grp->func_selector),
grp->func_selector);
sep = ", ";
} }
seq_printf(s, " ]"); seq_printf(s, " ]");
} }
......
...@@ -23,7 +23,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, ...@@ -23,7 +23,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
unsigned pin, bool input); unsigned pin, bool input);
static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) static inline void pinmux_init_pinctrl_handle(struct pinctrl *p)
{ {
p->func_selector = UINT_MAX;
INIT_LIST_HEAD(&p->groups); INIT_LIST_HEAD(&p->groups);
} }
int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, int pinmux_apply_muxmap(struct pinctrl_dev *pctldev,
......
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