summaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-exynos5440.c
diff options
context:
space:
mode:
authorSherman Yin <syin@broadcom.com>2013-08-27 11:32:12 -0700
committerLinus Walleij <linus.walleij@linaro.org>2013-08-28 13:34:41 +0200
commit03b054e9696c3cbd3d5905ec96da15acd0a2fe8d (patch)
tree7123b780c194d350b3e5134c267e17262effb385 /drivers/pinctrl/pinctrl-exynos5440.c
parentf5ba9c52bf1e236c4698c240955e5f119db62a28 (diff)
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. All c files changed have been build-tested to verify the change compiles and that the corresponding .o is successfully generated. Signed-off-by: Sherman Yin <syin@broadcom.com> Reviewed-by: Christian Daudt <csd@broadcom.com> Reviewed-by: Matt Porter <matt.porter@linaro.org> Tested-by: Stephen Warren <swarren@nvidia.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/pinctrl-exynos5440.c')
-rw-r--r--drivers/pinctrl/pinctrl-exynos5440.c113
1 files changed, 61 insertions, 52 deletions
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c
index 3b283fd898ff..544d469c5a7b 100644
--- a/drivers/pinctrl/pinctrl-exynos5440.c
+++ b/drivers/pinctrl/pinctrl-exynos5440.c
@@ -401,64 +401,71 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
/* set the pin config settings for a specified pin */
static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
- unsigned long config)
+ unsigned long *configs,
+ unsigned num_configs)
{
struct exynos5440_pinctrl_priv_data *priv;
void __iomem *base;
- enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(config);
- u32 cfg_value = PINCFG_UNPACK_VALUE(config);
+ enum pincfg_type cfg_type;
+ u32 cfg_value;
u32 data;
+ int i;
priv = pinctrl_dev_get_drvdata(pctldev);
base = priv->reg_base;
- switch (cfg_type) {
- case PINCFG_TYPE_PUD:
- /* first set pull enable/disable bit */
- data = readl(base + GPIO_PE);
- data &= ~(1 << pin);
- if (cfg_value)
- data |= (1 << pin);
- writel(data, base + GPIO_PE);
-
- /* then set pull up/down bit */
- data = readl(base + GPIO_PS);
- data &= ~(1 << pin);
- if (cfg_value == 2)
- data |= (1 << pin);
- writel(data, base + GPIO_PS);
- break;
-
- case PINCFG_TYPE_DRV:
- /* set the first bit of the drive strength */
- data = readl(base + GPIO_DS0);
- data &= ~(1 << pin);
- data |= ((cfg_value & 1) << pin);
- writel(data, base + GPIO_DS0);
- cfg_value >>= 1;
-
- /* set the second bit of the driver strength */
- data = readl(base + GPIO_DS1);
- data &= ~(1 << pin);
- data |= ((cfg_value & 1) << pin);
- writel(data, base + GPIO_DS1);
- break;
- case PINCFG_TYPE_SKEW_RATE:
- data = readl(base + GPIO_SR);
- data &= ~(1 << pin);
- data |= ((cfg_value & 1) << pin);
- writel(data, base + GPIO_SR);
- break;
- case PINCFG_TYPE_INPUT_TYPE:
- data = readl(base + GPIO_TYPE);
- data &= ~(1 << pin);
- data |= ((cfg_value & 1) << pin);
- writel(data, base + GPIO_TYPE);
- break;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
+ for (i = 0; i < num_configs; i++) {
+ cfg_type = PINCFG_UNPACK_TYPE(configs[i]);
+ cfg_value = PINCFG_UNPACK_VALUE(configs[i]);
+
+ switch (cfg_type) {
+ case PINCFG_TYPE_PUD:
+ /* first set pull enable/disable bit */
+ data = readl(base + GPIO_PE);
+ data &= ~(1 << pin);
+ if (cfg_value)
+ data |= (1 << pin);
+ writel(data, base + GPIO_PE);
+
+ /* then set pull up/down bit */
+ data = readl(base + GPIO_PS);
+ data &= ~(1 << pin);
+ if (cfg_value == 2)
+ data |= (1 << pin);
+ writel(data, base + GPIO_PS);
+ break;
+
+ case PINCFG_TYPE_DRV:
+ /* set the first bit of the drive strength */
+ data = readl(base + GPIO_DS0);
+ data &= ~(1 << pin);
+ data |= ((cfg_value & 1) << pin);
+ writel(data, base + GPIO_DS0);
+ cfg_value >>= 1;
+
+ /* set the second bit of the driver strength */
+ data = readl(base + GPIO_DS1);
+ data &= ~(1 << pin);
+ data |= ((cfg_value & 1) << pin);
+ writel(data, base + GPIO_DS1);
+ break;
+ case PINCFG_TYPE_SKEW_RATE:
+ data = readl(base + GPIO_SR);
+ data &= ~(1 << pin);
+ data |= ((cfg_value & 1) << pin);
+ writel(data, base + GPIO_SR);
+ break;
+ case PINCFG_TYPE_INPUT_TYPE:
+ data = readl(base + GPIO_TYPE);
+ data &= ~(1 << pin);
+ data |= ((cfg_value & 1) << pin);
+ writel(data, base + GPIO_TYPE);
+ break;
+ default:
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ } /* for each config */
return 0;
}
@@ -510,7 +517,8 @@ static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
/* set the pin config settings for a specified pin group */
static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
- unsigned group, unsigned long config)
+ unsigned group, unsigned long *configs,
+ unsigned num_configs)
{
struct exynos5440_pinctrl_priv_data *priv;
const unsigned int *pins;
@@ -520,7 +528,8 @@ static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
pins = priv->pin_groups[group].pins;
for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++)
- exynos5440_pinconf_set(pctldev, pins[cnt], config);
+ exynos5440_pinconf_set(pctldev, pins[cnt], configs,
+ num_configs);
return 0;
}