Skip to contentSkip to conversation

pinctrl: Pass all configs to driver on pin_config_set()

PATCH Superseded Sherman Yin 6 participants 14 messages Aug 15, 2013 – Aug 28, 2013 1 message not in the archive

Subsystems (14)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 pinctrl: Pass all configs to driver on pin_config_set()

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

Change-Id I99cbfa2ae7b774456eb71edb276711b1ddcd42c8

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  123 ++++++++++++----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   77 +++++++-------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 23 files changed, 879 insertions(+), 663 deletions(-)
drivers/pinctrl/mvebu/pinctrl-mvebu.c +20 -6
index bb7ddb1..e78c041 100644
@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned gid, unsigned long config)
+				unsigned gid, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+	int i, ret;
 
 	if (!grp->ctrl)
 		return -EINVAL;
 
-	if (grp->ctrl->mpp_set)
-		return grp->ctrl->mpp_set(grp->ctrl, config);
+	for (i = 0; i < num_configs; i++) {
+		if (grp->ctrl->mpp_set)
+			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
+		else
+			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
 
-	return mvebu_common_mpp_set(pctl, grp, config);
+		if (ret)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
@@ -303,6 +312,7 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 	struct mvebu_mpp_ctrl_setting *setting;
 	int ret;
+	unsigned long config;
 
 	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 						     func->name);
@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 		return -EINVAL;
 	}
 
-	ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 	if (ret) {
 		dev_err(pctl->dev, "cannot set group %s to %s\n",
 			func->groups[gid], func->name);
@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp;
 	struct mvebu_mpp_ctrl_setting *setting;
+	unsigned long config;
 
 	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 	if (!grp)
@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	if (!setting)
 		return -ENOTSUPP;
 
-	return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+
+	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 }
 
 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drivers/pinctrl/pinconf.c +19 -23

60 lines not on this page · raw message

drivers/pinctrl/pinctrl-abx500.c +102 -85

200 lines not on this page · raw message

drivers/pinctrl/pinctrl-at91.c +29 -19

59 lines not on this page · raw message

drivers/pinctrl/pinctrl-bcm2835.c +25 -18

53 lines not on this page · raw message

drivers/pinctrl/pinctrl-exynos5440.c +61 -52

139 lines not on this page · raw message

drivers/pinctrl/pinctrl-falcon.c +36 -27

82 lines not on this page · raw message

drivers/pinctrl/pinctrl-imx.c +16 -12
index 57a4eb0..bf94386 100644
@@ -310,11 +310,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int imx_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+			     unsigned pin_id, unsigned long *configs,
+			     unsigned num_configs)
 {
 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+	int i;
 
 	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
@@ -325,17 +327,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	if (info->flags & SHARE_MUX_CONF_REG) {
-		u32 reg;
-		reg = readl(ipctl->base + pin_reg->conf_reg);
-		reg &= ~0xffff;
-		reg |= config;
-		writel(reg, ipctl->base + pin_reg->conf_reg);
-	} else {
-		writel(config, ipctl->base + pin_reg->conf_reg);
-	}
-	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
-		pin_reg->conf_reg, config);
+	for (i = 0; i < num_configs; i++) {
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->conf_reg);
+			reg &= ~0xffff;
+			reg |= configs[i];
+			writel(reg, ipctl->base + pin_reg->conf_reg);
+		} else {
+			writel(configs[i], ipctl->base + pin_reg->conf_reg);
+		}
+		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+			pin_reg->conf_reg, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-mxs.c +50 -41

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +66 -57

147 lines not on this page · raw message

drivers/pinctrl/pinctrl-rockchip.c +35 -22

67 lines not on this page · raw message

drivers/pinctrl/pinctrl-samsung.c +13 -4
index a7fa9e2..cde23f4 100644
@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin */
 static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long config)
+				unsigned long *configs, unsigned num_configs)
 {
-	return samsung_pinconf_rw(pctldev, pin, &config, true);
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+		if (ret < 0)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 /* get the pin config settings for a specified pin */
@@ -456,7 +464,8 @@ static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin group */
 static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-			unsigned group, unsigned long config)
+			unsigned group, unsigned long *configs,
+			unsigned num_configs)
 {
 	struct samsung_pinctrl_drv_data *drvdata;
 	const unsigned int *pins;
@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 	pins = drvdata->pin_groups[group].pins;
 
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-		samsung_pinconf_set(pctldev, pins[cnt], config);
+		samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
 
 	return 0;
 }
drivers/pinctrl/pinctrl-single.c +22 -11
index 7323cca..a82ace4 100644
@@ -209,7 +209,7 @@ struct pcs_device {
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
+			   unsigned long *configs, unsigned num_configs);
 
 static enum pin_config_param pcs_bias[] = {
 	PIN_CONFIG_BIAS_PULL_DOWN,
@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
 	int i;
 	for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
 		config = pinconf_to_config_packed(pcs_bias[i], 0);
-		pcs_pinconf_set(pctldev, pin, config);
+		pcs_pinconf_set(pctldev, pin, &config, 1);
 	}
 }
 
@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
-				unsigned pin, unsigned long config)
+				unsigned pin, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pcs_function *func;
 	unsigned offset = 0, shift = 0, i, data, ret;
 	u16 arg;
+	int j;
 
 	ret = pcs_get_function(pctldev, pin, &func);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < func->nconfs; i++) {
-		if (pinconf_to_config_param(config) == func->conf[i].param) {
+	for (j = 0; j < num_configs; j++) {
+		for (i = 0; i < func->nconfs; i++) {
+			if (pinconf_to_config_param(configs[j])
+				!= func->conf[i].param)
+				continue;
+
 			offset = pin * (pcs->width / BITS_PER_BYTE);
 			data = pcs->read(pcs->base + offset);
-			arg = pinconf_to_config_argument(config);
+			arg = pinconf_to_config_argument(configs[j]);
 			switch (func->conf[i].param) {
 			/* 2 parameters */
 			case PIN_CONFIG_INPUT_SCHMITT:
@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				return -ENOTSUPP;
 			}
 			pcs->write(data, pcs->base + offset);
-			return 0;
+
+			break;
 		}
-	}
-	return -ENOTSUPP;
+		if (i >= func->nconfs)
+			return -ENOTSUPP;
+	} /* for each config */
+
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
@@ -695,7 +705,8 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned group, unsigned long config)
+				unsigned group, unsigned long *configs,
+				unsigned num_configs)
 {
 	const unsigned *pins;
 	unsigned npins;
@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 	if (ret)
 		return ret;
 	for (i = 0; i < npins; i++) {
-		if (pcs_pinconf_set(pctldev, pins[i], config))
+		if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs))
 			return -ENOTSUPP;
 	}
 	return 0;
drivers/pinctrl/pinctrl-st.c +7 -4
index 04d4506..7d67e4b 100644
@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
 							config, pin);
 }
 
