Commit 03b054e9 authored by Sherman Yin's avatar Sherman Yin Committed by Linus Walleij

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: default avatarSherman Yin <syin@broadcom.com>
Reviewed-by: default avatarChristian Daudt <csd@broadcom.com>
Reviewed-by: default avatarMatt Porter <matt.porter@linaro.org>
Tested-by: default avatarStephen Warren <swarren@nvidia.com>
Acked-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent f5ba9c52
...@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev,
} }
static int mvebu_pinconf_group_set(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 *pctl = pinctrl_dev_get_drvdata(pctldev);
struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; struct mvebu_pinctrl_group *grp = &pctl->groups[gid];
int i, ret;
if (!grp->ctrl) if (!grp->ctrl)
return -EINVAL; return -EINVAL;
for (i = 0; i < num_configs; i++) {
if (grp->ctrl->mpp_set) if (grp->ctrl->mpp_set)
return grp->ctrl->mpp_set(grp->ctrl, config); 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, 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, ...@@ -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_pinctrl_group *grp = &pctl->groups[gid];
struct mvebu_mpp_ctrl_setting *setting; struct mvebu_mpp_ctrl_setting *setting;
int ret; int ret;
unsigned long config;
setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, setting = mvebu_pinctrl_find_setting_by_name(pctl, grp,
func->name); func->name);
...@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid, ...@@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid,
return -EINVAL; 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) { if (ret) {
dev_err(pctl->dev, "cannot set group %s to %s\n", dev_err(pctl->dev, "cannot set group %s to %s\n",
func->groups[gid], func->name); func->groups[gid], func->name);
...@@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, ...@@ -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 *pctl = pinctrl_dev_get_drvdata(pctldev);
struct mvebu_pinctrl_group *grp; struct mvebu_pinctrl_group *grp;
struct mvebu_mpp_ctrl_setting *setting; struct mvebu_mpp_ctrl_setting *setting;
unsigned long config;
grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); grp = mvebu_pinctrl_find_group_by_pid(pctl, offset);
if (!grp) if (!grp)
...@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, ...@@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
if (!setting) if (!setting)
return -ENOTSUPP; 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, static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
......
...@@ -158,7 +158,7 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) ...@@ -158,7 +158,7 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
{ {
struct pinctrl_dev *pctldev = setting->pctldev; struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinconf_ops *ops = pctldev->desc->confops; const struct pinconf_ops *ops = pctldev->desc->confops;
int i, ret; int ret;
if (!ops) { if (!ops) {
dev_err(pctldev->dev, "missing confops\n"); dev_err(pctldev->dev, "missing confops\n");
...@@ -171,18 +171,16 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) ...@@ -171,18 +171,16 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
dev_err(pctldev->dev, "missing pin_config_set op\n"); dev_err(pctldev->dev, "missing pin_config_set op\n");
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_set(pctldev, ret = ops->pin_config_set(pctldev,
setting->data.configs.group_or_pin, setting->data.configs.group_or_pin,
setting->data.configs.configs[i]); setting->data.configs.configs,
setting->data.configs.num_configs);
if (ret < 0) { if (ret < 0) {
dev_err(pctldev->dev, dev_err(pctldev->dev,
"pin_config_set op failed for pin %d config %08lx\n", "pin_config_set op failed for pin %d\n",
setting->data.configs.group_or_pin, setting->data.configs.group_or_pin);
setting->data.configs.configs[i]);
return ret; return ret;
} }
}
break; break;
case PIN_MAP_TYPE_CONFIGS_GROUP: case PIN_MAP_TYPE_CONFIGS_GROUP:
if (!ops->pin_config_group_set) { if (!ops->pin_config_group_set) {
...@@ -190,18 +188,16 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) ...@@ -190,18 +188,16 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
"missing pin_config_group_set op\n"); "missing pin_config_group_set op\n");
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_group_set(pctldev, ret = ops->pin_config_group_set(pctldev,
setting->data.configs.group_or_pin, setting->data.configs.group_or_pin,
setting->data.configs.configs[i]); setting->data.configs.configs,
setting->data.configs.num_configs);
if (ret < 0) { if (ret < 0) {
dev_err(pctldev->dev, dev_err(pctldev->dev,
"pin_config_group_set op failed for group %d config %08lx\n", "pin_config_group_set op failed for group %d\n",
setting->data.configs.group_or_pin, setting->data.configs.group_or_pin);
setting->data.configs.configs[i]);
return ret; return ret;
} }
}
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -1041,18 +1041,26 @@ static int abx500_pin_config_get(struct pinctrl_dev *pctldev, ...@@ -1041,18 +1041,26 @@ static int abx500_pin_config_get(struct pinctrl_dev *pctldev,
static int abx500_pin_config_set(struct pinctrl_dev *pctldev, static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned pin,
unsigned long config) unsigned long *configs,
unsigned num_configs)
{ {
struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev); struct abx500_pinctrl *pct = pinctrl_dev_get_drvdata(pctldev);
struct gpio_chip *chip = &pct->chip; struct gpio_chip *chip = &pct->chip;
unsigned offset; unsigned offset;
int ret = -EINVAL; int ret = -EINVAL;
enum pin_config_param param = pinconf_to_config_param(config); int i;
enum pin_config_param argument = pinconf_to_config_argument(config); enum pin_config_param param;
enum pin_config_param argument;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
argument = pinconf_to_config_argument(configs[i]);
dev_dbg(chip->dev, "pin %d [%#lx]: %s %s\n", dev_dbg(chip->dev, "pin %d [%#lx]: %s %s\n",
pin, config, (param == PIN_CONFIG_OUTPUT) ? "output " : "input", pin, configs[i],
(param == PIN_CONFIG_OUTPUT) ? (argument ? "high" : "low") : (param == PIN_CONFIG_OUTPUT) ? "output " : "input",
(param == PIN_CONFIG_OUTPUT) ?
(argument ? "high" : "low") :
(argument ? "pull up" : "pull down")); (argument ? "pull up" : "pull down"));
/* on ABx500, there is no GPIO0, so adjust the offset */ /* on ABx500, there is no GPIO0, so adjust the offset */
...@@ -1064,11 +1072,12 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, ...@@ -1064,11 +1072,12 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
if (ret < 0) if (ret < 0)
goto out; goto out;
/* /*
* Some chips only support pull down, while some actually * Some chips only support pull down, while some
* support both pull up and pull down. Such chips have * actually support both pull up and pull down. Such
* a "pullud" range specified for the pins that support * chips have a "pullud" range specified for the pins
* both features. If the pin is not within that range, we * that support both features. If the pin is not
* fall back to the old bit set that only support pull down. * within that range, we fall back to the old bit set
* that only support pull down.
*/ */
if (abx500_pullud_supported(chip, pin)) if (abx500_pullud_supported(chip, pin))
ret = abx500_set_pull_updown(pct, ret = abx500_set_pull_updown(pct,
...@@ -1076,8 +1085,9 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, ...@@ -1076,8 +1085,9 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
ABX500_GPIO_PULL_NONE); ABX500_GPIO_PULL_NONE);
else else
/* Chip only supports pull down */ /* Chip only supports pull down */
ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, ret = abx500_gpio_set_bits(chip,
offset, ABX500_GPIO_PULL_NONE); AB8500_GPIO_PUD1_REG, offset,
ABX500_GPIO_PULL_NONE);
break; break;
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
...@@ -1087,21 +1097,25 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, ...@@ -1087,21 +1097,25 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
/* /*
* if argument = 1 set the pull down * if argument = 1 set the pull down
* else clear the pull down * else clear the pull down
* Some chips only support pull down, while some actually * Some chips only support pull down, while some
* support both pull up and pull down. Such chips have * actually support both pull up and pull down. Such
* a "pullud" range specified for the pins that support * chips have a "pullud" range specified for the pins
* both features. If the pin is not within that range, we * that support both features. If the pin is not
* fall back to the old bit set that only support pull down. * within that range, we fall back to the old bit set
* that only support pull down.
*/ */
if (abx500_pullud_supported(chip, pin)) if (abx500_pullud_supported(chip, pin))
ret = abx500_set_pull_updown(pct, ret = abx500_set_pull_updown(pct,
pin, pin,
argument ? ABX500_GPIO_PULL_DOWN : ABX500_GPIO_PULL_NONE); argument ? ABX500_GPIO_PULL_DOWN :
ABX500_GPIO_PULL_NONE);
else else
/* Chip only supports pull down */ /* Chip only supports pull down */
ret = abx500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, ret = abx500_gpio_set_bits(chip,
AB8500_GPIO_PUD1_REG,
offset, offset,
argument ? ABX500_GPIO_PULL_DOWN : ABX500_GPIO_PULL_NONE); argument ? ABX500_GPIO_PULL_DOWN :
ABX500_GPIO_PULL_NONE);
break; break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
...@@ -1114,25 +1128,28 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev, ...@@ -1114,25 +1128,28 @@ static int abx500_pin_config_set(struct pinctrl_dev *pctldev,
*/ */
ret = abx500_gpio_direction_input(chip, offset); ret = abx500_gpio_direction_input(chip, offset);
/* /*
* Some chips only support pull down, while some actually * Some chips only support pull down, while some
* support both pull up and pull down. Such chips have * actually support both pull up and pull down. Such
* a "pullud" range specified for the pins that support * chips have a "pullud" range specified for the pins
* both features. If the pin is not within that range, do * that support both features. If the pin is not
* nothing * within that range, do nothing
*/ */
if (abx500_pullud_supported(chip, pin)) if (abx500_pullud_supported(chip, pin))
ret = abx500_set_pull_updown(pct, ret = abx500_set_pull_updown(pct,
pin, pin,
argument ? ABX500_GPIO_PULL_UP : ABX500_GPIO_PULL_NONE); argument ? ABX500_GPIO_PULL_UP :
ABX500_GPIO_PULL_NONE);
break; break;
case PIN_CONFIG_OUTPUT: case PIN_CONFIG_OUTPUT:
ret = abx500_gpio_direction_output(chip, offset, argument); ret = abx500_gpio_direction_output(chip, offset,
argument);
break; break;
default: default:
dev_err(chip->dev, "illegal configuration requested\n"); dev_err(chip->dev, "illegal configuration requested\n");
} }
} /* for each config */
out: out:
if (ret < 0) if (ret < 0)
dev_err(pct->dev, "%s failed (%d)\n", __func__, ret); dev_err(pct->dev, "%s failed (%d)\n", __func__, ret);
......
...@@ -736,13 +736,21 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -736,13 +736,21 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int at91_pinconf_set(struct pinctrl_dev *pctldev, static int at91_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin_id, unsigned long config) unsigned pin_id, unsigned long *configs,
unsigned num_configs)
{ {
struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct at91_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
unsigned mask; unsigned mask;
void __iomem *pio; void __iomem *pio;
int i;
unsigned long config;
for (i = 0; i < num_configs; i++) {
config = configs[i];
dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, __LINE__, pin_id, config); dev_dbg(info->dev,
"%s:%d, pin_id=%d, config=0x%lx",
__func__, __LINE__, pin_id, config);
pio = pin_to_controller(info, pin_to_bank(pin_id)); pio = pin_to_controller(info, pin_to_bank(pin_id));
mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK); mask = pin_to_mask(pin_id % MAX_NB_GPIO_PER_BANK);
...@@ -761,6 +769,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -761,6 +769,8 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT) if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
info->ops->disable_schmitt_trig(pio, mask); info->ops->disable_schmitt_trig(pio, mask);
} /* for each config */
return 0; return 0;
} }
......
...@@ -893,12 +893,18 @@ static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -893,12 +893,18 @@ static int bcm2835_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config) unsigned pin, unsigned long *configs,
unsigned num_configs)
{ {
struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); struct bcm2835_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
enum bcm2835_pinconf_param param = BCM2835_PINCONF_UNPACK_PARAM(config); enum bcm2835_pinconf_param param;
u16 arg = BCM2835_PINCONF_UNPACK_ARG(config); u16 arg;
u32 off, bit; u32 off, bit;
int i;
for (i = 0; i < num_configs; i++) {
param = BCM2835_PINCONF_UNPACK_PARAM(configs[i]);
arg = BCM2835_PINCONF_UNPACK_ARG(configs[i]);
if (param != BCM2835_PINCONF_PARAM_PULL) if (param != BCM2835_PINCONF_PARAM_PULL)
return -EINVAL; return -EINVAL;
...@@ -915,6 +921,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -915,6 +921,7 @@ static int bcm2835_pinconf_set(struct pinctrl_dev *pctldev,
bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit)); bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), BIT(bit));
udelay(150); udelay(150);
bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0); bcm2835_gpio_wr(pc, GPPUDCLK0 + (off * 4), 0);
} /* for each config */
return 0; return 0;
} }
......
...@@ -401,17 +401,23 @@ static const struct pinmux_ops exynos5440_pinmux_ops = { ...@@ -401,17 +401,23 @@ static const struct pinmux_ops exynos5440_pinmux_ops = {
/* set the pin config settings for a specified pin */ /* set the pin config settings for a specified pin */
static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int 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; struct exynos5440_pinctrl_priv_data *priv;
void __iomem *base; void __iomem *base;
enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(config); enum pincfg_type cfg_type;
u32 cfg_value = PINCFG_UNPACK_VALUE(config); u32 cfg_value;
u32 data; u32 data;
int i;
priv = pinctrl_dev_get_drvdata(pctldev); priv = pinctrl_dev_get_drvdata(pctldev);
base = priv->reg_base; base = priv->reg_base;
for (i = 0; i < num_configs; i++) {
cfg_type = PINCFG_UNPACK_TYPE(configs[i]);
cfg_value = PINCFG_UNPACK_VALUE(configs[i]);
switch (cfg_type) { switch (cfg_type) {
case PINCFG_TYPE_PUD: case PINCFG_TYPE_PUD:
/* first set pull enable/disable bit */ /* first set pull enable/disable bit */
...@@ -459,6 +465,7 @@ static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -459,6 +465,7 @@ static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
WARN_ON(1); WARN_ON(1);
return -EINVAL; return -EINVAL;
} }
} /* for each config */
return 0; return 0;
} }
...@@ -510,7 +517,8 @@ static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -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 */ /* set the pin config settings for a specified pin group */
static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev, 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; struct exynos5440_pinctrl_priv_data *priv;
const unsigned int *pins; const unsigned int *pins;
...@@ -520,7 +528,8 @@ static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -520,7 +528,8 @@ static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
pins = priv->pin_groups[group].pins; pins = priv->pin_groups[group].pins;
for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++) 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; return 0;
} }
......
...@@ -238,7 +238,8 @@ static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev, ...@@ -238,7 +238,8 @@ static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev,
} }
static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev, static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev,
unsigned group, unsigned long config) unsigned group, unsigned long *configs,
unsigned num_configs)
{ {
return -ENOTSUPP; return -ENOTSUPP;
} }
...@@ -279,13 +280,19 @@ static int falcon_pinconf_get(struct pinctrl_dev *pctrldev, ...@@ -279,13 +280,19 @@ static int falcon_pinconf_get(struct pinctrl_dev *pctrldev,
} }
static int falcon_pinconf_set(struct pinctrl_dev *pctrldev, static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
unsigned pin, unsigned long config) unsigned pin, unsigned long *configs,
unsigned num_configs)
{ {
enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config); enum ltq_pinconf_param param;
int arg = LTQ_PINCONF_UNPACK_ARG(config); int arg;
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
void __iomem *mem = info->membase[PORT(pin)]; void __iomem *mem = info->membase[PORT(pin)];
u32 reg; u32 reg;
int i;
for (i = 0; i < num_configs; i++) {
param = LTQ_PINCONF_UNPACK_PARAM(configs[i]);
arg = LTQ_PINCONF_UNPACK_ARG(configs[i]);
switch (param) { switch (param) {
case LTQ_PINCONF_PARAM_DRIVE_CURRENT: case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
...@@ -312,6 +319,8 @@ static int falcon_pinconf_set(struct pinctrl_dev *pctrldev, ...@@ -312,6 +319,8 @@ static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
pad_w32(mem, BIT(PORT_PIN(pin)), reg); pad_w32(mem, BIT(PORT_PIN(pin)), reg);
if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin)))) if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin))))
return -ENOTSUPP; return -ENOTSUPP;
} /* for each config */
return 0; return 0;
} }
......
...@@ -323,11 +323,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -323,11 +323,13 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int imx_pinconf_set(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); struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev);
const struct imx_pinctrl_soc_info *info = ipctl->info; const struct imx_pinctrl_soc_info *info = ipctl->info;
const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id]; const struct imx_pin_reg *pin_reg = &info->pin_regs[pin_id];
int i;
if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) { if (!(info->flags & ZERO_OFFSET_VALID) && !pin_reg->conf_reg) {
dev_err(info->dev, "Pin(%s) does not support config function\n", 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, ...@@ -338,17 +340,19 @@ static int imx_pinconf_set(struct pinctrl_dev *pctldev,
dev_dbg(ipctl->dev, "pinconf set pin %s\n", dev_dbg(ipctl->dev, "pinconf set pin %s\n",
info->pins[pin_id].name); info->pins[pin_id].name);
for (i = 0; i < num_configs; i++) {
if (info->flags & SHARE_MUX_CONF_REG) { if (info->flags & SHARE_MUX_CONF_REG) {
u32 reg; u32 reg;
reg = readl(ipctl->base + pin_reg->conf_reg); reg = readl(ipctl->base + pin_reg->conf_reg);
reg &= ~0xffff; reg &= ~0xffff;
reg |= config; reg |= configs[i];
writel(reg, ipctl->base + pin_reg->conf_reg); writel(reg, ipctl->base + pin_reg->conf_reg);
} else { } else {
writel(config, ipctl->base + pin_reg->conf_reg); writel(configs[i], ipctl->base + pin_reg->conf_reg);
} }
dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n", dev_dbg(ipctl->dev, "write: offset 0x%x val 0x%lx\n",
pin_reg->conf_reg, config); pin_reg->conf_reg, configs[i]);
} /* for each config */
return 0; return 0;
} }
......
...@@ -233,7 +233,8 @@ static int mxs_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -233,7 +233,8 @@ static int mxs_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int mxs_pinconf_set(struct pinctrl_dev *pctldev, static int mxs_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config) unsigned pin, unsigned long *configs,
unsigned num_configs)
{ {
return -ENOTSUPP; return -ENOTSUPP;
} }
...@@ -249,7 +250,8 @@ static int mxs_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -249,7 +250,8 @@ static int mxs_pinconf_group_get(struct pinctrl_dev *pctldev,
} }
static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long config) unsigned group, unsigned long *configs,
unsigned num_configs)
{ {
struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev); struct mxs_pinctrl_data *d = pinctrl_dev_get_drvdata(pctldev);
struct mxs_group *g = &d->soc->groups[group]; struct mxs_group *g = &d->soc->groups[group];
...@@ -257,6 +259,11 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -257,6 +259,11 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,
u8 ma, vol, pull, bank, shift; u8 ma, vol, pull, bank, shift;
u16 pin; u16 pin;
u32 i; u32 i;
int n;
unsigned long config;
for (n = 0; n < num_configs; n++) {
config = configs[n];
ma = CONFIG_TO_MA(config); ma = CONFIG_TO_MA(config);
vol = CONFIG_TO_VOL(config); vol = CONFIG_TO_VOL(config);
...@@ -301,6 +308,8 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -301,6 +308,8 @@ static int mxs_pinconf_group_set(struct pinctrl_dev *pctldev,
/* cache the config value for mxs_pinconf_group_get() */ /* cache the config value for mxs_pinconf_group_get() */
g->config = config; g->config = config;
} /* for each config */
return 0; return 0;
} }
......
...@@ -1695,7 +1695,7 @@ static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1695,7 +1695,7 @@ static int nmk_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin,
} }
static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config) unsigned long *configs, unsigned num_configs)
{ {
static const char *pullnames[] = { static const char *pullnames[] = {
[NMK_GPIO_PULL_NONE] = "none", [NMK_GPIO_PULL_NONE] = "none",
...@@ -1712,20 +1712,9 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1712,20 +1712,9 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
struct pinctrl_gpio_range *range; struct pinctrl_gpio_range *range;
struct gpio_chip *chip; struct gpio_chip *chip;
unsigned bit; unsigned bit;
pin_cfg_t cfg;
/* int pull, slpm, output, val, i;
* The pin config contains pin number and altfunction fields, here bool lowemi, gpiomode, sleep;
* we just ignore that part. It's being handled by the framework and
* pinmux callback respectively.
*/
pin_cfg_t cfg = (pin_cfg_t) config;
int pull = PIN_PULL(cfg);
int slpm = PIN_SLPM(cfg);
int output = PIN_DIR(cfg);
int val = PIN_VAL(cfg);
bool lowemi = PIN_LOWEMI(cfg);
bool gpiomode = PIN_GPIOMODE(cfg);
bool sleep = PIN_SLEEPMODE(cfg);
range = nmk_match_gpio_range(pctldev, pin); range = nmk_match_gpio_range(pctldev, pin);
if (!range) { if (!range) {
...@@ -1740,6 +1729,21 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1740,6 +1729,21 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
chip = range->gc; chip = range->gc;
nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
for (i = 0; i < num_configs; i++) {
/*
* The pin config contains pin number and altfunction fields,
* here we just ignore that part. It's being handled by the
* framework and pinmux callback respectively.
*/
cfg = (pin_cfg_t) configs[i];
pull = PIN_PULL(cfg);
slpm = PIN_SLPM(cfg);
output = PIN_DIR(cfg);
val = PIN_VAL(cfg);
lowemi = PIN_LOWEMI(cfg);
gpiomode = PIN_GPIOMODE(cfg);
sleep = PIN_SLEEPMODE(cfg);
if (sleep) { if (sleep) {
int slpm_pull = PIN_SLPM_PULL(cfg); int slpm_pull = PIN_SLPM_PULL(cfg);
int slpm_output = PIN_SLPM_DIR(cfg); int slpm_output = PIN_SLPM_DIR(cfg);
...@@ -1749,8 +1753,8 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1749,8 +1753,8 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
gpiomode = true; gpiomode = true;
/* /*
* The SLPM_* values are normal values + 1 to allow zero to * The SLPM_* values are normal values + 1 to allow zero
* mean "same as normal". * to mean "same as normal".
*/ */
if (slpm_pull) if (slpm_pull)
pull = slpm_pull - 1; pull = slpm_pull - 1;
...@@ -1759,14 +1763,17 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1759,14 +1763,17 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
if (slpm_val) if (slpm_val)
val = slpm_val - 1; val = slpm_val - 1;
dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", dev_dbg(nmk_chip->chip.dev,
"pin %d: sleep pull %s, dir %s, val %s\n",
pin, pin,
slpm_pull ? pullnames[pull] : "same", slpm_pull ? pullnames[pull] : "same",
slpm_output ? (output ? "output" : "input") : "same", slpm_output ? (output ? "output" : "input")
: "same",
slpm_val ? (val ? "high" : "low") : "same"); slpm_val ? (val ? "high" : "low") : "same");
} }
dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n", dev_dbg(nmk_chip->chip.dev,
"pin %d [%#lx]: pull %s, slpm %s (%s%s), lowemi %s\n",
pin, cfg, pullnames[pull], slpmnames[slpm], pin, cfg, pullnames[pull], slpmnames[slpm],
output ? "output " : "input", output ? "output " : "input",
output ? (val ? "high" : "low") : "", output ? (val ? "high" : "low") : "",
...@@ -1788,6 +1795,8 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -1788,6 +1795,8 @@ static int nmk_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin,
__nmk_gpio_set_slpm(nmk_chip, bit, slpm); __nmk_gpio_set_slpm(nmk_chip, bit, slpm);
clk_disable(nmk_chip->clk); clk_disable(nmk_chip->clk);
} /* for each config */
return 0; return 0;
} }
......
...@@ -854,17 +854,19 @@ static int palmas_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -854,17 +854,19 @@ static int palmas_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int palmas_pinconf_set(struct pinctrl_dev *pctldev, static int palmas_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config) unsigned pin, unsigned long *configs,
unsigned num_configs)
{ {
struct palmas_pctrl_chip_info *pci = pinctrl_dev_get_drvdata(pctldev); struct palmas_pctrl_chip_info *pci = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
u16 param_val = pinconf_to_config_argument(config); u16 param_val;
const struct palmas_pingroup *g; const struct palmas_pingroup *g;
const struct palmas_pin_info *opt; const struct palmas_pin_info *opt;
int ret; int ret;
int base, add, mask; int base, add, mask;
int rval; int rval;
int group_nr; int group_nr;
int i;
for (group_nr = 0; group_nr < pci->num_pin_groups; ++group_nr) { for (group_nr = 0; group_nr < pci->num_pin_groups; ++group_nr) {
if (pci->pin_groups[group_nr].pins[0] == pin) if (pci->pin_groups[group_nr].pins[0] == pin)
...@@ -885,6 +887,10 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -885,6 +887,10 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev,
return -ENOTSUPP; return -ENOTSUPP;
} }
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
param_val = pinconf_to_config_argument(configs[i]);
switch (param) { switch (param) {
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
return 0; return 0;
...@@ -946,9 +952,12 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -946,9 +952,12 @@ static int palmas_pinconf_set(struct pinctrl_dev *pctldev,
__func__, base, add, mask, rval); __func__, base, add, mask, rval);
ret = palmas_update_bits(pci->palmas, base, add, mask, rval); ret = palmas_update_bits(pci->palmas, base, add, mask, rval);
if (ret < 0) { if (ret < 0) {
dev_err(pci->dev, "Reg 0x%02x update failed: %d\n", add, ret); dev_err(pci->dev, "Reg 0x%02x update failed: %d\n",
add, ret);
return ret; return ret;
} }
} /* for each config */
return 0; return 0;
} }
...@@ -960,7 +969,8 @@ static int palmas_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -960,7 +969,8 @@ static int palmas_pinconf_group_get(struct pinctrl_dev *pctldev,
} }
static int palmas_pinconf_group_set(struct pinctrl_dev *pctldev, static int palmas_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long config) unsigned group, unsigned long *configs,
unsigned num_configs)
{ {
dev_err(pctldev->dev, "palmas_pinconf_group_set op not supported\n"); dev_err(pctldev->dev, "palmas_pinconf_group_set op not supported\n");
return -ENOTSUPP; return -ENOTSUPP;
......
...@@ -574,16 +574,25 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl, ...@@ -574,16 +574,25 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
/* set the pin config settings for a specified pin */ /* set the pin config settings for a specified pin */
static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
unsigned long config) unsigned long *configs, unsigned num_configs)
{ {
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank = pin_to_bank(info, pin); struct rockchip_pin_bank *bank = pin_to_bank(info, pin);
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
u16 arg = pinconf_to_config_argument(config); u16 arg;
int i;
int rc;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
switch (param) { switch (param) {
case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_DISABLE:
return rockchip_set_pull(bank, pin - bank->pin_base, param); rc = rockchip_set_pull(bank, pin - bank->pin_base,
param);
if (rc)
return rc;
break; break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_DOWN:
...@@ -594,12 +603,16 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -594,12 +603,16 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
if (!arg) if (!arg)
return -EINVAL; return -EINVAL;
return rockchip_set_pull(bank, pin - bank->pin_base, param); rc = rockchip_set_pull(bank, pin - bank->pin_base,
param);
if (rc)
return rc;
break; break;
default: default:
return -ENOTSUPP; return -ENOTSUPP;
break; break;
} }
} /* for each config */
return 0; return 0;
} }
......
...@@ -442,9 +442,17 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, ...@@ -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 */ /* set the pin config settings for a specified pin */
static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int 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 */ /* 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, ...@@ -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 */ /* set the pin config settings for a specified pin group */
static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev, 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; struct samsung_pinctrl_drv_data *drvdata;
const unsigned int *pins; const unsigned int *pins;
...@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -466,7 +475,7 @@ static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
pins = drvdata->pin_groups[group].pins; pins = drvdata->pin_groups[group].pins;
for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) 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; return 0;
} }
......
...@@ -209,7 +209,7 @@ struct pcs_device { ...@@ -209,7 +209,7 @@ struct pcs_device {
static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, static int pcs_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config); unsigned long *config);
static int pcs_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, 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[] = { static enum pin_config_param pcs_bias[] = {
PIN_CONFIG_BIAS_PULL_DOWN, PIN_CONFIG_BIAS_PULL_DOWN,
...@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin) ...@@ -536,7 +536,7 @@ static void pcs_pinconf_clear_bias(struct pinctrl_dev *pctldev, unsigned pin)
int i; int i;
for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) { for (i = 0; i < ARRAY_SIZE(pcs_bias); i++) {
config = pinconf_to_config_packed(pcs_bias[i], 0); 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, ...@@ -622,22 +622,28 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int pcs_pinconf_set(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_device *pcs = pinctrl_dev_get_drvdata(pctldev);
struct pcs_function *func; struct pcs_function *func;
unsigned offset = 0, shift = 0, i, data, ret; unsigned offset = 0, shift = 0, i, data, ret;
u16 arg; u16 arg;
int j;
ret = pcs_get_function(pctldev, pin, &func); ret = pcs_get_function(pctldev, pin, &func);
if (ret) if (ret)
return ret; return ret;
for (j = 0; j < num_configs; j++) {
for (i = 0; i < func->nconfs; i++) { for (i = 0; i < func->nconfs; i++) {
if (pinconf_to_config_param(config) == func->conf[i].param) { if (pinconf_to_config_param(configs[j])
!= func->conf[i].param)
continue;
offset = pin * (pcs->width / BITS_PER_BYTE); offset = pin * (pcs->width / BITS_PER_BYTE);
data = pcs->read(pcs->base + offset); data = pcs->read(pcs->base + offset);
arg = pinconf_to_config_argument(config); arg = pinconf_to_config_argument(configs[j]);
switch (func->conf[i].param) { switch (func->conf[i].param) {
/* 2 parameters */ /* 2 parameters */
case PIN_CONFIG_INPUT_SCHMITT: case PIN_CONFIG_INPUT_SCHMITT:
...@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -667,10 +673,14 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev,
return -ENOTSUPP; return -ENOTSUPP;
} }
pcs->write(data, pcs->base + offset); pcs->write(data, pcs->base + offset);
return 0;
} break;
} }
if (i >= func->nconfs)
return -ENOTSUPP; return -ENOTSUPP;
} /* for each config */
return 0;
} }
static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev, static int pcs_pinconf_group_get(struct pinctrl_dev *pctldev,
...@@ -695,7 +705,8 @@ 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, 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; const unsigned *pins;
unsigned npins; unsigned npins;
...@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -705,7 +716,7 @@ static int pcs_pinconf_group_set(struct pinctrl_dev *pctldev,
if (ret) if (ret)
return ret; return ret;
for (i = 0; i < npins; i++) { 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 -ENOTSUPP;
} }
return 0; return 0;
......
...@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info, ...@@ -909,15 +909,18 @@ static void st_pinconf_set_retime(struct st_pinctrl *info,
config, pin); config, pin);
} }
static int st_pinconf_set(struct pinctrl_dev *pctldev, static int st_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin_id,
unsigned pin_id, unsigned long config) unsigned long *configs, unsigned num_configs)
{ {
int pin = st_gpio_pin(pin_id); int pin = st_gpio_pin(pin_id);
struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct st_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id); struct st_pio_control *pc = st_get_pio_control(pctldev, pin_id);
int i;
st_pinconf_set_config(pc, pin, config); for (i = 0; i < num_configs; i++) {
st_pinconf_set_retime(info, pc, pin, config); st_pinconf_set_config(pc, pin, configs[i]);
st_pinconf_set_retime(info, pc, pin, configs[i]);
} /* for each config */
return 0; return 0;
} }
......
...@@ -274,17 +274,20 @@ static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev, ...@@ -274,17 +274,20 @@ static int sunxi_pconf_group_get(struct pinctrl_dev *pctldev,
static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned group,
unsigned long config) unsigned long *configs,
unsigned num_configs)
{ {
struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
struct sunxi_pinctrl_group *g = &pctl->groups[group]; struct sunxi_pinctrl_group *g = &pctl->groups[group];
u32 val, mask; u32 val, mask;
u16 strength; u16 strength;
u8 dlevel; u8 dlevel;
int i;
switch (pinconf_to_config_param(config)) { for (i = 0; i < num_configs; i++) {
switch (pinconf_to_config_param(configs[i])) {
case PIN_CONFIG_DRIVE_STRENGTH: case PIN_CONFIG_DRIVE_STRENGTH:
strength = pinconf_to_config_argument(config); strength = pinconf_to_config_argument(configs[i]);
if (strength > 40) if (strength > 40)
return -EINVAL; return -EINVAL;
/* /*
...@@ -297,7 +300,8 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, ...@@ -297,7 +300,8 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
dlevel = strength / 10 - 1; dlevel = strength / 10 - 1;
val = readl(pctl->membase + sunxi_dlevel_reg(g->pin)); val = readl(pctl->membase + sunxi_dlevel_reg(g->pin));
mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin); mask = DLEVEL_PINS_MASK << sunxi_dlevel_offset(g->pin);
writel((val & ~mask) | dlevel << sunxi_dlevel_offset(g->pin), writel((val & ~mask)
| dlevel << sunxi_dlevel_offset(g->pin),
pctl->membase + sunxi_dlevel_reg(g->pin)); pctl->membase + sunxi_dlevel_reg(g->pin));
break; break;
case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
...@@ -317,7 +321,8 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev, ...@@ -317,7 +321,8 @@ static int sunxi_pconf_group_set(struct pinctrl_dev *pctldev,
} }
/* cache the config value */ /* cache the config value */
g->config = config; g->config = configs[i];
} /* for each config */
return 0; return 0;
} }
......
...@@ -436,7 +436,8 @@ static int tegra_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -436,7 +436,8 @@ static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int tegra_pinconf_set(struct pinctrl_dev *pctldev, static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config) unsigned pin, unsigned long *configs,
unsigned num_configs)
{ {
dev_err(pctldev->dev, "pin_config_set op not supported\n"); dev_err(pctldev->dev, "pin_config_set op not supported\n");
return -ENOTSUPP; return -ENOTSUPP;
...@@ -471,19 +472,24 @@ static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -471,19 +472,24 @@ static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
} }
static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long config) unsigned group, unsigned long *configs,
unsigned num_configs)
{ {
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config); enum tegra_pinconf_param param;
u16 arg = TEGRA_PINCONF_UNPACK_ARG(config); u16 arg;
const struct tegra_pingroup *g; const struct tegra_pingroup *g;
int ret; int ret, i;
s8 bank, bit, width; s8 bank, bit, width;
s16 reg; s16 reg;
u32 val, mask; u32 val, mask;
g = &pmx->soc->groups[group]; g = &pmx->soc->groups[group];
for (i = 0; i < num_configs; i++) {
param = TEGRA_PINCONF_UNPACK_PARAM(configs[i]);
arg = TEGRA_PINCONF_UNPACK_ARG(configs[i]);
ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit, ret = tegra_pinconf_reg(pmx, g, param, true, &bank, &reg, &bit,
&width); &width);
if (ret < 0) if (ret < 0)
...@@ -508,7 +514,7 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -508,7 +514,7 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
if (arg & ~mask) { if (arg & ~mask) {
dev_err(pctldev->dev, dev_err(pctldev->dev,
"config %lx: %x too big for %d bit register\n", "config %lx: %x too big for %d bit register\n",
config, arg, width); configs[i], arg, width);
return -EINVAL; return -EINVAL;
} }
...@@ -516,6 +522,7 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -516,6 +522,7 @@ static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
val &= ~(mask << bit); val &= ~(mask << bit);
val |= arg << bit; val |= arg << bit;
pmx_writel(pmx, val, bank, reg); pmx_writel(pmx, val, bank, reg);
} /* for each config */
return 0; return 0;
} }
......
...@@ -737,17 +737,23 @@ static int tz1090_pdc_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -737,17 +737,23 @@ static int tz1090_pdc_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int tz1090_pdc_pinconf_set(struct pinctrl_dev *pctldev, static int tz1090_pdc_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long config) unsigned int pin, unsigned long *configs,
unsigned num_configs)
{ {
struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
unsigned int arg = pinconf_to_config_argument(config); unsigned int arg;
int ret; int ret;
u32 reg, width, mask, shift, val, tmp; u32 reg, width, mask, shift, val, tmp;
unsigned long flags; unsigned long flags;
int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
__func__, tz1090_pdc_pins[pin].name, config); __func__, tz1090_pdc_pins[pin].name, configs[i]);
/* Get register information */ /* Get register information */
ret = tz1090_pdc_pinconf_reg(pctldev, pin, param, true, ret = tz1090_pdc_pinconf_reg(pctldev, pin, param, true,
...@@ -770,6 +776,7 @@ static int tz1090_pdc_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -770,6 +776,7 @@ static int tz1090_pdc_pinconf_set(struct pinctrl_dev *pctldev,
tmp |= val << shift; tmp |= val << shift;
pmx_write(pmx, tmp, reg); pmx_write(pmx, tmp, reg);
__global_unlock2(flags); __global_unlock2(flags);
} /* for each config */
return 0; return 0;
} }
...@@ -860,31 +867,39 @@ static int tz1090_pdc_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -860,31 +867,39 @@ static int tz1090_pdc_pinconf_group_get(struct pinctrl_dev *pctldev,
static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev, static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned int group,
unsigned long config) unsigned long *configs,
unsigned num_configs)
{ {
struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct tz1090_pdc_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tz1090_pdc_pingroup *g = &tz1090_pdc_groups[group]; const struct tz1090_pdc_pingroup *g = &tz1090_pdc_groups[group];
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
const unsigned int *pit; const unsigned int *pit;
unsigned int i; unsigned int i;
int ret, arg; int ret, arg;
u32 reg, width, mask, shift, val; u32 reg, width, mask, shift, val;
unsigned long flags; unsigned long flags;
const int *map; const int *map;
int j;
for (j = 0; j < num_configs; j++) {
param = pinconf_to_config_param(configs[j]);
dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
__func__, g->name, config); __func__, g->name, configs[j]);
/* Get register information */ /* Get register information */
ret = tz1090_pdc_pinconf_group_reg(pctldev, g, param, true, ret = tz1090_pdc_pinconf_group_reg(pctldev, g, param, true,
&reg, &width, &mask, &shift, &map); &reg, &width, &mask, &shift,
&map);
if (ret < 0) { if (ret < 0) {
/* /*
* Maybe we're trying to set a per-pin configuration of a group, * Maybe we're trying to set a per-pin configuration
* so do the pins one by one. This is mainly as a convenience. * of a group, so do the pins one by one. This is
* mainly as a convenience.
*/ */
for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) { for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
ret = tz1090_pdc_pinconf_set(pctldev, *pit, config); ret = tz1090_pdc_pinconf_set(pctldev, *pit,
configs, num_configs);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -892,7 +907,7 @@ static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -892,7 +907,7 @@ static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev,
} }
/* Unpack argument and map it to register value */ /* Unpack argument and map it to register value */
arg = pinconf_to_config_argument(config); arg = pinconf_to_config_argument(configs[j]);
for (i = 0; i < BIT(width); ++i) { for (i = 0; i < BIT(width); ++i) {
if (map[i] == arg || (map[i] == -EINVAL && !arg)) { if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
/* Write register field */ /* Write register field */
...@@ -902,13 +917,19 @@ static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -902,13 +917,19 @@ static int tz1090_pdc_pinconf_group_set(struct pinctrl_dev *pctldev,
val |= i << shift; val |= i << shift;
pmx_write(pmx, val, reg); pmx_write(pmx, val, reg);
__global_unlock2(flags); __global_unlock2(flags);
return 0; goto next_config;
} }
} }
dev_dbg(pctldev->dev, "%s: arg %u not supported\n", dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
__func__, arg); __func__, arg);
return 0; return 0;
next_config:
;
} /* for each config */
return 0;
} }
static struct pinconf_ops tz1090_pdc_pinconf_ops = { static struct pinconf_ops tz1090_pdc_pinconf_ops = {
......
...@@ -1762,17 +1762,23 @@ static int tz1090_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -1762,17 +1762,23 @@ static int tz1090_pinconf_get(struct pinctrl_dev *pctldev,
} }
static int tz1090_pinconf_set(struct pinctrl_dev *pctldev, static int tz1090_pinconf_set(struct pinctrl_dev *pctldev,
unsigned int pin, unsigned long config) unsigned int pin, unsigned long *configs,
unsigned num_configs)
{ {
struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
unsigned int arg = pinconf_to_config_argument(config); unsigned int arg;
int ret; int ret;
u32 reg, width, mask, shift, val, tmp; u32 reg, width, mask, shift, val, tmp;
unsigned long flags; unsigned long flags;
int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n", dev_dbg(pctldev->dev, "%s(pin=%s, config=%#lx)\n",
__func__, tz1090_pins[pin].name, config); __func__, tz1090_pins[pin].name, configs[i]);
/* Get register information */ /* Get register information */
ret = tz1090_pinconf_reg(pctldev, pin, param, true, ret = tz1090_pinconf_reg(pctldev, pin, param, true,
...@@ -1795,6 +1801,7 @@ static int tz1090_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -1795,6 +1801,7 @@ static int tz1090_pinconf_set(struct pinctrl_dev *pctldev,
tmp |= val << shift; tmp |= val << shift;
pmx_write(pmx, tmp, reg); pmx_write(pmx, tmp, reg);
__global_unlock2(flags); __global_unlock2(flags);
} /* for each config */
return 0; return 0;
} }
...@@ -1894,44 +1901,51 @@ static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev, ...@@ -1894,44 +1901,51 @@ static int tz1090_pinconf_group_get(struct pinctrl_dev *pctldev,
} }
static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned int group, unsigned long config) unsigned int group, unsigned long *configs,
unsigned num_configs)
{ {
struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); struct tz1090_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tz1090_pingroup *g; const struct tz1090_pingroup *g;
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
unsigned int arg, pin, i; unsigned int arg, pin, i;
const unsigned int *pit; const unsigned int *pit;
int ret; int ret;
u32 reg, width, mask, shift, val; u32 reg, width, mask, shift, val;
unsigned long flags; unsigned long flags;
const int *map; const int *map;
int j;
if (group >= ARRAY_SIZE(tz1090_groups)) { if (group >= ARRAY_SIZE(tz1090_groups)) {
pin = group - ARRAY_SIZE(tz1090_groups); pin = group - ARRAY_SIZE(tz1090_groups);
return tz1090_pinconf_set(pctldev, pin, config); return tz1090_pinconf_set(pctldev, pin, configs, num_configs);
} }
g = &tz1090_groups[group]; g = &tz1090_groups[group];
if (g->npins == 1) { if (g->npins == 1) {
pin = g->pins[0]; pin = g->pins[0];
ret = tz1090_pinconf_set(pctldev, pin, config); ret = tz1090_pinconf_set(pctldev, pin, configs, num_configs);
if (ret != -ENOTSUPP) if (ret != -ENOTSUPP)
return ret; return ret;
} }
for (j = 0; j < num_configs; j++) {
param = pinconf_to_config_param(configs[j]);
dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n", dev_dbg(pctldev->dev, "%s(group=%s, config=%#lx)\n",
__func__, g->name, config); __func__, g->name, configs[j]);
/* Get register information */ /* Get register information */
ret = tz1090_pinconf_group_reg(pctldev, g, param, true, ret = tz1090_pinconf_group_reg(pctldev, g, param, true, &reg,
&reg, &width, &mask, &shift, &map); &width, &mask, &shift, &map);
if (ret < 0) { if (ret < 0) {
/* /*
* Maybe we're trying to set a per-pin configuration of a group, * Maybe we're trying to set a per-pin configuration
* so do the pins one by one. This is mainly as a convenience. * of a group, so do the pins one by one. This is
* mainly as a convenience.
*/ */
for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) { for (i = 0, pit = g->pins; i < g->npins; ++i, ++pit) {
ret = tz1090_pinconf_set(pctldev, *pit, config); ret = tz1090_pinconf_set(pctldev, *pit, configs,
num_configs);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -1939,7 +1953,7 @@ static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -1939,7 +1953,7 @@ static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
} }
/* Unpack argument and map it to register value */ /* Unpack argument and map it to register value */
arg = pinconf_to_config_argument(config); arg = pinconf_to_config_argument(configs[j]);
for (i = 0; i < BIT(width); ++i) { for (i = 0; i < BIT(width); ++i) {
if (map[i] == arg || (map[i] == -EINVAL && !arg)) { if (map[i] == arg || (map[i] == -EINVAL && !arg)) {
/* Write register field */ /* Write register field */
...@@ -1949,13 +1963,19 @@ static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev, ...@@ -1949,13 +1963,19 @@ static int tz1090_pinconf_group_set(struct pinctrl_dev *pctldev,
val |= i << shift; val |= i << shift;
pmx_write(pmx, val, reg); pmx_write(pmx, val, reg);
__global_unlock2(flags); __global_unlock2(flags);
return 0; goto next_config;
} }
} }
dev_dbg(pctldev->dev, "%s: arg %u not supported\n", dev_dbg(pctldev->dev, "%s: arg %u not supported\n",
__func__, arg); __func__, arg);
return -EINVAL; return -EINVAL;
next_config:
;
} /* for each config */
return 0;
} }
static struct pinconf_ops tz1090_pinconf_ops = { static struct pinconf_ops tz1090_pinconf_ops = {
......
...@@ -1027,21 +1027,23 @@ static int u300_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -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, 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 = struct pinctrl_gpio_range *range =
pinctrl_find_gpio_range_from_pin(pctldev, pin); pinctrl_find_gpio_range_from_pin(pctldev, pin);
int ret; int ret, i;
if (!range) if (!range)
return -EINVAL; return -EINVAL;
for (i = 0; i < num_configs; i++) {
/* Note: none of these configurations take any argument */ /* Note: none of these configurations take any argument */
ret = u300_gpio_config_set(range->gc, ret = u300_gpio_config_set(range->gc,
(pin - range->pin_base + range->base), (pin - range->pin_base + range->base),
pinconf_to_config_param(config)); pinconf_to_config_param(configs[i]));
if (ret) if (ret)
return ret; return ret;
} /* for each config */
return 0; return 0;
} }
......
...@@ -499,13 +499,19 @@ static int xway_pinconf_get(struct pinctrl_dev *pctldev, ...@@ -499,13 +499,19 @@ static int xway_pinconf_get(struct pinctrl_dev *pctldev,
static int xway_pinconf_set(struct pinctrl_dev *pctldev, static int xway_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned pin,
unsigned long config) unsigned long *configs,
unsigned num_configs)
{ {
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config); enum ltq_pinconf_param param;
int arg = LTQ_PINCONF_UNPACK_ARG(config); int arg;
int port = PORT(pin); int port = PORT(pin);
u32 reg; u32 reg;
int i;
for (i = 0; i < num_configs; i++) {
param = LTQ_PINCONF_UNPACK_PARAM(configs[i]);
arg = LTQ_PINCONF_UNPACK_ARG(configs[i]);
switch (param) { switch (param) {
case LTQ_PINCONF_PARAM_OPEN_DRAIN: case LTQ_PINCONF_PARAM_OPEN_DRAIN:
...@@ -514,9 +520,13 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -514,9 +520,13 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
else else
reg = GPIO_OD(pin); reg = GPIO_OD(pin);
if (arg == 0) if (arg == 0)
gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); gpio_setbit(info->membase[0],
reg,
PORT_PIN(pin));
else else
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); gpio_clearbit(info->membase[0],
reg,
PORT_PIN(pin));
break; break;
case LTQ_PINCONF_PARAM_PULL: case LTQ_PINCONF_PARAM_PULL:
...@@ -525,7 +535,9 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -525,7 +535,9 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
else else
reg = GPIO_PUDEN(pin); reg = GPIO_PUDEN(pin);
if (arg == 0) { if (arg == 0) {
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); gpio_clearbit(info->membase[0],
reg,
PORT_PIN(pin));
break; break;
} }
gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); gpio_setbit(info->membase[0], reg, PORT_PIN(pin));
...@@ -535,38 +547,53 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev, ...@@ -535,38 +547,53 @@ static int xway_pinconf_set(struct pinctrl_dev *pctldev,
else else
reg = GPIO_PUDSEL(pin); reg = GPIO_PUDSEL(pin);
if (arg == 1) if (arg == 1)
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); gpio_clearbit(info->membase[0],
reg,
PORT_PIN(pin));
else if (arg == 2) else if (arg == 2)
gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); gpio_setbit(info->membase[0],
reg,
PORT_PIN(pin));
else else
dev_err(pctldev->dev, "Invalid pull value %d\n", arg); dev_err(pctldev->dev,
"Invalid pull value %d\n", arg);
break; break;
case LTQ_PINCONF_PARAM_OUTPUT: case LTQ_PINCONF_PARAM_OUTPUT:
reg = GPIO_DIR(pin); reg = GPIO_DIR(pin);
if (arg == 0) if (arg == 0)
gpio_clearbit(info->membase[0], reg, PORT_PIN(pin)); gpio_clearbit(info->membase[0],
reg,
PORT_PIN(pin));
else else
gpio_setbit(info->membase[0], reg, PORT_PIN(pin)); gpio_setbit(info->membase[0],
reg,
PORT_PIN(pin));
break; break;
default: default:
dev_err(pctldev->dev, "Invalid config param %04x\n", param); dev_err(pctldev->dev,
"Invalid config param %04x\n", param);
return -ENOTSUPP; return -ENOTSUPP;
} }
} /* for each config */
return 0; return 0;
} }
int xway_pinconf_group_set(struct pinctrl_dev *pctldev, int xway_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned selector, unsigned selector,
unsigned long config) unsigned long *configs,
unsigned num_configs)
{ {
struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev); struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
int i, ret = 0; int i, ret = 0;
for (i = 0; i < info->grps[selector].npins && !ret; i++) for (i = 0; i < info->grps[selector].npins && !ret; i++)
ret = xway_pinconf_set(pctldev, ret = xway_pinconf_set(pctldev,
info->grps[selector].pins[i], config); info->grps[selector].pins[i],
configs,
num_configs);
return ret; return ret;
} }
......
...@@ -529,12 +529,16 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, ...@@ -529,12 +529,16 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
} }
static int sh_pfc_pinconf_set(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_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
struct sh_pfc *pfc = pmx->pfc; 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 long flags;
unsigned int i;
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
if (!sh_pfc_pinconf_validate(pfc, _pin, param)) if (!sh_pfc_pinconf_validate(pfc, _pin, param))
return -ENOTSUPP; return -ENOTSUPP;
...@@ -555,12 +559,14 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, ...@@ -555,12 +559,14 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin,
default: default:
return -ENOTSUPP; return -ENOTSUPP;
} }
} /* for each config */
return 0; return 0;
} }
static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, 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); struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
const unsigned int *pins; const unsigned int *pins;
...@@ -571,7 +577,7 @@ static int sh_pfc_pinconf_group_set(struct pinctrl_dev *pctldev, unsigned group, ...@@ -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; num_pins = pmx->pfc->info->groups[group].nr_pins;
for (i = 0; i < num_pins; ++i) 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; return 0;
} }
......
...@@ -424,15 +424,16 @@ static int wmt_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -424,15 +424,16 @@ static int wmt_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,
} }
static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config) unsigned long *configs, unsigned num_configs)
{ {
struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev); struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);
enum pin_config_param param = pinconf_to_config_param(config); enum pin_config_param param;
u16 arg = pinconf_to_config_argument(config); u16 arg;
u32 bank = WMT_BANK_FROM_PIN(pin); u32 bank = WMT_BANK_FROM_PIN(pin);
u32 bit = WMT_BIT_FROM_PIN(pin); u32 bit = WMT_BIT_FROM_PIN(pin);
u32 reg_pull_en = data->banks[bank].reg_pull_en; u32 reg_pull_en = data->banks[bank].reg_pull_en;
u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg; u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg;
int i;
if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) { if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) {
dev_err(data->dev, "bias functions not supported on pin %d\n", dev_err(data->dev, "bias functions not supported on pin %d\n",
...@@ -440,6 +441,10 @@ static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -440,6 +441,10 @@ static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < num_configs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
if ((param == PIN_CONFIG_BIAS_PULL_DOWN) || if ((param == PIN_CONFIG_BIAS_PULL_DOWN) ||
(param == PIN_CONFIG_BIAS_PULL_UP)) { (param == PIN_CONFIG_BIAS_PULL_UP)) {
if (arg == 0) if (arg == 0)
...@@ -462,6 +467,7 @@ static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, ...@@ -462,6 +467,7 @@ static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
dev_err(data->dev, "unknown pinconf param\n"); dev_err(data->dev, "unknown pinconf param\n");
return -EINVAL; return -EINVAL;
} }
} /* for each config */
return 0; return 0;
} }
......
...@@ -47,13 +47,15 @@ struct pinconf_ops { ...@@ -47,13 +47,15 @@ struct pinconf_ops {
unsigned long *config); unsigned long *config);
int (*pin_config_set) (struct pinctrl_dev *pctldev, int (*pin_config_set) (struct pinctrl_dev *pctldev,
unsigned pin, unsigned pin,
unsigned long config); unsigned long *configs,
unsigned num_configs);
int (*pin_config_group_get) (struct pinctrl_dev *pctldev, int (*pin_config_group_get) (struct pinctrl_dev *pctldev,
unsigned selector, unsigned selector,
unsigned long *config); unsigned long *config);
int (*pin_config_group_set) (struct pinctrl_dev *pctldev, int (*pin_config_group_set) (struct pinctrl_dev *pctldev,
unsigned selector, unsigned selector,
unsigned long config); unsigned long *configs,
unsigned num_configs);
int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev, int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
const char *arg, const char *arg,
unsigned long *config); unsigned long *config);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment