diff options
| author | Soren Brinkmann <soren.brinkmann@xilinx.com> | 2015-01-09 10:43:51 -0500 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2015-01-14 08:10:09 -0500 |
| commit | 7382b6231591a76d061d04a420937bbc5e1c1106 (patch) | |
| tree | bf609d22d0f0a70d5dd383cc45f940b966bce6ac /drivers/pinctrl/qcom | |
| parent | add958cee967df0a6d003e59b104ba9a6f263e00 (diff) | |
pinctrl: qcom-spmi-gpio: Migrate to pinconf-generic
Instead of the driver caring about implementation details like device
tree, just provide information about driver specific pinconf parameters
to pinconf-generic which takes care of parsing the DT.
Signed-off-by: Soren Brinkmann <soren.brinkmann@xilinx.com>
Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/qcom')
| -rw-r--r-- | drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | 125 |
1 files changed, 11 insertions, 114 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c index b863b5080890..17f811c9c2c0 100644 --- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c +++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c | |||
| @@ -131,14 +131,14 @@ struct pmic_gpio_state { | |||
| 131 | struct gpio_chip chip; | 131 | struct gpio_chip chip; |
| 132 | }; | 132 | }; |
| 133 | 133 | ||
| 134 | struct pmic_gpio_bindings { | 134 | static const struct pinconf_generic_dt_params pmic_gpio_bindings[] = { |
| 135 | const char *property; | 135 | {"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP, 0}, |
| 136 | unsigned param; | 136 | {"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH, 0}, |
| 137 | }; | 137 | }; |
| 138 | 138 | ||
| 139 | static struct pmic_gpio_bindings pmic_gpio_bindings[] = { | 139 | static const struct pin_config_item pmic_conf_items[ARRAY_SIZE(pmic_gpio_bindings)] = { |
| 140 | {"qcom,pull-up-strength", PMIC_GPIO_CONF_PULL_UP}, | 140 | PCONFDUMP(PMIC_GPIO_CONF_PULL_UP, "pull up strength", NULL, true), |
| 141 | {"qcom,drive-strength", PMIC_GPIO_CONF_STRENGTH}, | 141 | PCONFDUMP(PMIC_GPIO_CONF_STRENGTH, "drive-strength", NULL, true), |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | static const char *const pmic_gpio_groups[] = { | 144 | static const char *const pmic_gpio_groups[] = { |
| @@ -209,118 +209,11 @@ static int pmic_gpio_get_group_pins(struct pinctrl_dev *pctldev, unsigned pin, | |||
| 209 | return 0; | 209 | return 0; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | static int pmic_gpio_parse_dt_config(struct device_node *np, | ||
| 213 | struct pinctrl_dev *pctldev, | ||
| 214 | unsigned long **configs, | ||
| 215 | unsigned int *nconfs) | ||
| 216 | { | ||
| 217 | struct pmic_gpio_bindings *par; | ||
| 218 | unsigned long cfg; | ||
| 219 | int ret, i; | ||
| 220 | u32 val; | ||
| 221 | |||
| 222 | for (i = 0; i < ARRAY_SIZE(pmic_gpio_bindings); i++) { | ||
| 223 | par = &pmic_gpio_bindings[i]; | ||
| 224 | ret = of_property_read_u32(np, par->property, &val); | ||
| 225 | |||
| 226 | /* property not found */ | ||
| 227 | if (ret == -EINVAL) | ||
| 228 | continue; | ||
| 229 | |||
| 230 | /* use zero as default value */ | ||
| 231 | if (ret) | ||
| 232 | val = 0; | ||
| 233 | |||
| 234 | dev_dbg(pctldev->dev, "found %s with value %u\n", | ||
| 235 | par->property, val); | ||
| 236 | |||
| 237 | cfg = pinconf_to_config_packed(par->param, val); | ||
| 238 | |||
| 239 | ret = pinctrl_utils_add_config(pctldev, configs, nconfs, cfg); | ||
| 240 | if (ret) | ||
| 241 | return ret; | ||
| 242 | } | ||
| 243 | |||
| 244 | return 0; | ||
| 245 | } | ||
| 246 | |||
| 247 | static int pmic_gpio_dt_subnode_to_map(struct pinctrl_dev *pctldev, | ||
| 248 | struct device_node *np, | ||
| 249 | struct pinctrl_map **map, | ||
| 250 | unsigned *reserv, unsigned *nmaps, | ||
| 251 | enum pinctrl_map_type type) | ||
| 252 | { | ||
| 253 | unsigned long *configs = NULL; | ||
| 254 | unsigned nconfs = 0; | ||
| 255 | struct property *prop; | ||
| 256 | const char *group; | ||
| 257 | int ret; | ||
| 258 | |||
| 259 | ret = pmic_gpio_parse_dt_config(np, pctldev, &configs, &nconfs); | ||
| 260 | if (ret < 0) | ||
| 261 | return ret; | ||
| 262 | |||
| 263 | if (!nconfs) | ||
| 264 | return 0; | ||
| 265 | |||
| 266 | ret = of_property_count_strings(np, "pins"); | ||
| 267 | if (ret < 0) | ||
| 268 | goto exit; | ||
| 269 | |||
| 270 | ret = pinctrl_utils_reserve_map(pctldev, map, reserv, nmaps, ret); | ||
| 271 | if (ret < 0) | ||
| 272 | goto exit; | ||
| 273 | |||
| 274 | of_property_for_each_string(np, "pins", prop, group) { | ||
| 275 | ret = pinctrl_utils_add_map_configs(pctldev, map, | ||
| 276 | reserv, nmaps, group, | ||
| 277 | configs, nconfs, type); | ||
| 278 | if (ret < 0) | ||
| 279 | break; | ||
| 280 | } | ||
| 281 | exit: | ||
| 282 | kfree(configs); | ||
| 283 | return ret; | ||
| 284 | } | ||
| 285 | |||
| 286 | static int pmic_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
| 287 | struct device_node *np_config, | ||
| 288 | struct pinctrl_map **map, unsigned *nmaps) | ||
| 289 | { | ||
| 290 | enum pinctrl_map_type type; | ||
| 291 | struct device_node *np; | ||
| 292 | unsigned reserv; | ||
| 293 | int ret; | ||
| 294 | |||
| 295 | ret = 0; | ||
| 296 | *map = NULL; | ||
| 297 | *nmaps = 0; | ||
| 298 | reserv = 0; | ||
| 299 | type = PIN_MAP_TYPE_CONFIGS_GROUP; | ||
| 300 | |||
| 301 | for_each_child_of_node(np_config, np) { | ||
| 302 | ret = pinconf_generic_dt_subnode_to_map(pctldev, np, map, | ||
| 303 | &reserv, nmaps, type); | ||
| 304 | if (ret) | ||
| 305 | break; | ||
| 306 | |||
| 307 | ret = pmic_gpio_dt_subnode_to_map(pctldev, np, map, &reserv, | ||
| 308 | nmaps, type); | ||
| 309 | if (ret) | ||
| 310 | break; | ||
| 311 | } | ||
| 312 | |||
| 313 | if (ret < 0) | ||
| 314 | pinctrl_utils_dt_free_map(pctldev, *map, *nmaps); | ||
| 315 | |||
| 316 | return ret; | ||
| 317 | } | ||
| 318 | |||
| 319 | static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { | 212 | static const struct pinctrl_ops pmic_gpio_pinctrl_ops = { |
| 320 | .get_groups_count = pmic_gpio_get_groups_count, | 213 | .get_groups_count = pmic_gpio_get_groups_count, |
| 321 | .get_group_name = pmic_gpio_get_group_name, | 214 | .get_group_name = pmic_gpio_get_group_name, |
| 322 | .get_group_pins = pmic_gpio_get_group_pins, | 215 | .get_group_pins = pmic_gpio_get_group_pins, |
| 323 | .dt_node_to_map = pmic_gpio_dt_node_to_map, | 216 | .dt_node_to_map = pinconf_generic_dt_node_to_map_group, |
| 324 | .dt_free_map = pinctrl_utils_dt_free_map, | 217 | .dt_free_map = pinctrl_utils_dt_free_map, |
| 325 | }; | 218 | }; |
| 326 | 219 | ||
| @@ -590,6 +483,7 @@ static void pmic_gpio_config_dbg_show(struct pinctrl_dev *pctldev, | |||
| 590 | } | 483 | } |
| 591 | 484 | ||
| 592 | static const struct pinconf_ops pmic_gpio_pinconf_ops = { | 485 | static const struct pinconf_ops pmic_gpio_pinconf_ops = { |
| 486 | .is_generic = true, | ||
| 593 | .pin_config_group_get = pmic_gpio_config_get, | 487 | .pin_config_group_get = pmic_gpio_config_get, |
| 594 | .pin_config_group_set = pmic_gpio_config_set, | 488 | .pin_config_group_set = pmic_gpio_config_set, |
| 595 | .pin_config_group_dbg_show = pmic_gpio_config_dbg_show, | 489 | .pin_config_group_dbg_show = pmic_gpio_config_dbg_show, |
| @@ -848,6 +742,9 @@ static int pmic_gpio_probe(struct platform_device *pdev) | |||
| 848 | pctrldesc->name = dev_name(dev); | 742 | pctrldesc->name = dev_name(dev); |
| 849 | pctrldesc->pins = pindesc; | 743 | pctrldesc->pins = pindesc; |
| 850 | pctrldesc->npins = npins; | 744 | pctrldesc->npins = npins; |
| 745 | pctrldesc->num_dt_params = ARRAY_SIZE(pmic_gpio_bindings); | ||
| 746 | pctrldesc->params = pmic_gpio_bindings; | ||
| 747 | pctrldesc->conf_items = pmic_conf_items; | ||
| 851 | 748 | ||
| 852 | for (i = 0; i < npins; i++, pindesc++) { | 749 | for (i = 0; i < npins; i++, pindesc++) { |
| 853 | pad = &pads[i]; | 750 | pad = &pads[i]; |