-static int st_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
 {
 	int pin = st_gpio_pin(pin_id);
 	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+	int i;
 
-	st_pinconf_set_config(pc, pin, config);
-	st_pinconf_set_retime(info, pc, pin, config);
+	for (i = 0; i < num_configs; i++) {
+		st_pinconf_set_config(pc, pin, configs[i]);
+		st_pinconf_set_retime(info, pc, pin, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-sunxi.c +41 -36

91 lines not on this page · raw message

drivers/pinctrl/pinctrl-tegra.c +38 -31

96 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090-pdc.c +78 -57

171 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090.c +80 -60

187 lines not on this page · raw message

drivers/pinctrl/pinctrl-u300.c +10 -8
index 46a152d..ef6e300 100644
@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
 }
 
 static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			       unsigned long config)
+			       unsigned long *configs, unsigned num_configs)
 {
 	struct pinctrl_gpio_range *range =
 		pinctrl_find_gpio_range_from_pin(pctldev, pin);
-	int ret;
+	int ret, i;
 
 	if (!range)
 		return -EINVAL;
 
-	/* Note: none of these configurations take any argument */
-	ret = u300_gpio_config_set(range->gc,
-				   (pin - range->pin_base + range->base),
-				   pinconf_to_config_param(config));
-	if (ret)
-		return ret;
+	for (i = 0; i < num_configs; i++) {
+		/* Note: none of these configurations take any argument */
+		ret = u300_gpio_config_set(range->gc,
+			(pin - range->pin_base + range->base),
+			pinconf_to_config_param(configs[i]));
+		if (ret)
+			return ret;
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-xway.c +73 -46

147 lines not on this page · raw message

drivers/pinctrl/sh-pfc/pinctrl.c +24 -18

69 lines not on this page · raw message

drivers/pinctrl/vt8500/pinctrl-wmt.c +30 -24

73 lines not on this page · raw message

include/linux/pinctrl/pinconf.h +4 -2
index f699869..09eb80f 100644
@@ -47,13 +47,15 @@ struct pinconf_ops {
 			       unsigned long *config);
 	int (*pin_config_set) (struct pinctrl_dev *pctldev,
 			       unsigned pin,
-			       unsigned long config);
+			       unsigned long *configs,
+			       unsigned num_configs);
 	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
 				     unsigned long *config);
 	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
-				     unsigned long config);
+				     unsigned long *configs,
+				     unsigned num_configs);
 	int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
 					   const char *arg,
 					   unsigned long *config);
Signature · 1 line
1.7.9.5
#1 lore raw
Quoted 9 lines · Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

Quoted 5 lines

Change-Id: I99cbfa2ae7b774456eb71edb276711b1ddcd42c8

That tag shouldn't be included in upstream patches.

Quoted 3 lines
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 include/linux/pinctrl/pinconf.h       |    6 +-

Those files, Reviewed-by: Stephen Warren <[email protected]>

On Tegra (Tegra114 Dalmore board, on top of next-20130816),
Tested-by: Stephen Warren <nvidia.com>

#2 lore raw
In reply to Sherman Yin

Hi Sherman,

Quoted 13 lines · Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

Change-Id I99cbfa2ae7b774456eb71edb276711b1ddcd42c8
Quoted 8 lines

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

Good work! This is obviously the right thing to do and it's looking very good.

Right now this does not apply to my "devel" branch, so I'd like you to rebase on that right now. (This is what will go into v3.12).

This is also late in the development cycle so I believe this is going to be v3.13 material unless there are more release candidates.

You can also hold on until after the v3.12 merge window and then rebase it and we'll merge it as a first patch in the v3.13 development cycle.

What do you say?

Yours,
Linus Walleij

#3 lore raw

Hi Linus,

Quoted 11 lines

Right now this does not apply to my "devel" branch, so I'd like you to rebase on that right now. (This is what will go into v3.12).

This is also late in the development cycle so I believe this is going to be v3.13 material unless there are more release candidates.

You can also hold on until after the v3.12 merge window and then rebase it and we'll merge it as a first patch in the v3.13 development cycle.

What do you say?

You mean the "devel" branch in this tree, right? Please let me know if you're talking about another tree/branch.

git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git

I cherry-picked my commit on top of devel, and there was just a simple conflict in pinctrl-sunxi.c. It's easy enough to fix, so I'll send out v2 that's based on "devel" instead of rc6 anyway. I can just do another rebase after v3.12 merge window if needed.

Thanks!
Sherman

#4 lore raw

PATCH v2 1/1 pinctrl: Pass all configs to driver on pin_config_set()

In reply to Sherman Yin

From: Sherman Yin <[email protected]>

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   95 +++++++++--------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 23 files changed, 889 insertions(+), 673 deletions(-)
drivers/pinctrl/mvebu/pinctrl-mvebu.c +20 -6
index bb7ddb1..e78c041 100644
@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned gid, unsigned long config)
+				unsigned gid, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+	int i, ret;
 
 	if (!grp->ctrl)
 		return -EINVAL;
 
-	if (grp->ctrl->mpp_set)
-		return grp->ctrl->mpp_set(grp->ctrl, config);
+	for (i = 0; i < num_configs; i++) {
+		if (grp->ctrl->mpp_set)
+			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
+		else
+			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
 
-	return mvebu_common_mpp_set(pctl, grp, config);
+		if (ret)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
@@ -303,6 +312,7 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 	struct mvebu_mpp_ctrl_setting *setting;
 	int ret;
+	unsigned long config;
 
 	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 						     func->name);
@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 		return -EINVAL;
 	}
 
-	ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 	if (ret) {
 		dev_err(pctl->dev, "cannot set group %s to %s\n",
 			func->groups[gid], func->name);
@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp;
 	struct mvebu_mpp_ctrl_setting *setting;
+	unsigned long config;
 
 	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 	if (!grp)
@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	if (!setting)
 		return -ENOTSUPP;
 
-	return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+
+	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 }
 
 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drivers/pinctrl/pinconf.c +19 -23

60 lines not on this page · raw message

drivers/pinctrl/pinctrl-abx500.c +102 -85

200 lines not on this page · raw message

drivers/pinctrl/pinctrl-at91.c +29 -19

59 lines not on this page · raw message

drivers/pinctrl/pinctrl-bcm2835.c +25 -18

53 lines not on this page · raw message

drivers/pinctrl/pinctrl-exynos5440.c +61 -52

139 lines not on this page · raw message

drivers/pinctrl/pinctrl-falcon.c +36 -27

82 lines not on this page · raw message

drivers/pinctrl/pinctrl-imx.c +16 -12
index 3a14245..51f3a49 100644
@@ -335,11 +335,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int imx_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+			     unsigned pin_id, unsigned long *configs,
+			     unsigned num_configs)
 {
 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+	int i;
 
 	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
@@ -350,17 +352,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	if (info->flags & SHARE_MUX_CONF_REG) {
-		u32 reg;
-		reg = readl(ipctl->base + pin_reg->conf_reg);
-		reg &= ~0xffff;
-		reg |= config;
-		writel(reg, ipctl->base + pin_reg->conf_reg);
-	} else {
-		writel(config, ipctl->base + pin_reg->conf_reg);
-	}
-	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
-		pin_reg->conf_reg, config);
+	for (i = 0; i < num_configs; i++) {
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->conf_reg);
+			reg &= ~0xffff;
+			reg |= configs[i];
+			writel(reg, ipctl->base + pin_reg->conf_reg);
+		} else {
+			writel(configs[i], ipctl->base + pin_reg->conf_reg);
+		}
+		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+			pin_reg->conf_reg, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-mxs.c +50 -41

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +67 -58

148 lines not on this page · raw message

drivers/pinctrl/pinctrl-rockchip.c +35 -22

67 lines not on this page · raw message

drivers/pinctrl/pinctrl-samsung.c +13 -4
index 439f2ef..222648d 100644
@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin */
 static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long config)
+				unsigned long *configs, unsigned num_configs)
 {
-	return samsung_pinconf_rw(pctldev, pin, &config, true);
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+		if (ret < 0)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 /* get the pin config settings for a specified pin */
@@ -456,7 +464,8 @@ static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin group */
 static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-			unsigned group, unsigned long config)
+			unsigned group, unsigned long *configs,
+			unsigned num_configs)
 {
 	struct samsung_pinctrl_drv_data *drvdata;
 	const unsigned int *pins;
@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 	pins = drvdata->pin_groups[group].pins;
 
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-		samsung_pinconf_set(pctldev, pins[cnt], config);
+		samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
 
 	return 0;
 }
