diff options
| author | Sherman Yin <syin@broadcom.com> | 2013-08-27 14:32:12 -0400 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2013-08-28 07:34:41 -0400 |
| commit | 03b054e9696c3cbd3d5905ec96da15acd0a2fe8d (patch) | |
| tree | 7123b780c194d350b3e5134c267e17262effb385 | |
| parent | f5ba9c52bf1e236c4698c240955e5f119db62a28 (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>
24 files changed, 952 insertions, 726 deletions
diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index bb7ddb1bc89f..e78c041c3c73 100644 --- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c | |||
| @@ -191,18 +191,27 @@ static int mvebu_pinconf_group_get(struct pinctrl_dev *pctldev, | |||
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, | 193 | static int mvebu_pinconf_group_set(struct pinctrl_dev *pctldev, |
| 194 | unsigned gid, unsigned long config) | 194 | unsigned gid, unsigned long *configs, |
| 195 | unsigned num_configs) | ||
| 195 | { | 196 | { |
| 196 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | 197 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
| 197 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | 198 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; |
| 199 | int i, ret; | ||
| 198 | 200 | ||
| 199 | if (!grp->ctrl) | 201 | if (!grp->ctrl) |
| 200 | return -EINVAL; | 202 | return -EINVAL; |
| 201 | 203 | ||
| 202 | if (grp->ctrl->mpp_set) | 204 | for (i = 0; i < num_configs; i++) { |
| 203 | return grp->ctrl->mpp_set(grp->ctrl, config); | 205 | if (grp->ctrl->mpp_set) |
| 206 | ret = grp->ctrl->mpp_set(grp->ctrl, configs[i]); | ||
| 207 | else | ||
| 208 | ret = mvebu_common_mpp_set(pctl, grp, configs[i]); | ||
| 204 | 209 | ||
| 205 | return mvebu_common_mpp_set(pctl, grp, config); | 210 | if (ret) |
| 211 | return ret; | ||
| 212 | } /* for each config */ | ||
| 213 | |||
| 214 | return 0; | ||
| 206 | } | 215 | } |
| 207 | 216 | ||
| 208 | static void mvebu_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, | 217 | 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 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; | 312 | struct mvebu_pinctrl_group *grp = &pctl->groups[gid]; |
| 304 | struct mvebu_mpp_ctrl_setting *setting; | 313 | struct mvebu_mpp_ctrl_setting *setting; |
| 305 | int ret; | 314 | int ret; |
| 315 | unsigned long config; | ||
| 306 | 316 | ||
| 307 | setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, | 317 | setting = mvebu_pinctrl_find_setting_by_name(pctl, grp, |
| 308 | func->name); | 318 | func->name); |
| @@ -313,7 +323,8 @@ static int mvebu_pinmux_enable(struct pinctrl_dev *pctldev, unsigned fid, | |||
| 313 | return -EINVAL; | 323 | return -EINVAL; |
| 314 | } | 324 | } |
| 315 | 325 | ||
| 316 | ret = mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); | 326 | config = setting->val; |
| 327 | ret = mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1); | ||
| 317 | if (ret) { | 328 | if (ret) { |
| 318 | dev_err(pctl->dev, "cannot set group %s to %s\n", | 329 | dev_err(pctl->dev, "cannot set group %s to %s\n", |
| 319 | func->groups[gid], func->name); | 330 | func->groups[gid], func->name); |
| @@ -329,6 +340,7 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
| 329 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); | 340 | struct mvebu_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); |
| 330 | struct mvebu_pinctrl_group *grp; | 341 | struct mvebu_pinctrl_group *grp; |
| 331 | struct mvebu_mpp_ctrl_setting *setting; | 342 | struct mvebu_mpp_ctrl_setting *setting; |
| 343 | unsigned long config; | ||
| 332 | 344 | ||
| 333 | grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); | 345 | grp = mvebu_pinctrl_find_group_by_pid(pctl, offset); |
| 334 | if (!grp) | 346 | if (!grp) |
| @@ -341,7 +353,9 @@ static int mvebu_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev, | |||
| 341 | if (!setting) | 353 | if (!setting) |
| 342 | return -ENOTSUPP; | 354 | return -ENOTSUPP; |
| 343 | 355 | ||
| 344 | return mvebu_pinconf_group_set(pctldev, grp->gid, setting->val); | 356 | config = setting->val; |
| 357 | |||
| 358 | return mvebu_pinconf_group_set(pctldev, grp->gid, &config, 1); | ||
| 345 | } | 359 | } |
| 346 | 360 | ||
| 347 | static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, | 361 | static int mvebu_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, |
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 8da2d6db228c..a138965c01cb 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c | |||
| @@ -158,7 +158,7 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) | |||
| 158 | { | 158 | { |
| 159 | struct pinctrl_dev *pctldev = setting->pctldev; | 159 | struct pinctrl_dev *pctldev = setting->pctldev; |
| 160 | const struct pinconf_ops *ops = pctldev->desc->confops; | 160 | const struct pinconf_ops *ops = pctldev->desc->confops; |
| 161 | int i, ret; | 161 | int ret; |
| 162 | 162 | ||
| 163 | if (!ops) { | 163 | if (!ops) { |
| 164 | dev_err(pctldev->dev, "missing confops\n"); | 164 | dev_err(pctldev->dev, "missing confops\n"); |
| @@ -171,17 +171,15 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) | |||
| 171 | dev_err(pctldev->dev, "missing pin_config_set op\n"); | 171 | dev_err(pctldev->dev, "missing pin_config_set op\n"); |
| 172 | return -EINVAL; | 172 | return -EINVAL; |
| 173 | } | 173 | } |
| 174 | for (i = 0; i < setting->data.configs.num_configs; i++) { | 174 | ret = ops->pin_config_set(pctldev, |
| 175 | ret = ops->pin_config_set(pctldev, | 175 | setting->data.configs.group_or_pin, |
| 176 | setting->data.configs.group_or_pin, | 176 | setting->data.configs.configs, |
| 177 | setting->data.configs.configs[i]); | 177 | setting->data.configs.num_configs); |
| 178 | if (ret < 0) { | 178 | if (ret < 0) { |
| 179 | dev_err(pctldev->dev, | 179 | dev_err(pctldev->dev, |
| 180 | "pin_config_set op failed for pin %d config %08lx\n", | 180 | "pin_config_set op failed for pin %d\n", |
| 181 | setting->data.configs.group_or_pin, | 181 | setting->data.configs.group_or_pin); |
| 182 | setting->data.configs.configs[i]); | 182 | return ret; |
| 183 | return ret; | ||
| 184 | } | ||
| 185 | } | 183 | } |
| 186 | break; | 184 | break; |
| 187 | case PIN_MAP_TYPE_CONFIGS_GROUP: | 185 | case PIN_MAP_TYPE_CONFIGS_GROUP: |
| @@ -190,17 +188,15 @@ int pinconf_apply_setting(struct pinctrl_setting const *setting) | |||
| 190 | "missing pin_config_group_set op\n"); | 188 | "missing pin_config_group_set op\n"); |
| 191 | return -EINVAL; | 189 | return -EINVAL; |
| 192 | } | 190 | } |
| 193 | for (i = 0; i < setting->data.configs.num_configs; i++) { | 191 | ret = ops->pin_config_group_set(pctldev, |
| 194 | ret = ops->pin_config_group_set(pctldev, | 192 | setting->data.configs.group_or_pin, |
| 195 | setting->data.configs.group_or_pin, | 193 | setting->data.configs.configs, |
| 196 | setting->data.configs.configs[i]); | 194 | setting->data.configs.num_configs); |
| 197 | if (ret < 0) { | 195 | if (ret < 0) { |
| 198 | dev_err(pctldev->dev, | 196 | dev_err(pctldev->dev, |
| 199 | "pin_config_group_set op failed for group %d config %08lx\n", | 197 | "pin_config_group_set op failed for group %d\n", |
| 200 | setting->data.configs.group_or_pin, | 198 | setting->data.configs.group_or_pin); |
