diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-03-02 15:05:45 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-03-05 05:20:50 -0500 |
commit | 7ecdb16fe63e5b356335ebdc236adfb48cef31e1 (patch) | |
tree | 036d9939c64f98e1f85343f15c12ad83c9a2a890 /drivers/pinctrl | |
parent | 57b676f9c1b7cd84397fe5a86c9bd2788ac4bd32 (diff) |
pinctrl: refactor struct pinctrl handling in core.c vs pinmux.c
This change separates two aspects of struct pinctrl:
a) The data representation of the parsed mapping table, into:
1) The top-level struct pinctrl object, a single entity returned
by pinctrl_get().
2) The parsed version of each mapping table entry, struct
pinctrl_setting, of which there is one per mapping table entry.
b) The code that handles this; the code for (1) above is in core.c, and
the code to parse/execute each entry in (2) above is in pinmux.c, while
the iteration over multiple settings is lifted to core.c.
This will allow the following future changes:
1) pinctrl_get() API rework, so that struct pinctrl represents all states
for the device, and the device can select between them without calling
put()/get() again.
2) To support that, a struct pinctrl_state object will be inserted into
the data model between the struct pinctrl and struct pinctrl_setting.
3) The mapping table will be extended to allow specification of pin config
settings too. To support this, struct pinctrl_setting will be enhanced
to store either mux settings or config settings, and functions will be
added to pinconf.c to parse/execute pin configuration settings.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r-- | drivers/pinctrl/core.c | 105 | ||||
-rw-r--r-- | drivers/pinctrl/core.h | 25 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.c | 402 | ||||
-rw-r--r-- | drivers/pinctrl/pinmux.h | 41 |
4 files changed, 197 insertions, 376 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index aefc3394db91..535f8d53c289 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -460,14 +460,15 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); | |||
460 | 460 | ||
461 | static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) | 461 | static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) |
462 | { | 462 | { |
463 | struct pinctrl_dev *pctldev = NULL; | 463 | struct pinctrl_dev *pctldev; |
464 | const char *devname; | 464 | const char *devname; |
465 | struct pinctrl *p; | 465 | struct pinctrl *p; |
466 | unsigned num_maps = 0; | 466 | unsigned num_maps = 0; |
467 | int ret = -ENODEV; | 467 | int ret; |
468 | struct pinctrl_maps *maps_node; | 468 | struct pinctrl_maps *maps_node; |
469 | int i; | 469 | int i; |
470 | struct pinctrl_map const *map; | 470 | struct pinctrl_map const *map; |
471 | struct pinctrl_setting *setting; | ||
471 | 472 | ||
472 | /* We must have both a dev and state name */ | 473 | /* We must have both a dev and state name */ |
473 | if (WARN_ON(!dev || !name)) | 474 | if (WARN_ON(!dev || !name)) |
@@ -487,39 +488,50 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) | |||
487 | dev_err(dev, "failed to alloc struct pinctrl\n"); | 488 | dev_err(dev, "failed to alloc struct pinctrl\n"); |
488 | return ERR_PTR(-ENOMEM); | 489 | return ERR_PTR(-ENOMEM); |
489 | } | 490 | } |
490 | pinmux_init_pinctrl_handle(p); | 491 | p->dev = dev; |
492 | p->state = name; | ||
493 | INIT_LIST_HEAD(&p->settings); | ||
491 | 494 | ||
492 | /* Iterate over the pin control maps to locate the right ones */ | 495 | /* Iterate over the pin control maps to locate the right ones */ |
493 | for_each_maps(maps_node, i, map) { | 496 | for_each_maps(maps_node, i, map) { |
497 | /* Map must be for this device */ | ||
498 | if (strcmp(map->dev_name, devname)) | ||
499 | continue; | ||
500 | |||
501 | /* State name must be the one we're looking for */ | ||
502 | if (strcmp(map->name, name)) | ||
503 | continue; | ||
504 | |||
494 | /* | 505 | /* |
495 | * First, try to find the pctldev given in the map | 506 | * Try to find the pctldev given in the map |
496 | */ | 507 | */ |
497 | pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); | 508 | pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); |
498 | if (!pctldev) { | 509 | if (!pctldev) { |
499 | dev_err(dev, "unknown pinctrl device %s in map entry", | 510 | dev_err(dev, "unknown pinctrl device %s in map entry", |
500 | map->ctrl_dev_name); | 511 | map->ctrl_dev_name); |
501 | pinmux_put(p); | ||
502 | kfree(p); | ||
503 | /* Eventually, this should trigger deferred probe */ | 512 | /* Eventually, this should trigger deferred probe */ |
504 | return ERR_PTR(-ENODEV); | 513 | ret = -ENODEV; |
514 | goto error; | ||
505 | } | 515 | } |
506 | 516 | ||
507 | dev_dbg(dev, "in map, found pctldev %s to handle function %s", | 517 | dev_dbg(dev, "in map, found pctldev %s to handle function %s", |
508 | dev_name(pctldev->dev), map->function); | 518 | dev_name(pctldev->dev), map->function); |
509 | 519 | ||
510 | /* Map must be for this device */ | 520 | setting = kzalloc(sizeof(*setting), GFP_KERNEL); |
511 | if (strcmp(map->dev_name, devname)) | 521 | if (setting == NULL) { |
512 | continue; | 522 | dev_err(dev, |
523 | "failed to alloc struct pinctrl_setting\n"); | ||
524 | ret = -ENOMEM; | ||
525 | goto error; | ||
526 | } | ||
513 | 527 | ||
514 | /* State name must be the one we're looking for */ | 528 | setting->pctldev = pctldev; |
515 | if (strcmp(map->name, name)) | 529 | ret = pinmux_map_to_setting(map, setting); |
516 | continue; | 530 | if (ret < 0) |
531 | goto error; | ||
532 | |||
533 | list_add_tail(&setting->node, &p->settings); | ||
517 | 534 | ||
518 | ret = pinmux_apply_muxmap(pctldev, p, dev, devname, map); | ||
519 | if (ret) { | ||
520 | kfree(p); | ||
521 | return ERR_PTR(ret); | ||
522 | } | ||
523 | num_maps++; | 535 | num_maps++; |
524 | } | 536 | } |
525 | 537 | ||
@@ -541,6 +553,14 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) | |||
541 | list_add_tail(&p->node, &pinctrl_list); | 553 | list_add_tail(&p->node, &pinctrl_list); |
542 | 554 | ||
543 | return p; | 555 | return p; |
556 | |||
557 | error: | ||
558 | list_for_each_entry(setting, &p->settings, node) | ||
559 | pinmux_free_setting(setting); | ||
560 | |||
561 | kfree(p); | ||
562 | |||
563 | return ERR_PTR(ret); | ||
544 | } | 564 | } |
545 | 565 | ||
546 | /** | 566 | /** |
@@ -564,13 +584,18 @@ EXPORT_SYMBOL_GPL(pinctrl_get); | |||
564 | 584 | ||
565 | static void pinctrl_put_locked(struct pinctrl *p) | 585 | static void pinctrl_put_locked(struct pinctrl *p) |
566 | { | 586 | { |
587 | struct pinctrl_setting *setting, *n; | ||
588 | |||
567 | if (p == NULL) | 589 | if (p == NULL) |
568 | return; | 590 | return; |
569 | 591 | ||
570 | if (p->usecount) | 592 | if (p->usecount) |
571 | pr_warn("releasing pin control handle with active users!\n"); | 593 | pr_warn("releasing pin control handle with active users!\n"); |
572 | /* Free the groups and all acquired pins */ | 594 | list_for_each_entry_safe(setting, n, &p->settings, node) { |
573 | pinmux_put(p); | 595 | pinmux_free_setting(setting); |
596 | list_del(&setting->node); | ||
597 | kfree(setting); | ||
598 | } | ||
574 | 599 | ||
575 | /* Remove from list */ | 600 | /* Remove from list */ |
576 | list_del(&p->node); | 601 | list_del(&p->node); |
@@ -592,18 +617,24 @@ EXPORT_SYMBOL_GPL(pinctrl_put); | |||
592 | 617 | ||
593 | static int pinctrl_enable_locked(struct pinctrl *p) | 618 | static int pinctrl_enable_locked(struct pinctrl *p) |
594 | { | 619 | { |
595 | int ret = 0; | 620 | struct pinctrl_setting *setting; |
621 | int ret; | ||
596 | 622 | ||
597 | if (p == NULL) | 623 | if (p == NULL) |
598 | return -EINVAL; | 624 | return -EINVAL; |
599 | 625 | ||
600 | if (p->usecount++ == 0) { | 626 | if (p->usecount++ == 0) { |
601 | ret = pinmux_enable(p); | 627 | list_for_each_entry(setting, &p->settings, node) { |
602 | if (ret) | 628 | ret = pinmux_enable_setting(setting); |
603 | p->usecount--; | 629 | if (ret < 0) { |
630 | /* FIXME: Difficult to return to prev state */ | ||
631 | p->usecount--; | ||
632 | return ret; | ||
633 | } | ||
634 | } | ||
604 | } | 635 | } |
605 | 636 | ||
606 | return ret; | 637 | return 0; |
607 | } | 638 | } |
608 | 639 | ||
609 | /** | 640 | /** |
@@ -622,11 +653,14 @@ EXPORT_SYMBOL_GPL(pinctrl_enable); | |||
622 | 653 | ||
623 | static void pinctrl_disable_locked(struct pinctrl *p) | 654 | static void pinctrl_disable_locked(struct pinctrl *p) |
624 | { | 655 | { |
656 | struct pinctrl_setting *setting; | ||
657 | |||
625 | if (p == NULL) | 658 | if (p == NULL) |
626 | return; | 659 | return; |
627 | 660 | ||
628 | if (--p->usecount == 0) { | 661 | if (--p->usecount == 0) { |
629 | pinmux_disable(p); | 662 | list_for_each_entry(setting, &p->settings, node) |
663 | pinmux_disable_setting(setting); | ||
630 | } | 664 | } |
631 | } | 665 | } |
632 | 666 | ||
@@ -857,27 +891,20 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) | |||
857 | static int pinctrl_show(struct seq_file *s, void *what) | 891 | static int pinctrl_show(struct seq_file *s, void *what) |
858 | { | 892 | { |
859 | struct pinctrl *p; | 893 | struct pinctrl *p; |
894 | struct pinctrl_setting *setting; | ||
860 | 895 | ||
861 | seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); | 896 | seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); |
862 | 897 | ||
863 | mutex_lock(&pinctrl_mutex); | 898 | mutex_lock(&pinctrl_mutex); |
864 | 899 | ||
865 | list_for_each_entry(p, &pinctrl_list, node) { | 900 | list_for_each_entry(p, &pinctrl_list, node) { |
866 | struct pinctrl_dev *pctldev = p->pctldev; | 901 | seq_printf(s, "device: %s state: %s users: %u\n", |
902 | dev_name(p->dev), p->state, p->usecount); | ||
867 | 903 | ||
868 | if (!pctldev) { | 904 | list_for_each_entry(setting, &p->settings, node) { |
869 | seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); | 905 | seq_printf(s, " "); |
870 | continue; | 906 | pinmux_dbg_show(s, setting); |
871 | } | 907 | } |
872 | |||
873 | seq_printf(s, "device: %s", | ||
874 | pinctrl_dev_get_name(p->pctldev)); | ||
875 | |||
876 | pinmux_dbg_show(s, p); | ||
877 | |||
878 | seq_printf(s, " users: %u map-> %s\n", | ||
879 | p->usecount, | ||
880 | p->dev ? dev_name(p->dev) : "(system)"); | ||
881 | } | 908 | } |
882 | 909 | ||
883 | mutex_unlock(&pinctrl_mutex); | 910 | mutex_unlock(&pinctrl_mutex); |
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8808f25a07d4..5f258b793400 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h | |||
@@ -49,22 +49,31 @@ struct pinctrl_dev { | |||
49 | * struct pinctrl - per-device pin control state holder | 49 | * struct pinctrl - per-device pin control state holder |
50 | * @node: global list node | 50 | * @node: global list node |
51 | * @dev: the device using this pin control handle | 51 | * @dev: the device using this pin control handle |
52 | * @state: the state name passed to pinctrl_get() | ||
52 | * @usecount: the number of active users of this pin controller setting, used | 53 | * @usecount: the number of active users of this pin controller setting, used |
53 | * to keep track of nested use cases | 54 | * to keep track of nested use cases |
54 | * @pctldev: pin control device handling this pin control handle | 55 | * @settings: a list of settings for this device/state |
55 | * @groups: the group selectors for the pinmux device and | ||
56 | * selector combination handling this pinmux, this is a list that | ||
57 | * will be traversed on all pinmux operations such as | ||
58 | * get/put/enable/disable | ||
59 | */ | 56 | */ |
60 | struct pinctrl { | 57 | struct pinctrl { |
61 | struct list_head node; | 58 | struct list_head node; |
62 | struct device *dev; | 59 | struct device *dev; |
60 | const char *state; | ||
63 | unsigned usecount; | 61 | unsigned usecount; |
62 | struct list_head settings; | ||
63 | }; | ||
64 | |||
65 | /** | ||
66 | * struct pinctrl_setting - an individual mux setting | ||
67 | * @node: list node for struct pinctrl's @settings field | ||
68 | * @pctldev: pin control device handling to be programmed | ||
69 | * @group_selector: the group selector to program | ||
70 | * @func_selector: the function selector to program | ||
71 | */ | ||
72 | struct pinctrl_setting { | ||
73 | struct list_head node; | ||
64 | struct pinctrl_dev *pctldev; | 74 | struct pinctrl_dev *pctldev; |
65 | #ifdef CONFIG_PINMUX | 75 | unsigned group_selector; |
66 | struct list_head groups; | 76 | unsigned func_selector; |
67 | #endif | ||
68 | }; | 77 | }; |
69 | 78 | ||
70 | /** | 79 | /** |
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 7342c26f4246..f0fb98d252e8 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * | 7 | * |
8 | * Author: Linus Walleij <linus.walleij@linaro.org> | 8 | * Author: Linus Walleij <linus.walleij@linaro.org> |
9 | * | 9 | * |
10 | * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. | ||
11 | * | ||
10 | * License terms: GNU General Public License (GPL) version 2 | 12 | * License terms: GNU General Public License (GPL) version 2 |
11 | */ | 13 | */ |
12 | #define pr_fmt(fmt) "pinmux core: " fmt | 14 | #define pr_fmt(fmt) "pinmux core: " fmt |
@@ -28,19 +30,6 @@ | |||
28 | #include "core.h" | 30 | #include "core.h" |
29 | #include "pinmux.h" | 31 | #include "pinmux.h" |
30 | 32 | ||
31 | /** | ||
32 | * struct pinmux_group - group list item for pinmux groups | ||
33 | * @node: pinmux group list node | ||
34 | * @func_selector: the function selector for the pinmux device handling | ||
35 | * this pinmux | ||
36 | * @group_selector: the group selector for this group | ||
37 | */ | ||
38 | struct pinmux_group { | ||
39 | struct list_head node; | ||
40 | unsigned func_selector; | ||
41 | unsigned group_selector; | ||
42 | }; | ||
43 | |||
44 | int pinmux_check_ops(struct pinctrl_dev *pctldev) | 33 | int pinmux_check_ops(struct pinctrl_dev *pctldev) |
45 | { | 34 | { |
46 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 35 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
@@ -244,164 +233,8 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, | |||
244 | return ret; | 233 | return ret; |
245 | } | 234 | } |
246 | 235 | ||
247 | /** | 236 | static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, |
248 | * acquire_pins() - acquire all the pins for a certain function on a pinmux | 237 | const char *function) |
249 | * @pctldev: the device to take the pins on | ||
250 | * @owner: a representation of the owner of this pin; typically the device | ||
251 | * name that controls its mux function | ||
252 | * @group_selector: the group selector containing the pins to acquire | ||
253 | */ | ||
254 | static int acquire_pins(struct pinctrl_dev *pctldev, | ||
255 | const char *owner, | ||
256 | unsigned group_selector) | ||
257 | { | ||
258 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
259 | const unsigned *pins; | ||
260 | unsigned num_pins; | ||
261 | int ret; | ||
262 | int i; | ||
263 | |||
264 | ret = pctlops->get_group_pins(pctldev, group_selector, | ||
265 | &pins, &num_pins); | ||
266 | if (ret) | ||
267 | return ret; | ||
268 | |||
269 | dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n", | ||
270 | num_pins, group_selector); | ||
271 | |||
272 | /* Try to allocate all pins in this group, one by one */ | ||
273 | for (i = 0; i < num_pins; i++) { | ||
274 | ret = pin_request(pctldev, pins[i], owner, NULL); | ||
275 | if (ret) { | ||
276 | dev_err(pctldev->dev, | ||
277 | "could not get request pin %d on device %s - conflicting mux mappings?\n", | ||
278 | pins[i], | ||
279 | pinctrl_dev_get_name(pctldev)); | ||
280 | /* On error release all taken pins */ | ||
281 | i--; /* this pin just failed */ | ||
282 | for (; i >= 0; i--) | ||
283 | pin_free(pctldev, pins[i], NULL); | ||
284 | return -ENODEV; | ||
285 | } | ||
286 | } | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * release_pins() - release pins taken by earlier acquirement | ||
292 | * @pctldev: the device to free the pins on | ||
293 | * @group_selector: the group selector containing the pins to free | ||
294 | */ | ||
295 | static void release_pins(struct pinctrl_dev *pctldev, | ||
296 | unsigned group_selector) | ||
297 | { | ||
298 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
299 | const unsigned *pins; | ||
300 | unsigned num_pins; | ||
301 | int ret; | ||
302 | int i; | ||
303 | |||
304 | ret = pctlops->get_group_pins(pctldev, group_selector, | ||
305 | &pins, &num_pins); | ||
306 | if (ret) { | ||
307 | dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", | ||
308 | group_selector); | ||
309 | return; | ||
310 | } | ||
311 | for (i = 0; i < num_pins; i++) | ||
312 | pin_free(pctldev, pins[i], NULL); | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * pinmux_check_pin_group() - check function and pin group combo | ||
317 | * @pctldev: device to check the pin group vs function for | ||
318 | * @func_selector: the function selector to check the pin group for, we have | ||
319 | * already looked this up in the calling function | ||
320 | * @pin_group: the pin group to match to the function | ||
321 | * | ||
322 | * This function will check that the pinmux driver can supply the | ||
323 | * selected pin group for a certain function, returns the group selector if | ||
324 | * the group and function selector will work fine together, else returns | ||
325 | * negative | ||
326 | */ | ||
327 | static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, | ||
328 | unsigned func_selector, | ||
329 | const char *pin_group) | ||
330 | { | ||
331 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; | ||
332 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
333 | int ret; | ||
334 | |||
335 | /* | ||
336 | * If the driver does not support different pin groups for the | ||
337 | * functions, we only support group 0, and assume this exists. | ||
338 | */ | ||
339 | if (!pctlops || !pctlops->list_groups) | ||
340 | return 0; | ||
341 | |||
342 | /* | ||
343 | * Passing NULL (no specific group) will select the first and | ||
344 | * hopefully only group of pins available for this function. | ||
345 | */ | ||
346 | if (!pin_group) { | ||
347 | char const * const *groups; | ||
348 | unsigned num_groups; | ||
349 | |||
350 | ret = pmxops->get_function_groups(pctldev, func_selector, | ||
351 | &groups, &num_groups); | ||
352 | if (ret) | ||
353 | return ret; | ||
354 | if (num_groups < 1) | ||
355 | return -EINVAL; | ||
356 | ret = pinctrl_get_group_selector(pctldev, groups[0]); | ||
357 | if (ret < 0) { | ||
358 | dev_err(pctldev->dev, | ||
359 | "function %s wants group %s but the pin controller does not seem to have that group\n", | ||
360 | pmxops->get_function_name(pctldev, func_selector), | ||
361 | groups[0]); | ||
362 | return ret; | ||
363 | } | ||
364 | |||
365 | if (num_groups > 1) | ||
366 | dev_dbg(pctldev->dev, | ||
367 | "function %s support more than one group, default-selecting first group %s (%d)\n", | ||
368 | pmxops->get_function_name(pctldev, func_selector), | ||
369 | groups[0], | ||
370 | ret); | ||
371 | |||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | dev_dbg(pctldev->dev, | ||
376 | "check if we have pin group %s on controller %s\n", | ||
377 | pin_group, pinctrl_dev_get_name(pctldev)); | ||
378 | |||
379 | ret = pinctrl_get_group_selector(pctldev, pin_group); | ||
380 | if (ret < 0) { | ||
381 | dev_dbg(pctldev->dev, | ||
382 | "%s does not support pin group %s with function %s\n", | ||
383 | pinctrl_dev_get_name(pctldev), | ||
384 | pin_group, | ||
385 | pmxops->get_function_name(pctldev, func_selector)); | ||
386 | } | ||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * pinmux_search_function() - check pin control driver for a certain function | ||
392 | * @pctldev: device to check for function and position | ||
393 | * @map: function map containing the function and position to look for | ||
394 | * @func_selector: returns the applicable function selector if found | ||
395 | * @group_selector: returns the applicable group selector if found | ||
396 | * | ||
397 | * This will search the pinmux driver for an applicable | ||
398 | * function with a specific pin group, returns 0 if these can be mapped | ||
399 | * negative otherwise | ||
400 | */ | ||
401 | static int pinmux_search_function(struct pinctrl_dev *pctldev, | ||
402 | struct pinctrl_map const *map, | ||
403 | unsigned *func_selector, | ||
404 | unsigned *group_selector) | ||
405 | { | 238 | { |
406 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 239 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
407 | unsigned selector = 0; | 240 | unsigned selector = 0; |
@@ -410,155 +243,128 @@ static int pinmux_search_function(struct pinctrl_dev *pctldev, | |||
410 | while (ops->list_functions(pctldev, selector) >= 0) { | 243 | while (ops->list_functions(pctldev, selector) >= 0) { |
411 | const char *fname = ops->get_function_name(pctldev, | 244 | const char *fname = ops->get_function_name(pctldev, |
412 | selector); | 245 | selector); |
413 | int ret; | ||
414 | 246 | ||
415 | if (!strcmp(map->function, fname)) { | 247 | if (!strcmp(function, fname)) |
416 | /* Found the function, check pin group */ | 248 | return selector; |
417 | ret = pinmux_check_pin_group(pctldev, selector, | ||
418 | map->group); | ||
419 | if (ret < 0) | ||
420 | return ret; | ||
421 | 249 | ||
422 | /* This function and group selector can be used */ | ||
423 | *func_selector = selector; | ||
424 | *group_selector = ret; | ||
425 | return 0; | ||
426 | |||
427 | } | ||
428 | selector++; | 250 | selector++; |
429 | } | 251 | } |
430 | 252 | ||
431 | pr_err("%s does not support function %s\n", | 253 | pr_err("%s does not support function %s\n", |
432 | pinctrl_dev_get_name(pctldev), map->function); | 254 | pinctrl_dev_get_name(pctldev), function); |
433 | return -EINVAL; | 255 | return -EINVAL; |
434 | } | 256 | } |
435 | 257 | ||
436 | /** | 258 | int pinmux_map_to_setting(struct pinctrl_map const *map, |
437 | * pinmux_enable_muxmap() - enable a map entry for a certain pinmux | 259 | struct pinctrl_setting *setting) |
438 | */ | ||
439 | static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, | ||
440 | struct pinctrl *p, | ||
441 | struct device *dev, | ||
442 | const char *devname, | ||
443 | struct pinctrl_map const *map) | ||
444 | { | 260 | { |
445 | unsigned func_selector; | 261 | struct pinctrl_dev *pctldev = setting->pctldev; |
446 | unsigned group_selector; | 262 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; |
447 | struct pinmux_group *grp; | 263 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; |
264 | char const * const *groups; | ||
265 | unsigned num_groups; | ||
448 | int ret; | 266 | int ret; |
267 | const char *group; | ||
268 | int i; | ||
269 | const unsigned *pins; | ||
270 | unsigned num_pins; | ||
449 | 271 | ||
450 | /* | 272 | setting->func_selector = |
451 | * Note that we're not locking the pinmux mutex here, because | 273 | pinmux_func_name_to_selector(pctldev, map->function); |
452 | * this is only called at pinmux initialization time when it | 274 | if (setting->func_selector < 0) |
453 | * has not been added to any list and thus is not reachable | 275 | return setting->func_selector; |
454 | * by anyone else. | ||
455 | */ | ||
456 | 276 | ||
457 | if (p->pctldev && p->pctldev != pctldev) { | 277 | ret = pmxops->get_function_groups(pctldev, setting->func_selector, |
458 | dev_err(pctldev->dev, | 278 | &groups, &num_groups); |
459 | "different pin control devices given for device %s, function %s\n", | 279 | if (ret < 0) |
460 | devname, map->function); | 280 | return ret; |
281 | if (!num_groups) | ||
461 | return -EINVAL; | 282 | return -EINVAL; |
283 | |||
284 | if (map->group) { | ||
285 | bool found = false; | ||
286 | group = map->group; | ||
287 | for (i = 0; i < num_groups; i++) { | ||
288 | if (!strcmp(group, groups[i])) { | ||
289 | found = true; | ||
290 | break; | ||
291 | } | ||
292 | } | ||
293 | if (!found) | ||
294 | return -EINVAL; | ||
295 | } else { | ||
296 | group = groups[0]; | ||
462 | } | 297 | } |
463 | p->dev = dev; | ||
464 | p->pctldev = pctldev; | ||
465 | 298 | ||
466 | /* Now go into the driver and try to match a function and group */ | 299 | setting->group_selector = |
467 | ret = pinmux_search_function(pctldev, map, &func_selector, | 300 | pinctrl_get_group_selector(pctldev, group); |
468 | &group_selector); | 301 | if (setting->group_selector < 0) |
469 | if (ret < 0) | 302 | return setting->group_selector; |
470 | return ret; | ||
471 | 303 | ||
472 | /* Now add this group selector, we may have many of them */ | 304 | ret = pctlops->get_group_pins(pctldev, setting->group_selector, |
473 | grp = kmalloc(sizeof(*grp), GFP_KERNEL); | 305 | &pins, &num_pins); |
474 | if (!grp) | ||
475 | return -ENOMEM; | ||
476 | grp->func_selector = func_selector; | ||
477 | grp->group_selector = group_selector; | ||
478 | ret = acquire_pins(pctldev, devname, group_selector); | ||
479 | if (ret) { | 306 | if (ret) { |
480 | kfree(grp); | 307 | dev_err(pctldev->dev, |
481 | return ret; | 308 | "could not get pins for device %s group selector %d\n", |
309 | pinctrl_dev_get_name(pctldev), setting->group_selector); | ||
310 | return -ENODEV; | ||
311 | } | ||
312 | |||
313 | /* Try to allocate all pins in this group, one by one */ | ||
314 | for (i = 0; i < num_pins; i++) { | ||
315 | ret = pin_request(pctldev, pins[i], map->dev_name, NULL); | ||
316 | if (ret) { | ||
317 | dev_err(pctldev->dev, | ||
318 | "could not get request pin %d on device %s\n", | ||
319 | pins[i], pinctrl_dev_get_name(pctldev)); | ||
320 | /* On error release all taken pins */ | ||
321 | i--; /* this pin just failed */ | ||
322 | for (; i >= 0; i--) | ||
323 | pin_free(pctldev, pins[i], NULL); | ||
324 | return -ENODEV; | ||
325 | } | ||
482 | } | 326 | } |
483 | list_add_tail(&grp->node, &p->groups); | ||
484 | 327 | ||
485 | return 0; | 328 | return 0; |
486 | } | 329 | } |
487 | 330 | ||
488 | /** | 331 | void pinmux_free_setting(struct pinctrl_setting const *setting) |
489 | * pinmux_apply_muxmap() - apply a certain mux mapping entry | ||
490 | */ | ||
491 | int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, | ||
492 | struct pinctrl *p, | ||
493 | struct device *dev, | ||
494 | const char *devname, | ||
495 | struct pinctrl_map const *map) | ||
496 | { | 332 | { |
333 | struct pinctrl_dev *pctldev = setting->pctldev; | ||
334 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | ||
335 | const unsigned *pins; | ||
336 | unsigned num_pins; | ||
497 | int ret; | 337 | int ret; |
338 | int i; | ||
498 | 339 | ||
499 | ret = pinmux_enable_muxmap(pctldev, p, dev, | 340 | ret = pctlops->get_group_pins(pctldev, setting->group_selector, |
500 | devname, map); | 341 | &pins, &num_pins); |
501 | if (ret) { | 342 | if (ret) { |
502 | pinmux_put(p); | 343 | dev_err(pctldev->dev, |
503 | return ret; | 344 | "could not get pins for device %s group selector %d\n", |
345 | pinctrl_dev_get_name(pctldev), setting->group_selector); | ||
346 | return; | ||
504 | } | 347 | } |
505 | 348 | ||
506 | return 0; | 349 | for (i = 0; i < num_pins; i++) |
507 | } | 350 | pin_free(pctldev, pins[i], NULL); |
508 | |||
509 | /** | ||
510 | * pinmux_put() - free up the pinmux portions of a pin controller handle | ||
511 | */ | ||
512 | void pinmux_put(struct pinctrl *p) | ||
513 | { | ||
514 | struct list_head *node, *tmp; | ||
515 | |||
516 | list_for_each_safe(node, tmp, &p->groups) { | ||
517 | struct pinmux_group *grp = | ||
518 | list_entry(node, struct pinmux_group, node); | ||
519 | /* Release all pins taken by this group */ | ||
520 | release_pins(p->pctldev, grp->group_selector); | ||
521 | list_del(node); | ||
522 | kfree(grp); | ||
523 | } | ||
524 | } | 351 | } |
525 | 352 | ||
526 | /** | 353 | int pinmux_enable_setting(struct pinctrl_setting const *setting) |
527 | * pinmux_enable() - enable the pinmux portion of a pin control handle | ||
528 | */ | ||
529 | int pinmux_enable(struct pinctrl *p) | ||
530 | { | 354 | { |
531 | struct pinctrl_dev *pctldev = p->pctldev; | 355 | struct pinctrl_dev *pctldev = setting->pctldev; |
532 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 356 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
533 | struct pinmux_group *grp; | ||
534 | int ret; | ||
535 | 357 | ||
536 | list_for_each_entry(grp, &p->groups, node) { | 358 | return ops->enable(pctldev, setting->func_selector, |
537 | ret = ops->enable(pctldev, grp->func_selector, | 359 | setting->group_selector); |
538 | grp->group_selector); | ||
539 | if (ret) | ||
540 | /* | ||
541 | * TODO: call disable() on all groups we called | ||
542 | * enable() on to this point? | ||
543 | */ | ||
544 | return ret; | ||
545 | } | ||
546 | return 0; | ||
547 | } | 360 | } |
548 | 361 | ||
549 | /** | 362 | void pinmux_disable_setting(struct pinctrl_setting const *setting) |
550 | * pinmux_disable() - disable the pinmux portions of a pin control handle | ||
551 | */ | ||
552 | void pinmux_disable(struct pinctrl *p) | ||
553 | { | 363 | { |
554 | struct pinctrl_dev *pctldev = p->pctldev; | 364 | struct pinctrl_dev *pctldev = setting->pctldev; |
555 | const struct pinmux_ops *ops = pctldev->desc->pmxops; | 365 | const struct pinmux_ops *ops = pctldev->desc->pmxops; |
556 | struct pinmux_group *grp; | ||
557 | 366 | ||
558 | list_for_each_entry(grp, &p->groups, node) { | 367 | ops->disable(pctldev, setting->func_selector, setting->group_selector); |
559 | ops->disable(pctldev, grp->func_selector, | ||
560 | grp->group_selector); | ||
561 | } | ||
562 | } | 368 | } |
563 | 369 | ||
564 | #ifdef CONFIG_DEBUG_FS | 370 | #ifdef CONFIG_DEBUG_FS |
@@ -635,30 +441,18 @@ static int pinmux_pins_show(struct seq_file *s, void *what) | |||
635 | return 0; | 441 | return 0; |
636 | } | 442 | } |
637 | 443 | ||
638 | void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) | 444 | void pinmux_dbg_show(struct seq_file *s, struct pinctrl_setting const *setting) |
639 | { | 445 | { |
640 | struct pinctrl_dev *pctldev = p->pctldev; | 446 | struct pinctrl_dev *pctldev = setting->pctldev; |
641 | const struct pinmux_ops *pmxops; | 447 | const struct pinmux_ops *pmxops = pctldev->desc->pmxops; |
642 | const struct pinctrl_ops *pctlops; | 448 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; |
643 | struct pinmux_group *grp; | 449 | |
644 | const char *sep = ""; | 450 | seq_printf(s, "controller: %s group: %s (%u) function: %s (%u)\n", |
645 | 451 | pinctrl_dev_get_name(pctldev), | |
646 | pmxops = pctldev->desc->pmxops; | 452 | pctlops->get_group_name(pctldev, setting->group_selector), |
647 | pctlops = pctldev->desc->pctlops; | 453 | setting->group_selector, |
648 | 454 | pmxops->get_function_name(pctldev, setting->func_selector), | |
649 | seq_printf(s, " groups: ["); | 455 | setting->func_selector); |
650 | list_for_each_entry(grp, &p->groups, node) { | ||
651 | seq_printf(s, "%s%s (%u)=%s (%u)", | ||
652 | sep, | ||
653 | pctlops->get_group_name(pctldev, | ||
654 | grp->group_selector), | ||
655 | grp->group_selector, | ||
656 | pmxops->get_function_name(pctldev, | ||
657 | grp->func_selector), | ||
658 | grp->func_selector); | ||
659 | sep = ", "; | ||
660 | } | ||
661 | seq_printf(s, " ]"); | ||
662 | } | 456 | } |
663 | 457 | ||
664 | static int pinmux_functions_open(struct inode *inode, struct file *file) | 458 | static int pinmux_functions_open(struct inode *inode, struct file *file) |
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 822febb2d968..1500ae88f87c 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #ifdef CONFIG_PINMUX | 13 | #ifdef CONFIG_PINMUX |
14 | 14 | ||
15 | int pinmux_check_ops(struct pinctrl_dev *pctldev); | 15 | int pinmux_check_ops(struct pinctrl_dev *pctldev); |
16 | |||
16 | int pinmux_request_gpio(struct pinctrl_dev *pctldev, | 17 | int pinmux_request_gpio(struct pinctrl_dev *pctldev, |
17 | struct pinctrl_gpio_range *range, | 18 | struct pinctrl_gpio_range *range, |
18 | unsigned pin, unsigned gpio); | 19 | unsigned pin, unsigned gpio); |
@@ -21,21 +22,16 @@ void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, | |||
21 | int pinmux_gpio_direction(struct pinctrl_dev *pctldev, | 22 | int pinmux_gpio_direction(struct pinctrl_dev *pctldev, |
22 | struct pinctrl_gpio_range *range, | 23 | struct pinctrl_gpio_range *range, |
23 | unsigned pin, bool input); | 24 | unsigned pin, bool input); |
24 | static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) | 25 | |
25 | { | 26 | int pinmux_map_to_setting(struct pinctrl_map const *map, |
26 | INIT_LIST_HEAD(&p->groups); | 27 | struct pinctrl_setting *setting); |
27 | } | 28 | void pinmux_free_setting(struct pinctrl_setting const *setting); |
28 | int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, | 29 | int pinmux_enable_setting(struct pinctrl_setting const *setting); |
29 | struct pinctrl *p, | 30 | void pinmux_disable_setting(struct pinctrl_setting const *setting); |
30 | struct device *dev, | 31 | |
31 | const char *devname, | 32 | void pinmux_dbg_show(struct seq_file *s, struct pinctrl_setting const *setting); |
32 | struct pinctrl_map const *map); | ||
33 | void pinmux_put(struct pinctrl *p); | ||
34 | int pinmux_enable(struct pinctrl *p); | ||
35 | void pinmux_disable(struct pinctrl *p); | ||
36 | void pinmux_init_device_debugfs(struct dentry *devroot, | 33 | void pinmux_init_device_debugfs(struct dentry *devroot, |
37 | struct pinctrl_dev *pctldev); | 34 | struct pinctrl_dev *pctldev); |
38 | void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p); | ||
39 | 35 | ||
40 | #else | 36 | #else |
41 | 37 | ||
@@ -64,28 +60,23 @@ static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev, | |||
64 | return 0; | 60 | return 0; |
65 | } | 61 | } |
66 | 62 | ||
67 | static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) | 63 | static inline int pinmux_map_to_setting(struct pinctrl_map const *map, |
68 | { | 64 | struct pinctrl_setting *setting) |
69 | } | ||
70 | |||
71 | static inline int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, | ||
72 | struct pinctrl *p, | ||
73 | struct device *dev, | ||
74 | const char *devname, | ||
75 | struct pinctrl_map const *map) | ||
76 | { | 65 | { |
77 | return 0; | 66 | return 0; |
78 | } | 67 | } |
79 | 68 | ||
80 | static inline void pinmux_put(struct pinctrl *p) | 69 | static inline void pinmux_free_setting(struct pinctrl_setting const *setting) |
81 | { | 70 | { |
82 | } | 71 | } |
83 | 72 | ||
84 | static inline int pinmux_enable(struct pinctrl *p) | 73 | static inline int pinmux_enable_setting(struct pinctrl_setting const *setting) |
85 | { | 74 | { |
75 | return 0; | ||
86 | } | 76 | } |
87 | 77 | ||
88 | static inline void pinmux_disable(struct pinctrl *p) | 78 | static inline void pinmux_disable_setting( |
79 | struct pinctrl_setting const *setting) | ||
89 | { | 80 | { |
90 | } | 81 | } |
91 | 82 | ||