drivers/pinctrl/pinctrl-single.c +22 -11
index 6866548..8f31768 100644
@@ -209,7 +209,7 @@ struct pcs_device {
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
+			   unsigned long *configs, unsigned num_configs);
 
 static enum pin_config_param pcs_bias[] = {
 	PIN_CONFIG_BIAS_PULL_DOWN,
@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
 	int i;
 	for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
 		config = pinconf_to_config_packed(pcs_bias[i], 0);
-		pcs_pinconf_set(pctldev, pin, config);
+		pcs_pinconf_set(pctldev, pin, &config, 1);
 	}
 }
 
@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
-				unsigned pin, unsigned long config)
+				unsigned pin, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pcs_function *func;
 	unsigned offset = 0, shift = 0, i, data, ret;
 	u16 arg;
+	int j;
 
 	ret = pcs_get_function(pctldev, pin, &func);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < func->nconfs; i++) {
-		if (pinconf_to_config_param(config) == func->conf[i].param) {
+	for (j = 0; j < num_configs; j++) {
+		for (i = 0; i < func->nconfs; i++) {
+			if (pinconf_to_config_param(configs[j])
+				!= func->conf[i].param)
+				continue;
+
 			offset = pin * (pcs->width / BITS_PER_BYTE);
 			data = pcs->read(pcs->base + offset);
-			arg = pinconf_to_config_argument(config);
+			arg = pinconf_to_config_argument(configs[j]);
 			switch (func->conf[i].param) {
 			/* 2 parameters */
 			case PIN_CONFIG_INPUT_SCHMITT:
@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				return -ENOTSUPP;
 			}
 			pcs->write(data, pcs->base + offset);
-			return 0;
+
+			break;
 		}
-	}
-	return -ENOTSUPP;
+		if (i >= func->nconfs)
+			return -ENOTSUPP;
+	} /* for each config */
+
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
@@ -695,7 +705,8 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned group, unsigned long config)
+				unsigned group, unsigned long *configs,
+				unsigned num_configs)
 {
 	const unsigned *pins;
 	unsigned npins;
@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 	if (ret)
 		return ret;
 	for (i = 0; i < npins; i++) {
-		if (pcs_pinconf_set(pctldev, pins[i], config))
+		if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs))
 			return -ENOTSUPP;
 	}
 	return 0;
drivers/pinctrl/pinctrl-st.c +7 -4
index 2a10a31..9cadc68 100644
@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
 							config, pin);
 }
 
-static int st_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
 {
 	int pin = st_gpio_pin(pin_id);
 	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+	int i;
 
-	st_pinconf_set_config(pc, pin, config);
-	st_pinconf_set_retime(info, pc, pin, config);
+	for (i = 0; i < num_configs; i++) {
+		st_pinconf_set_config(pc, pin, configs[i]);
+		st_pinconf_set_retime(info, pc, pin, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-sunxi.c +50 -45

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-tegra.c +38 -31

96 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090-pdc.c +78 -57

171 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090.c +80 -60

187 lines not on this page · raw message

drivers/pinctrl/pinctrl-u300.c +10 -8
index 6fbdc06..209a01b 100644
@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
 }
 
 static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			       unsigned long config)
+			       unsigned long *configs, unsigned num_configs)
 {
 	struct pinctrl_gpio_range *range =
 		pinctrl_find_gpio_range_from_pin(pctldev, pin);
-	int ret;
+	int ret, i;
 
 	if (!range)
 		return -EINVAL;
 
-	/* Note: none of these configurations take any argument */
-	ret = u300_gpio_config_set(range->gc,
-				   (pin - range->pin_base + range->base),
-				   pinconf_to_config_param(config));
-	if (ret)
-		return ret;
+	for (i = 0; i < num_configs; i++) {
+		/* Note: none of these configurations take any argument */
+		ret = u300_gpio_config_set(range->gc,
+			(pin - range->pin_base + range->base),
+			pinconf_to_config_param(configs[i]));
+		if (ret)
+			return ret;
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-xway.c +73 -46

147 lines not on this page · raw message

drivers/pinctrl/sh-pfc/pinctrl.c +24 -18

69 lines not on this page · raw message

drivers/pinctrl/vt8500/pinctrl-wmt.c +30 -24

73 lines not on this page · raw message

include/linux/pinctrl/pinconf.h +4 -2
index f699869..09eb80f 100644
@@ -47,13 +47,15 @@ struct pinconf_ops {
 			       unsigned long *config);
 	int (*pin_config_set) (struct pinctrl_dev *pctldev,
 			       unsigned pin,
-			       unsigned long config);
+			       unsigned long *configs,
+			       unsigned num_configs);
 	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
 				     unsigned long *config);
 	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
-				     unsigned long config);
+				     unsigned long *configs,
+				     unsigned num_configs);
 	int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
 					   const char *arg,
 					   unsigned long *config);
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v2 1/1 pinctrl: Pass all configs to driver on pin_config_set()

In reply to Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   95 +++++++++--------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 23 files changed, 889 insertions(+), 673 deletions(-)
drivers/pinctrl/mvebu/pinctrl-mvebu.c +20 -6
index bb7ddb1..e78c041 100644
@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned gid, unsigned long config)
+				unsigned gid, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+	int i, ret;
 
 	if (!grp->ctrl)
 		return -EINVAL;
 
-	if (grp->ctrl->mpp_set)
-		return grp->ctrl->mpp_set(grp->ctrl, config);
+	for (i = 0; i < num_configs; i++) {
+		if (grp->ctrl->mpp_set)
+			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
+		else
+			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
 
-	return mvebu_common_mpp_set(pctl, grp, config);
+		if (ret)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
@@ -303,6 +312,7 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 	struct mvebu_mpp_ctrl_setting *setting;
 	int ret;
+	unsigned long config;
 
 	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 						     func->name);
@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 		return -EINVAL;
 	}
 
-	ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 	if (ret) {
 		dev_err(pctl->dev, "cannot set group %s to %s\n",
 			func->groups[gid], func->name);
@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp;
 	struct mvebu_mpp_ctrl_setting *setting;
+	unsigned long config;
 
 	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 	if (!grp)
@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	if (!setting)
 		return -ENOTSUPP;
 
-	return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+
+	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 }
 
 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drivers/pinctrl/pinconf.c +19 -23

60 lines not on this page · raw message

drivers/pinctrl/pinctrl-abx500.c +102 -85

200 lines not on this page · raw message

drivers/pinctrl/pinctrl-at91.c +29 -19

59 lines not on this page · raw message

drivers/pinctrl/pinctrl-bcm2835.c +25 -18

53 lines not on this page · raw message

drivers/pinctrl/pinctrl-exynos5440.c +61 -52

139 lines not on this page · raw message

drivers/pinctrl/pinctrl-falcon.c +36 -27

82 lines not on this page · raw message

drivers/pinctrl/pinctrl-imx.c +16 -12
index 3a14245..51f3a49 100644
@@ -335,11 +335,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int imx_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+			     unsigned pin_id, unsigned long *configs,
+			     unsigned num_configs)
 {
 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+	int i;
 
 	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
@@ -350,17 +352,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	if (info->flags & SHARE_MUX_CONF_REG) {
-		u32 reg;
-		reg = readl(ipctl->base + pin_reg->conf_reg);
-		reg &= ~0xffff;
-		reg |= config;
-		writel(reg, ipctl->base + pin_reg->conf_reg);
-	} else {
-		writel(config, ipctl->base + pin_reg->conf_reg);
-	}
-	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
-		pin_reg->conf_reg, config);
+	for (i = 0; i < num_configs; i++) {
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->conf_reg);
+			reg &= ~0xffff;
+			reg |= configs[i];
+			writel(reg, ipctl->base + pin_reg->conf_reg);
+		} else {
+			writel(configs[i], ipctl->base + pin_reg->conf_reg);
+		}
+		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+			pin_reg->conf_reg, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-mxs.c +50 -41

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +67 -58

148 lines not on this page · raw message

drivers/pinctrl/pinctrl-rockchip.c +35 -22

67 lines not on this page · raw message

drivers/pinctrl/pinctrl-samsung.c +13 -4
index 439f2ef..222648d 100644
@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin */
 static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long config)
