pinctrl: enhance pinctrl_get() to handle multiple functions
authorStephen Warren <swarren@nvidia.com>
Fri, 2 Mar 2012 01:48:31 +0000 (18:48 -0700)
committerLinus Walleij <linus.walleij@linaro.org>
Fri, 2 Mar 2012 15:12:03 +0000 (16:12 +0100)
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>
drivers/pinctrl/core.h
drivers/pinctrl/pinmux.c
drivers/pinctrl/pinmux.h

index 7551611666f8988012489bbd5290a827b10ab7da..8164e7b4182bfc5a053e9ec4983350d78a030610 100644 (file)
@@ -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
 };
index 2a405618b448fde3d762993ce2e4a33049ba353a..f409f161ea1d1cd6732ed051f360bcfe758373b3 100644 (file)
 /**
  * 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, " ]");
 }
index 84b8fe946b5c9f77bb5695a76d7bb291b3124b39..822febb2d9680c56007881fb1a80a3fbefce08f3 100644 (file)
@@ -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,