diff options
| author | Shawn Guo <shawn.guo@linaro.org> | 2012-05-13 11:19:00 -0400 |
|---|---|---|
| committer | Linus Walleij <linus.walleij@linaro.org> | 2012-05-14 04:42:40 -0400 |
| commit | 3b7ac941e06477a76538038f7e8b70395897a215 (patch) | |
| tree | 068cb0385c6800afeb00aaa83e7d8c39d26e82bd | |
| parent | c7eea50b980b28f4edaa0cfbdf2456532472bc03 (diff) | |
pinctrl: mxs: create group for pin config node
The initial mxs pinctrl support, commit 1772311 (pinctrl: add
pinctrl-mxs support) skipped creating group from device tree pin config
node. Add it to get pin config node work for client device.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
| -rw-r--r-- | drivers/pinctrl/pinctrl-mxs.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index 93cd959971c5..787ae7bb7dc3 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c | |||
| @@ -70,13 +70,18 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
| 70 | struct pinctrl_map **map, unsigned *num_maps) | 70 | struct pinctrl_map **map, unsigned *num_maps) |
| 71 | { | 71 | { |
| 72 | struct pinctrl_map *new_map; | 72 | struct pinctrl_map *new_map; |
| 73 | char *group; | 73 | char *group = NULL; |
| 74 | unsigned new_num; | 74 | unsigned new_num = 1; |
| 75 | unsigned long config = 0; | 75 | unsigned long config = 0; |
| 76 | unsigned long *pconfig; | 76 | unsigned long *pconfig; |
| 77 | int length = strlen(np->name) + SUFFIX_LEN; | 77 | int length = strlen(np->name) + SUFFIX_LEN; |
| 78 | u32 val; | 78 | bool purecfg = false; |
| 79 | int ret; | 79 | u32 val, reg; |
| 80 | int ret, i = 0; | ||
| 81 | |||
| 82 | /* Check for pin config node which has no 'reg' property */ | ||
| 83 | if (of_property_read_u32(np, "reg", ®)) | ||
| 84 | purecfg = true; | ||
| 80 | 85 | ||
| 81 | ret = of_property_read_u32(np, "fsl,drive-strength", &val); | 86 | ret = of_property_read_u32(np, "fsl,drive-strength", &val); |
| 82 | if (!ret) | 87 | if (!ret) |
| @@ -88,21 +93,26 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
| 88 | if (!ret) | 93 | if (!ret) |
| 89 | config |= val << PULL_SHIFT | PULL_PRESENT; | 94 | config |= val << PULL_SHIFT | PULL_PRESENT; |
| 90 | 95 | ||
| 91 | new_num = config ? 2 : 1; | 96 | /* Check for group node which has both mux and config settings */ |
| 97 | if (!purecfg && config) | ||
| 98 | new_num = 2; | ||
| 99 | |||
| 92 | new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL); | 100 | new_map = kzalloc(sizeof(*new_map) * new_num, GFP_KERNEL); |
| 93 | if (!new_map) | 101 | if (!new_map) |
| 94 | return -ENOMEM; | 102 | return -ENOMEM; |
| 95 | 103 | ||
| 96 | new_map[0].type = PIN_MAP_TYPE_MUX_GROUP; | 104 | if (!purecfg) { |
| 97 | new_map[0].data.mux.function = np->name; | 105 | new_map[i].type = PIN_MAP_TYPE_MUX_GROUP; |
| 98 | 106 | new_map[i].data.mux.function = np->name; | |
| 99 | /* Compose group name */ | 107 | |
| 100 | group = kzalloc(length, GFP_KERNEL); | 108 | /* Compose group name */ |
| 101 | if (!group) | 109 | group = kzalloc(length, GFP_KERNEL); |
| 102 | return -ENOMEM; | 110 | if (!group) |
| 103 | of_property_read_u32(np, "reg", &val); | 111 | return -ENOMEM; |
| 104 | snprintf(group, length, "%s.%d", np->name, val); | 112 | snprintf(group, length, "%s.%d", np->name, reg); |
| 105 | new_map[0].data.mux.group = group; | 113 | new_map[i].data.mux.group = group; |
| 114 | i++; | ||
| 115 | } | ||
| 106 | 116 | ||
| 107 | if (config) { | 117 | if (config) { |
| 108 | pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); | 118 | pconfig = kmemdup(&config, sizeof(config), GFP_KERNEL); |
| @@ -111,10 +121,11 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, | |||
| 111 | goto free; | 121 | goto free; |
| 112 | } | 122 | } |
| 113 | 123 | ||
| 114 | new_map[1].type = PIN_MAP_TYPE_CONFIGS_GROUP; | 124 | new_map[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; |
| 115 | new_map[1].data.configs.group_or_pin = group; | 125 | new_map[i].data.configs.group_or_pin = purecfg ? np->name : |
| 116 | new_map[1].data.configs.configs = pconfig; | 126 | group; |
| 117 | new_map[1].data.configs.num_configs = 1; | 127 | new_map[i].data.configs.configs = pconfig; |
| 128 | new_map[i].data.configs.num_configs = 1; | ||
| 118 | } | 129 | } |
| 119 | 130 | ||
| 120 | *map = new_map; | 131 | *map = new_map; |
| @@ -342,8 +353,10 @@ static int __devinit mxs_pinctrl_parse_group(struct platform_device *pdev, | |||
| 342 | group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL); | 353 | group = devm_kzalloc(&pdev->dev, length, GFP_KERNEL); |
| 343 | if (!group) | 354 | if (!group) |
| 344 | return -ENOMEM; | 355 | return -ENOMEM; |
| 345 | of_property_read_u32(np, "reg", &val); | 356 | if (of_property_read_u32(np, "reg", &val)) |
| 346 | snprintf(group, length, "%s.%d", np->name, val); | 357 | snprintf(group, length, "%s", np->name); |
| 358 | else | ||
| 359 | snprintf(group, length, "%s.%d", np->name, val); | ||
| 347 | g->name = group; | 360 | g->name = group; |
| 348 | 361 | ||
| 349 | prop = of_find_property(np, propname, &length); | 362 | prop = of_find_property(np, propname, &length); |
| @@ -367,7 +380,8 @@ static int __devinit mxs_pinctrl_parse_group(struct platform_device *pdev, | |||
| 367 | g->pins[i] = MUXID_TO_PINID(g->pins[i]); | 380 | g->pins[i] = MUXID_TO_PINID(g->pins[i]); |
| 368 | } | 381 | } |
| 369 | 382 | ||
| 370 | *out_name = g->name; | 383 | if (out_name) |
| 384 | *out_name = g->name; | ||
| 371 | 385 | ||
| 372 | return 0; | 386 | return 0; |
| 373 | } | 387 | } |
| @@ -393,6 +407,7 @@ static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, | |||
| 393 | /* Count total functions and groups */ | 407 | /* Count total functions and groups */ |
| 394 | fn = fnull; | 408 | fn = fnull; |
| 395 | for_each_child_of_node(np, child) { | 409 | for_each_child_of_node(np, child) { |
| 410 | soc->ngroups++; | ||
| 396 | /* Skip pure pinconf node */ | 411 | /* Skip pure pinconf node */ |
| 397 | if (of_property_read_u32(child, "reg", &val)) | 412 | if (of_property_read_u32(child, "reg", &val)) |
| 398 | continue; | 413 | continue; |
| @@ -400,7 +415,6 @@ static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, | |||
| 400 | fn = child->name; | 415 | fn = child->name; |
| 401 | soc->nfunctions++; | 416 | soc->nfunctions++; |
| 402 | } | 417 | } |
| 403 | soc->ngroups++; | ||
| 404 | } | 418 | } |
| 405 | 419 | ||
| 406 | soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * | 420 | soc->functions = devm_kzalloc(&pdev->dev, soc->nfunctions * |
| @@ -430,8 +444,14 @@ static int __devinit mxs_pinctrl_probe_dt(struct platform_device *pdev, | |||
| 430 | idxf = 0; | 444 | idxf = 0; |
| 431 | fn = fnull; | 445 | fn = fnull; |
| 432 | for_each_child_of_node(np, child) { | 446 | for_each_child_of_node(np, child) { |
| 433 | if (of_property_read_u32(child, "reg", &val)) | 447 | if (of_property_read_u32(child, "reg", &val)) { |
| 448 | ret = mxs_pinctrl_parse_group(pdev, child, | ||
| 449 | idxg++, NULL); | ||
| 450 | if (ret) | ||
| 451 | return ret; | ||
| 434 | continue; | 452 | continue; |
| 453 | } | ||
| 454 | |||
| 435 | if (strcmp(fn, child->name)) { | 455 | if (strcmp(fn, child->name)) { |
| 436 | f = &soc->functions[idxf++]; | 456 | f = &soc->functions[idxf++]; |
| 437 | f->groups = devm_kzalloc(&pdev->dev, f->ngroups * | 457 | f->groups = devm_kzalloc(&pdev->dev, f->ngroups * |