+				unsigned long *configs, unsigned num_configs)
 {
-	return samsung_pinconf_rw(pctldev, pin, &config, true);
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+		if (ret < 0)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 /* get the pin config settings for a specified pin */
@@ -456,7 +464,8 @@ static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin group */
 static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-			unsigned group, unsigned long config)
+			unsigned group, unsigned long *configs,
+			unsigned num_configs)
 {
 	struct samsung_pinctrl_drv_data *drvdata;
 	const unsigned int *pins;
@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 	pins = drvdata->pin_groups[group].pins;
 
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-		samsung_pinconf_set(pctldev, pins[cnt], config);
+		samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
 
 	return 0;
 }
drivers/pinctrl/pinctrl-single.c +22 -11
index 6866548..8f31768 100644
@@ -209,7 +209,7 @@ struct pcs_device {
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
+			   unsigned long *configs, unsigned num_configs);
 
 static enum pin_config_param pcs_bias[] = {
 	PIN_CONFIG_BIAS_PULL_DOWN,
@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
 	int i;
 	for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
 		config = pinconf_to_config_packed(pcs_bias[i], 0);
-		pcs_pinconf_set(pctldev, pin, config);
+		pcs_pinconf_set(pctldev, pin, &config, 1);
 	}
 }
 
@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
-				unsigned pin, unsigned long config)
+				unsigned pin, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pcs_function *func;
 	unsigned offset = 0, shift = 0, i, data, ret;
 	u16 arg;
+	int j;
 
 	ret = pcs_get_function(pctldev, pin, &func);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < func->nconfs; i++) {
-		if (pinconf_to_config_param(config) == func->conf[i].param) {
+	for (j = 0; j < num_configs; j++) {
+		for (i = 0; i < func->nconfs; i++) {
+			if (pinconf_to_config_param(configs[j])
+				!= func->conf[i].param)
+				continue;
+
 			offset = pin * (pcs->width / BITS_PER_BYTE);
 			data = pcs->read(pcs->base + offset);
-			arg = pinconf_to_config_argument(config);
+			arg = pinconf_to_config_argument(configs[j]);
 			switch (func->conf[i].param) {
 			/* 2 parameters */
 			case PIN_CONFIG_INPUT_SCHMITT:
@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				return -ENOTSUPP;
 			}
 			pcs->write(data, pcs->base + offset);
-			return 0;
+
+			break;
 		}
-	}
-	return -ENOTSUPP;
+		if (i >= func->nconfs)
+			return -ENOTSUPP;
+	} /* for each config */
+
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
@@ -695,7 +705,8 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned group, unsigned long config)
+				unsigned group, unsigned long *configs,
+				unsigned num_configs)
 {
 	const unsigned *pins;
 	unsigned npins;
@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 	if (ret)
 		return ret;
 	for (i = 0; i < npins; i++) {
-		if (pcs_pinconf_set(pctldev, pins[i], config))
+		if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs))
 			return -ENOTSUPP;
 	}
 	return 0;
drivers/pinctrl/pinctrl-st.c +7 -4
index 2a10a31..9cadc68 100644
@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
 							config, pin);
 }
 
-static int st_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
 {
 	int pin = st_gpio_pin(pin_id);
 	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+	int i;
 
-	st_pinconf_set_config(pc, pin, config);
-	st_pinconf_set_retime(info, pc, pin, config);
+	for (i = 0; i < num_configs; i++) {
+		st_pinconf_set_config(pc, pin, configs[i]);
+		st_pinconf_set_retime(info, pc, pin, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-sunxi.c +50 -45

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-tegra.c +38 -31

96 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090-pdc.c +78 -57

171 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090.c +80 -60

187 lines not on this page · raw message

drivers/pinctrl/pinctrl-u300.c +10 -8
index 6fbdc06..209a01b 100644
@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
 }
 
 static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			       unsigned long config)
+			       unsigned long *configs, unsigned num_configs)
 {
 	struct pinctrl_gpio_range *range =
 		pinctrl_find_gpio_range_from_pin(pctldev, pin);
-	int ret;
+	int ret, i;
 
 	if (!range)
 		return -EINVAL;
 
-	/* Note: none of these configurations take any argument */
-	ret = u300_gpio_config_set(range->gc,
-				   (pin - range->pin_base + range->base),
-				   pinconf_to_config_param(config));
-	if (ret)
-		return ret;
+	for (i = 0; i < num_configs; i++) {
+		/* Note: none of these configurations take any argument */
+		ret = u300_gpio_config_set(range->gc,
+			(pin - range->pin_base + range->base),
+			pinconf_to_config_param(configs[i]));
+		if (ret)
+			return ret;
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-xway.c +73 -46

147 lines not on this page · raw message

drivers/pinctrl/sh-pfc/pinctrl.c +24 -18

69 lines not on this page · raw message

drivers/pinctrl/vt8500/pinctrl-wmt.c +30 -24

73 lines not on this page · raw message

include/linux/pinctrl/pinconf.h +4 -2
index f699869..09eb80f 100644
@@ -47,13 +47,15 @@ struct pinconf_ops {
 			       unsigned long *config);
 	int (*pin_config_set) (struct pinctrl_dev *pctldev,
 			       unsigned pin,
-			       unsigned long config);
+			       unsigned long *configs,
+			       unsigned num_configs);
 	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
 				     unsigned long *config);
 	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
-				     unsigned long config);
+				     unsigned long *configs,
+				     unsigned num_configs);
 	int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
 					   const char *arg,
 					   unsigned long *config);
Signature · 1 line
1.7.9.5
#6 lore raw
Quoted 9 lines · Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

Quoted 6 lines

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

Didn't you get review from Stephen Warren?

Quoted 28 lines

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   95 +++++++++--------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
Quoted 8 lines
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 23 files changed, 889 insertions(+), 673 deletions(-)

Please try to put all the maintainers for the above files on the To: line so they get a chance to review/ack the patch.

Yours,
Linus Walleij

#7 lore raw

Hi Linus,

Quoted 1 line

Didn't you get review from Stephen Warren?

Yes, just wasn't sure when those tags should be added. They have been added to v3 now.

Quoted 2 lines

Please try to put all the maintainers for the above files on the To: line so they get a chance to review/ack the patch.

Ok. I've added the emails from get_maintainer.pl for each of the files. v3 has been rebased today and I also applied the API changes to pinctrl-palmas.c

Regards,
Sherman

#8 lore raw

PATCH v3 1/1 pinctrl: Pass all configs to driver on pin_config_set()

In reply to Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

  drivers/pinctrl/pinconf.c             |   42 ++++----
  drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
  include/linux/pinctrl/pinconf.h       |    6 +-

On Tegra (Tegra114 Dalmore board, on top of next-20130816),

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c
[v3] rebased on linux-pinctrl.git:devel as of 2013.08.25. Applied API change
to new driver pinctrl-palmas.c. Re build-tested all files.

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-palmas.c      |  134 ++++++++++++-----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   77 +++++++-------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 24 files changed, 952 insertions(+), 726 deletions(-)
drivers/pinctrl/mvebu/pinctrl-mvebu.c +20 -6
index bb7ddb1..e78c041 100644
@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned gid, unsigned long config)
+				unsigned gid, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+	int i, ret;
 
 	if (!grp->ctrl)
 		return -EINVAL;
 
-	if (grp->ctrl->mpp_set)
-		return grp->ctrl->mpp_set(grp->ctrl, config);
+	for (i = 0; i < num_configs; i++) {
+		if (grp->ctrl->mpp_set)
+			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
+		else
+			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
 
-	return mvebu_common_mpp_set(pctl, grp, config);
+		if (ret)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
@@ -303,6 +312,7 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 	struct mvebu_mpp_ctrl_setting *setting;
 	int ret;
+	unsigned long config;
 
 	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 						     func->name);
