Browse Source

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>
Stephen Warren 13 years ago
parent
commit
d4e3198736
3 changed files with 14 additions and 27 deletions
  1. 0 3
      drivers/pinctrl/core.h
  2. 14 23
      drivers/pinctrl/pinmux.c
  3. 0 1
      drivers/pinctrl/pinmux.h

+ 0 - 3
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
 };

+ 14 - 23
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, " ]");
 }

+ 0 - 1
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,