aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pinctrl/pinconf.c55
-rw-r--r--include/linux/pinctrl/pinconf.h8
2 files changed, 49 insertions, 14 deletions
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index e875f21a590..ad30263a741 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -158,7 +158,7 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinconf_ops *ops = pctldev->desc->confops;
- int i, ret;
+ int ret, i;
if (!ops) {
dev_err(pctldev->dev, "missing confops\n");
@@ -167,39 +167,66 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting)
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
- if (!ops->pin_config_set) {
+ if (!ops->pin_config_set && !ops->pin_config_set_bulk) {
dev_err(pctldev->dev, "missing pin_config_set op\n");
return -EINVAL;
}
- for (i = 0; i < setting->data.configs.num_configs; i++) {
- ret = ops->pin_config_set(pctldev,
+ if (ops->pin_config_group_set_bulk) {
+ ret = ops->pin_config_group_set_bulk(pctldev,
setting->data.configs.group_or_pin,
- setting->data.configs.configs[i]);
+ setting->data.configs.configs,
+ setting->data.configs.num_configs);
if (ret < 0) {
dev_err(pctldev->dev,
- "pin_config_set op failed for pin %d config %08lx\n",
- setting->data.configs.group_or_pin,
- setting->data.configs.configs[i]);
+ "pin_config_set op failed for pin %d\n",
+ setting->data.configs.group_or_pin);
return ret;
}
+ } else if (ops->pin_config_set) {
+ for (i = 0; i < setting->data.configs.num_configs; i++) {
+ ret = ops->pin_config_set(pctldev,
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ if (ret < 0) {
+ dev_err(pctldev->dev,
+ "pin_config_set op failed for pin %d config %08lx\n",
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ return ret;
+ }
+ }
}
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
- if (!ops->pin_config_group_set) {
+ if (!ops->pin_config_group_set &&
+ !ops->pin_config_group_set_bulk) {
dev_err(pctldev->dev,
"missing pin_config_group_set op\n");
return -EINVAL;
}
- for (i = 0; i < setting->data.configs.num_configs; i++) {
- ret = ops->pin_config_group_set(pctldev,
+ if (ops->pin_config_group_set_bulk) {
+ ret = ops->pin_config_group_set_bulk(pctldev,
setting->data.configs.group_or_pin,
- setting->data.configs.configs[i]);
+ setting->data.configs.configs,
+ setting->data.configs.num_configs);
if (ret < 0) {
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);
+ return ret;
+ }
+ } else if (ops->pin_config_group_set) {
+ for (i = 0; i < setting->data.configs.num_configs; i++) {
+ ret = ops->pin_config_group_set(pctldev,
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
- return ret;
+ if (ret < 0) {
+ dev_err(pctldev->dev,
+ "pin_config_group_set op failed for group %d config %08lx\n",
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ return ret;
+ }
}
}
break;
diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h
index 1ad4f31ef6b..e6a68e476ae 100644
--- a/include/linux/pinctrl/pinconf.h
+++ b/include/linux/pinctrl/pinconf.h
@@ -48,12 +48,20 @@ struct pinconf_ops {
int (*pin_config_set) (struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long config);
+ int (*pin_config_set_bulk) (struct pinctrl_dev *pctldev,
+ unsigned pin,
+ 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);
+ int (*pin_config_group_set_bulk) (struct pinctrl_dev *pctldev,
+ unsigned selector,
+ unsigned long *configs,
+ unsigned num_configs);
int (*pin_config_dbg_parse_modify) (struct pinctrl_dev *pctldev,
const char *arg,
unsigned long *config);