@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 		return -EINVAL;
 	}
 
-	ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 	if (ret) {
 		dev_err(pctl->dev, "cannot set group %s to %s\n",
 			func->groups[gid], func->name);
@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp;
 	struct mvebu_mpp_ctrl_setting *setting;
+	unsigned long config;
 
 	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 	if (!grp)
@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	if (!setting)
 		return -ENOTSUPP;
 
-	return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+
+	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 }
 
 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drivers/pinctrl/pinconf.c +19 -23

60 lines not on this page · raw message

drivers/pinctrl/pinctrl-abx500.c +102 -85

200 lines not on this page · raw message

drivers/pinctrl/pinctrl-at91.c +29 -19

59 lines not on this page · raw message

drivers/pinctrl/pinctrl-bcm2835.c +25 -18

53 lines not on this page · raw message

drivers/pinctrl/pinctrl-exynos5440.c +61 -52

139 lines not on this page · raw message

drivers/pinctrl/pinctrl-falcon.c +36 -27

82 lines not on this page · raw message

drivers/pinctrl/pinctrl-imx.c +16 -12
index 3602493..d78dd81 100644
@@ -323,11 +323,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int imx_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+			     unsigned pin_id, unsigned long *configs,
+			     unsigned num_configs)
 {
 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+	int i;
 
 	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
@@ -338,17 +340,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	if (info->flags & SHARE_MUX_CONF_REG) {
-		u32 reg;
-		reg = readl(ipctl->base + pin_reg->conf_reg);
-		reg &= ~0xffff;
-		reg |= config;
-		writel(reg, ipctl->base + pin_reg->conf_reg);
-	} else {
-		writel(config, ipctl->base + pin_reg->conf_reg);
-	}
-	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
-		pin_reg->conf_reg, config);
+	for (i = 0; i < num_configs; i++) {
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->conf_reg);
+			reg &= ~0xffff;
+			reg |= configs[i];
+			writel(reg, ipctl->base + pin_reg->conf_reg);
+		} else {
+			writel(configs[i], ipctl->base + pin_reg->conf_reg);
+		}
+		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+			pin_reg->conf_reg, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-mxs.c +50 -41

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +67 -58

148 lines not on this page · raw message

drivers/pinctrl/pinctrl-palmas.c +72 -62

166 lines not on this page · raw message

drivers/pinctrl/pinctrl-rockchip.c +35 -22

67 lines not on this page · raw message

drivers/pinctrl/pinctrl-samsung.c +13 -4
index 439f2ef..222648d 100644
@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin */
 static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long config)
+				unsigned long *configs, unsigned num_configs)
 {
-	return samsung_pinconf_rw(pctldev, pin, &config, true);
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+		if (ret < 0)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 /* get the pin config settings for a specified pin */
@@ -456,7 +464,8 @@ static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin group */
 static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-			unsigned group, unsigned long config)
+			unsigned group, unsigned long *configs,
+			unsigned num_configs)
 {
 	struct samsung_pinctrl_drv_data *drvdata;
 	const unsigned int *pins;
@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 	pins = drvdata->pin_groups[group].pins;
 
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-		samsung_pinconf_set(pctldev, pins[cnt], config);
+		samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
 
 	return 0;
 }
drivers/pinctrl/pinctrl-single.c +22 -11
index 6866548..8f31768 100644
@@ -209,7 +209,7 @@ struct pcs_device {
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
+			   unsigned long *configs, unsigned num_configs);
 
 static enum pin_config_param pcs_bias[] = {
 	PIN_CONFIG_BIAS_PULL_DOWN,
@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
 	int i;
 	for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
 		config = pinconf_to_config_packed(pcs_bias[i], 0);
-		pcs_pinconf_set(pctldev, pin, config);
+		pcs_pinconf_set(pctldev, pin, &config, 1);
 	}
 }
 
@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
-				unsigned pin, unsigned long config)
+				unsigned pin, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pcs_function *func;
 	unsigned offset = 0, shift = 0, i, data, ret;
 	u16 arg;
+	int j;
 
 	ret = pcs_get_function(pctldev, pin, &func);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < func->nconfs; i++) {
-		if (pinconf_to_config_param(config) == func->conf[i].param) {
+	for (j = 0; j < num_configs; j++) {
+		for (i = 0; i < func->nconfs; i++) {
+			if (pinconf_to_config_param(configs[j])
+				!= func->conf[i].param)
+				continue;
+
 			offset = pin * (pcs->width / BITS_PER_BYTE);
 			data = pcs->read(pcs->base + offset);
-			arg = pinconf_to_config_argument(config);
+			arg = pinconf_to_config_argument(configs[j]);
 			switch (func->conf[i].param) {
 			/* 2 parameters */
 			case PIN_CONFIG_INPUT_SCHMITT:
@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				return -ENOTSUPP;
 			}
 			pcs->write(data, pcs->base + offset);
-			return 0;
+
+			break;
 		}
-	}
-	return -ENOTSUPP;
+		if (i >= func->nconfs)
+			return -ENOTSUPP;
+	} /* for each config */
+
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
@@ -695,7 +705,8 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned group, unsigned long config)
+				unsigned group, unsigned long *configs,
+				unsigned num_configs)
 {
 	const unsigned *pins;
 	unsigned npins;
@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 	if (ret)
 		return ret;
 	for (i = 0; i < npins; i++) {
-		if (pcs_pinconf_set(pctldev, pins[i], config))
+		if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs))
 			return -ENOTSUPP;
 	}
 	return 0;
drivers/pinctrl/pinctrl-st.c +7 -4
index 2a10a31..9cadc68 100644
@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
 							config, pin);
 }
 
-static int st_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
 {
 	int pin = st_gpio_pin(pin_id);
 	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+	int i;
 
-	st_pinconf_set_config(pc, pin, config);
-	st_pinconf_set_retime(info, pc, pin, config);
+	for (i = 0; i < num_configs; i++) {
+		st_pinconf_set_config(pc, pin, configs[i]);
+		st_pinconf_set_retime(info, pc, pin, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-sunxi.c +41 -36

91 lines not on this page · raw message

drivers/pinctrl/pinctrl-tegra.c +38 -31

96 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090-pdc.c +78 -57

171 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090.c +80 -60

187 lines not on this page · raw message

drivers/pinctrl/pinctrl-u300.c +10 -8
index 6fbdc06..209a01b 100644
@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
 }
 
 static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			       unsigned long config)
+			       unsigned long *configs, unsigned num_configs)
 {
 	struct pinctrl_gpio_range *range =
 		pinctrl_find_gpio_range_from_pin(pctldev, pin);
-	int ret;
+	int ret, i;
 
 	if (!range)
 		return -EINVAL;
 
-	/* Note: none of these configurations take any argument */
-	ret = u300_gpio_config_set(range->gc,
-				   (pin - range->pin_base + range->base),
-				   pinconf_to_config_param(config));
-	if (ret)
-		return ret;
+	for (i = 0; i < num_configs; i++) {
+		/* Note: none of these configurations take any argument */
+		ret = u300_gpio_config_set(range->gc,
+			(pin - range->pin_base + range->base),
+			pinconf_to_config_param(configs[i]));
+		if (ret)
+			return ret;
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-xway.c +73 -46

147 lines not on this page · raw message

drivers/pinctrl/sh-pfc/pinctrl.c +24 -18

69 lines not on this page · raw message

drivers/pinctrl/vt8500/pinctrl-wmt.c +30 -24

73 lines not on this page · raw message

include/linux/pinctrl/pinconf.h +4 -2
index f699869..09eb80f 100644
@@ -47,13 +47,15 @@ struct pinconf_ops {
 			       unsigned long *config);
 	int (*pin_config_set) (struct pinctrl_dev *pctldev,
 			       unsigned pin,
-			       unsigned long config);
+			       unsigned long *configs,
+			       unsigned num_configs);
 	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
 				     unsigned long *config);
 	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
-				     unsigned long config);
+				     unsigned long *configs,
+				     unsigned num_configs);
 	int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
 					   const char *arg,
 					   unsigned long *config);
Signature · 1 line
1.7.9.5
#9 lore raw

Hi Sherman,

Thank you for the patch.

Quoted 63 lines · On Sunday 25 August 2013 19:41:39 Sherman Yin wrote:

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

  drivers/pinctrl/pinconf.c             |   42 ++++----
  drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
  include/linux/pinctrl/pinconf.h       |    6 +-

On Tegra (Tegra114 Dalmore board, on top of next-20130816),

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and
build-tested pinctrl-sunxi.c
[v3] rebased on linux-pinctrl.git:devel as of 2013.08.25. Applied API
change to new driver pinctrl-palmas.c. Re build-tested all files.

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++--------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-palmas.c      |  134 ++++++++++++-----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   77 +++++++-------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 24 files changed, 952 insertions(+), 726 deletions(-)

[snip]

Quoted 7 lines
(quoted diff) +0 -0

b/drivers/pinctrl/sh-pfc/pinctrl.c index 8649ec3..ced199e 100644

drivers/pinctrl/sh-pfc/pinctrl.c +0 -0
@@ -529,38 +529,44 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev
 *pctldev, unsigned _pin, }
 

drivers/pinctrl/sh-pfc/pinctrl.c static int sh_pfc_pinconf_get(struct pinctrl_dev · line 538

Quoted 10 lines
drivers/pinctrl/sh-pfc/pinctrl.c +3 -2
 static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
-			      unsigned long config)
+			      unsigned long *configs, unsigned num_configs)
 {
 	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
 	struct sh_pfc *pfc = pmx->pfc;
-	enum pin_config_param param = pinconf_to_config_param(config);
+	enum pin_config_param param;
 	unsigned long flags;
+	int i;

Could you please make this an unsigned int ?

Other than that the sh-pfc part looks good to me.

Quoted 40 lines
drivers/pinctrl/sh-pfc/pinctrl.c +18 -14
-	if (!sh_pfc_pinconf_validate(pfc, _pin, param))
-		return -ENOTSUPP;
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
 
-	switch (param) {
-	case PIN_CONFIG_BIAS_PULL_UP:
-	case PIN_CONFIG_BIAS_PULL_DOWN:
-	case PIN_CONFIG_BIAS_DISABLE:
-		if (!pfc->info->ops || !pfc->info->ops->set_bias)
+		if (!sh_pfc_pinconf_validate(pfc, _pin, param))
 			return -ENOTSUPP;
 
-		spin_lock_irqsave(&pfc->lock, flags);
-		pfc->info->ops->set_bias(pfc, _pin, param);
-		spin_unlock_irqrestore(&pfc->lock, flags);
+		switch (param) {
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+		case PIN_CONFIG_BIAS_DISABLE:
+			if (!pfc->info->ops || !pfc->info->ops->set_bias)
+				return -ENOTSUPP;
 
-		break;
+			spin_lock_irqsave(&pfc->lock, flags);
+			pfc->info->ops->set_bias(pfc, _pin, param);
+			spin_unlock_irqrestore(&pfc->lock, flags);
 
-	default:
-		return -ENOTSUPP;
-	}
+			break;
+
+		default:
+			return -ENOTSUPP;
+		}
+	} /* for each config */
 
 	return 0;
 }
Signature · 3 lines
Regards,

Laurent Pinchart
#10 lore raw

Hi Laurent,

Quoted 20 lines
Quoted 7 lines
(quoted diff) +0 -0

b/drivers/pinctrl/sh-pfc/pinctrl.c index 8649ec3..ced199e 100644

drivers/pinctrl/sh-pfc/pinctrl.c +0 -0
@@ -529,38 +529,44 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev
 *pctldev, unsigned _pin, }
 

drivers/pinctrl/sh-pfc/pinctrl.c static int sh_pfc_pinconf_get(struct pinctrl_dev · line 538

Quoted 10 lines
drivers/pinctrl/sh-pfc/pinctrl.c +3 -2
 static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
-			      unsigned long config)
+			      unsigned long *configs, unsigned num_configs)
 {
 	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
 	struct sh_pfc *pfc = pmx->pfc;
-	enum pin_config_param param = pinconf_to_config_param(config);
+	enum pin_config_param param;
 	unsigned long flags;
+	int i;

Could you please make this an unsigned int ?

Quoted 1 line

Other than that the sh-pfc part looks good to me.

Thanks for the review. I'll make this change. Can I add you as a Reviewed-by?

I just realized I didn't include the linux-arm-kernel maillist in my v3 patch, so I'll make this change send out a v4.

Regards,
Sherman

A message that is not in the archive (sent off-list or not yet received): 1377484899-4918-1-git-send-email-syin-dY08KVG/lbpWk0Htik3J/[email protected]

#12 lore raw
Quoted 30 lines · Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

  drivers/pinctrl/pinconf.c             |   42 ++++----
  drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
  include/linux/pinctrl/pinconf.h       |    6 +-

On Tegra (Tegra114 Dalmore board, on top of next-20130816),

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

Quoted 7 lines

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c
[v3] rebased on linux-pinctrl.git:devel as of 2013.08.25. Applied API change
to new driver pinctrl-palmas.c. Re build-tested all files.

OK it appears to work flawlessly on ux500 as well, and with Stephen's Tested-by and Laurent's ACK, there is really no reason for me not to apply this right off. And no reason to prolong this much needed change.

So patch applied for v3.12.

Let's see if something nasty happens in linux-next or this is a go.

Yours,
Linus Walleij

#13 lore raw

PATCH v4 1/1 pinctrl: Pass all configs to driver on pin_config_set()

In reply to Sherman Yin

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

  drivers/pinctrl/pinconf.c             |   42 ++++----
  drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
  include/linux/pinctrl/pinconf.h       |    6 +-

On Tegra (Tegra114 Dalmore board, on top of next-20130816),

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and build-
tested pinctrl-sunxi.c
[v3] rebased on linux-pinctrl.git:devel as of 2013.08.25. Applied API change
to new driver pinctrl-palmas.c. Re build-tested all files.
[v4] Changed int to unsigned int in sh-pfc/pinctrl.c

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++++---------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-palmas.c      |  134 ++++++++++++-----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   77 +++++++-------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 24 files changed, 952 insertions(+), 726 deletions(-)
drivers/pinctrl/mvebu/pinctrl-mvebu.c +20 -6
index bb7ddb1..e78c041 100644
@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned gid, unsigned long config)
+				unsigned gid, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
+	int i, ret;
 
 	if (!grp->ctrl)
 		return -EINVAL;
 
-	if (grp->ctrl->mpp_set)
-		return grp->ctrl->mpp_set(grp->ctrl, config);
+	for (i = 0; i < num_configs; i++) {
+		if (grp->ctrl->mpp_set)
+			ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]);
+		else
+			ret = mvebu_common_mpp_set(pctl, grp, configs[i]);
 
-	return mvebu_common_mpp_set(pctl, grp, config);
+		if (ret)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
@@ -303,6 +312,7 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 	struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
 	struct mvebu_mpp_ctrl_setting *setting;
 	int ret;
+	unsigned long config;
 
 	setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
 						     func->name);
@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
 		return -EINVAL;
 	}
 
-	ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+	ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 	if (ret) {
 		dev_err(pctl->dev, "cannot set group %s to %s\n",
 			func->groups[gid], func->name);
@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	struct mvebu_pinctrl_group *grp;
 	struct mvebu_mpp_ctrl_setting *setting;
+	unsigned long config;
 
 	grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
 	if (!grp)
@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 	if (!setting)
 		return -ENOTSUPP;
 
-	return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val);
+	config = setting->val;
+
+	return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1);
 }
 
 static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
drivers/pinctrl/pinconf.c +19 -23

60 lines not on this page · raw message

drivers/pinctrl/pinctrl-abx500.c +102 -85

200 lines not on this page · raw message

drivers/pinctrl/pinctrl-at91.c +29 -19

59 lines not on this page · raw message

drivers/pinctrl/pinctrl-bcm2835.c +25 -18

53 lines not on this page · raw message

drivers/pinctrl/pinctrl-exynos5440.c +61 -52

139 lines not on this page · raw message

drivers/pinctrl/pinctrl-falcon.c +36 -27

82 lines not on this page · raw message

drivers/pinctrl/pinctrl-imx.c +16 -12
index 3602493..d78dd81 100644
@@ -323,11 +323,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int imx_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+			     unsigned pin_id, unsigned long *configs,
+			     unsigned num_configs)
 {
 	struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
 	const struct imx_pinctrl_soc_info *info = ipctl->info;
 	const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
+	int i;
 
 	if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
 		dev_err(info->dev, "Pin(%s) does not support config function\n",
@@ -338,17 +340,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
 	dev_dbg(ipctl->dev, "pinconf set pin %s\n",
 		info->pins[pin_id].name);
 
-	if (info->flags & SHARE_MUX_CONF_REG) {
-		u32 reg;
-		reg = readl(ipctl->base + pin_reg->conf_reg);
-		reg &= ~0xffff;
-		reg |= config;
-		writel(reg, ipctl->base + pin_reg->conf_reg);
-	} else {
-		writel(config, ipctl->base + pin_reg->conf_reg);
-	}
-	dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
-		pin_reg->conf_reg, config);
+	for (i = 0; i < num_configs; i++) {
+		if (info->flags & SHARE_MUX_CONF_REG) {
+			u32 reg;
+			reg = readl(ipctl->base + pin_reg->conf_reg);
+			reg &= ~0xffff;
+			reg |= configs[i];
+			writel(reg, ipctl->base + pin_reg->conf_reg);
+		} else {
+			writel(configs[i], ipctl->base + pin_reg->conf_reg);
+		}
+		dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
+			pin_reg->conf_reg, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-mxs.c +50 -41

113 lines not on this page · raw message

drivers/pinctrl/pinctrl-nomadik.c +67 -58

148 lines not on this page · raw message

drivers/pinctrl/pinctrl-palmas.c +72 -62

166 lines not on this page · raw message

drivers/pinctrl/pinctrl-rockchip.c +35 -22

67 lines not on this page · raw message

drivers/pinctrl/pinctrl-samsung.c +13 -4
index 439f2ef..222648d 100644
@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin */
 static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-				unsigned long config)
+				unsigned long *configs, unsigned num_configs)
 {
-	return samsung_pinconf_rw(pctldev, pin, &config, true);
+	int i, ret;
+
+	for (i = 0; i < num_configs; i++) {
+		ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);
+		if (ret < 0)
+			return ret;
+	} /* for each config */
+
+	return 0;
 }
 
 /* get the pin config settings for a specified pin */
@@ -456,7 +464,8 @@ static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
 
 /* set the pin config settings for a specified pin group */
 static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
-			unsigned group, unsigned long config)
+			unsigned group, unsigned long *configs,
+			unsigned num_configs)
 {
 	struct samsung_pinctrl_drv_data *drvdata;
 	const unsigned int *pins;
@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
 	pins = drvdata->pin_groups[group].pins;
 
 	for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
-		samsung_pinconf_set(pctldev, pins[cnt], config);
+		samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);
 
 	return 0;
 }
drivers/pinctrl/pinctrl-single.c +22 -11
index 6866548..8f31768 100644
@@ -209,7 +209,7 @@ struct pcs_device {
 static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
 			   unsigned long *config);
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
-			   unsigned long config);
+			   unsigned long *configs, unsigned num_configs);
 
 static enum pin_config_param pcs_bias[] = {
 	PIN_CONFIG_BIAS_PULL_DOWN,
@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
 	int i;
 	for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
 		config = pinconf_to_config_packed(pcs_bias[i], 0);
-		pcs_pinconf_set(pctldev, pin, config);
+		pcs_pinconf_set(pctldev, pin, &config, 1);
 	}
 }
 
@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
-				unsigned pin, unsigned long config)
+				unsigned pin, unsigned long *configs,
+				unsigned num_configs)
 {
 	struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev);
 	struct pcs_function *func;
 	unsigned offset = 0, shift = 0, i, data, ret;
 	u16 arg;
+	int j;
 
 	ret = pcs_get_function(pctldev, pin, &func);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < func->nconfs; i++) {
-		if (pinconf_to_config_param(config) == func->conf[i].param) {
+	for (j = 0; j < num_configs; j++) {
+		for (i = 0; i < func->nconfs; i++) {
+			if (pinconf_to_config_param(configs[j])
+				!= func->conf[i].param)
+				continue;
+
 			offset = pin * (pcs->width / BITS_PER_BYTE);
 			data = pcs->read(pcs->base + offset);
-			arg = pinconf_to_config_argument(config);
+			arg = pinconf_to_config_argument(configs[j]);
 			switch (func->conf[i].param) {
 			/* 2 parameters */
 			case PIN_CONFIG_INPUT_SCHMITT:
@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
 				return -ENOTSUPP;
 			}
 			pcs->write(data, pcs->base + offset);
-			return 0;
+
+			break;
 		}
-	}
-	return -ENOTSUPP;
+		if (i >= func->nconfs)
+			return -ENOTSUPP;
+	} /* for each config */
+
+	return 0;
 }
 
 static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
@@ -695,7 +705,8 @@ static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
 }
 
 static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
-				unsigned group, unsigned long config)
+				unsigned group, unsigned long *configs,
+				unsigned num_configs)
 {
 	const unsigned *pins;
 	unsigned npins;
@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
 	if (ret)
 		return ret;
 	for (i = 0; i < npins; i++) {
-		if (pcs_pinconf_set(pctldev, pins[i], config))
+		if (pcs_pinconf_set(pctldev, pins[i], configs, num_configs))
 			return -ENOTSUPP;
 	}
 	return 0;
drivers/pinctrl/pinctrl-st.c +7 -4
index 2a10a31..9cadc68 100644
@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
 							config, pin);
 }
 
-static int st_pinconf_set(struct pinctrl_dev *pctldev,
-			     unsigned pin_id, unsigned long config)
+static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
+			unsigned long *configs, unsigned num_configs)
 {
 	int pin = st_gpio_pin(pin_id);
 	struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
 	struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
+	int i;
 
-	st_pinconf_set_config(pc, pin, config);
-	st_pinconf_set_retime(info, pc, pin, config);
+	for (i = 0; i < num_configs; i++) {
+		st_pinconf_set_config(pc, pin, configs[i]);
+		st_pinconf_set_retime(info, pc, pin, configs[i]);
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-sunxi.c +41 -36

91 lines not on this page · raw message

drivers/pinctrl/pinctrl-tegra.c +38 -31

96 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090-pdc.c +78 -57

171 lines not on this page · raw message

drivers/pinctrl/pinctrl-tz1090.c +80 -60

187 lines not on this page · raw message

drivers/pinctrl/pinctrl-u300.c +10 -8
index 6fbdc06..209a01b 100644
@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
 }
 
 static int u300_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
-			       unsigned long config)
+			       unsigned long *configs, unsigned num_configs)
 {
 	struct pinctrl_gpio_range *range =
 		pinctrl_find_gpio_range_from_pin(pctldev, pin);
-	int ret;
+	int ret, i;
 
 	if (!range)
 		return -EINVAL;
 
-	/* Note: none of these configurations take any argument */
-	ret = u300_gpio_config_set(range->gc,
-				   (pin - range->pin_base + range->base),
-				   pinconf_to_config_param(config));
-	if (ret)
-		return ret;
+	for (i = 0; i < num_configs; i++) {
+		/* Note: none of these configurations take any argument */
+		ret = u300_gpio_config_set(range->gc,
+			(pin - range->pin_base + range->base),
+			pinconf_to_config_param(configs[i]));
+		if (ret)
+			return ret;
+	} /* for each config */
 
 	return 0;
 }
drivers/pinctrl/pinctrl-xway.c +73 -46

147 lines not on this page · raw message

drivers/pinctrl/sh-pfc/pinctrl.c +24 -18

69 lines not on this page · raw message

drivers/pinctrl/vt8500/pinctrl-wmt.c +30 -24

73 lines not on this page · raw message

include/linux/pinctrl/pinconf.h +4 -2
index f699869..09eb80f 100644
@@ -47,13 +47,15 @@ struct pinconf_ops {
 			       unsigned long *config);
 	int (*pin_config_set) (struct pinctrl_dev *pctldev,
 			       unsigned pin,
-			       unsigned long config);
+			       unsigned long *configs,
+			       unsigned num_configs);
 	int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
 				     unsigned long *config);
 	int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
 				     unsigned selector,
-				     unsigned long config);
+				     unsigned long *configs,
+				     unsigned num_configs);
 	int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
 					   const char *arg,
 					   unsigned long *config);
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH v4 1/1 pinctrl: Pass all configs to driver on pin_config_set()

Quoted 16 lines · On Tuesday 27 August 2013 11:32:12 Sherman Yin wrote:

When setting pin configuration in the pinctrl framework, pin_config_set() or pin_config_group_set() is called in a loop to set one configuration at a time for the specified pin or group.

This patch 1) removes the loop and 2) changes the API to pass the whole pin config array to the driver. It is now up to the driver to loop through the configs. This allows the driver to potentially combine configs and reduce the number of writes to pin config registers.

All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated.

Quoted 7 lines
  drivers/pinctrl/pinconf.c             |   42 ++++----
  drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
  include/linux/pinctrl/pinconf.h       |    6 +-

On Tegra (Tegra114 Dalmore board, on top of next-20130816),

For drivers/pinctrl/sh-pfc/pinctrl.c,

Quoted 40 lines

---
Please refer to the discussion with Linus W. "[PATCH] ARM: Adds pin config API to set all configs in one function" here:

http://lists.infradead.org/pipermail/linux-arm-kernel/2013-May/166567.html

All c files changed have been build-tested to verify the change compiles and that the corresponding .o are successfully generated.

[v2] rebased on LinusW's linux-pinctrl.git "devel" branch. Fixed and
build-tested pinctrl-sunxi.c
[v3] rebased on linux-pinctrl.git:devel as of 2013.08.25. Applied API
change to new driver pinctrl-palmas.c. Re build-tested all files.
[v4] Changed int to unsigned int in sh-pfc/pinctrl.c

---
 drivers/pinctrl/mvebu/pinctrl-mvebu.c |   26 +++--
 drivers/pinctrl/pinconf.c             |   42 ++++----
 drivers/pinctrl/pinctrl-abx500.c      |  187 ++++++++++++++++--------------
 drivers/pinctrl/pinctrl-at91.c        |   48 +++++----
 drivers/pinctrl/pinctrl-bcm2835.c     |   43 ++++----
 drivers/pinctrl/pinctrl-exynos5440.c  |  113 +++++++++++---------
 drivers/pinctrl/pinctrl-falcon.c      |   63 ++++++-----
 drivers/pinctrl/pinctrl-imx.c         |   28 ++---
 drivers/pinctrl/pinctrl-mxs.c         |   91 ++++++++--------
 drivers/pinctrl/pinctrl-nomadik.c     |  125 ++++++++++++----------
 drivers/pinctrl/pinctrl-palmas.c      |  134 ++++++++++++-----------
 drivers/pinctrl/pinctrl-rockchip.c    |   57 ++++++----
 drivers/pinctrl/pinctrl-samsung.c     |   17 ++-
 drivers/pinctrl/pinctrl-single.c      |   33 ++++--
 drivers/pinctrl/pinctrl-st.c          |   11 +-
 drivers/pinctrl/pinctrl-sunxi.c       |   77 +++++++-------
 drivers/pinctrl/pinctrl-tegra.c       |   69 ++++++------
 drivers/pinctrl/pinctrl-tz1090-pdc.c  |  135 ++++++++++++++----------
 drivers/pinctrl/pinctrl-tz1090.c      |  140 +++++++++++++-----------
 drivers/pinctrl/pinctrl-u300.c        |   18 ++--
 drivers/pinctrl/pinctrl-xway.c        |  119 +++++++++++++--------
 drivers/pinctrl/sh-pfc/pinctrl.c      |   42 ++++----
 drivers/pinctrl/vt8500/pinctrl-wmt.c  |   54 +++++-----
 include/linux/pinctrl/pinconf.h       |    6 +-
 24 files changed, 952 insertions(+), 726 deletions(-)

[snip]

Quoted 75 lines
(quoted diff) +0 -0

b/drivers/pinctrl/sh-pfc/pinctrl.c index 8649ec3..e758af9 100644

drivers/pinctrl/sh-pfc/pinctrl.c +24 -17
@@ -529,38 +529,44 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev
 *pctldev, unsigned _pin, }
 
 static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
-			      unsigned long config)
+			      unsigned long *configs, unsigned num_configs)
 {
 	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
 	struct sh_pfc *pfc = pmx->pfc;
-	enum pin_config_param param = pinconf_to_config_param(config);
+	enum pin_config_param param;
 	unsigned long flags;
+	unsigned int i;
 
-	if (!sh_pfc_pinconf_validate(pfc, _pin, param))
-		return -ENOTSUPP;
+	for (i = 0; i < num_configs; i++) {
+		param = pinconf_to_config_param(configs[i]);
 
-	switch (param) {
-	case PIN_CONFIG_BIAS_PULL_UP:
-	case PIN_CONFIG_BIAS_PULL_DOWN:
-	case PIN_CONFIG_BIAS_DISABLE:
-		if (!pfc->info->ops || !pfc->info->ops->set_bias)
+		if (!sh_pfc_pinconf_validate(pfc, _pin, param))
 			return -ENOTSUPP;
 
-		spin_lock_irqsave(&pfc->lock, flags);
-		pfc->info->ops->set_bias(pfc, _pin, param);
-		spin_unlock_irqrestore(&pfc->lock, flags);
+		switch (param) {
+		case PIN_CONFIG_BIAS_PULL_UP:
+		case PIN_CONFIG_BIAS_PULL_DOWN:
+		case PIN_CONFIG_BIAS_DISABLE:
+			if (!pfc->info->ops || !pfc->info->ops->set_bias)
+				return -ENOTSUPP;
 
-		break;
+			spin_lock_irqsave(&pfc->lock, flags);
+			pfc->info->ops->set_bias(pfc, _pin, param);
+			spin_unlock_irqrestore(&pfc->lock, flags);
 
-	default:
-		return -ENOTSUPP;
-	}
+			break;
+
+		default:
+			return -ENOTSUPP;
+		}
+	} /* for each config */
 
 	return 0;
 }
 
 static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned
 group, -				    unsigned long config)
+				    unsigned long *configs,
+				    unsigned num_configs)
 {
 	struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
 	const unsigned int *pins;
@@ -571,7 +577,7 @@ static int sh_pfc_pinconf_group_set(struct pinctrl_dev
 *pctldev, unsigned group, num_pins = pmx->pfc->info->groups[group].nr_pins;
 
 	for (i = 0; i < num_pins; ++i)
-		sh_pfc_pinconf_set(pctldev, pins[i], config);
+		sh_pfc_pinconf_set(pctldev, pins[i], configs, num_configs);
 
 	return 0;
 }
Signature · 3 lines
Regards,

Laurent Pinchart