diff options
author | Stephen Warren <swarren@nvidia.com> | 2012-03-02 15:05:48 -0500 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-03-05 05:25:11 -0500 |
commit | 1e2082b520721734c358f776d34a069867214c8e (patch) | |
tree | 4d11e15a4127ad69faf7555864480a6fafe5422c /drivers/pinctrl/core.c | |
parent | 6e5e959dde0d92d177f035652aeaa77f9330c9c6 (diff) |
pinctrl: enhance mapping table to support pin config operations
The pinctrl mapping table can now contain entries to:
* Set the mux function of a pin group
* Apply a set of pin config options to a pin or a group
This allows pinctrl_select_state() to apply pin configs settings as well
as mux settings.
v3: Fix find_pinctrl() to iterate over the correct list.
s/_MUX_CONFIGS_/_CONFIGS_/ in mapping table macros.
Fix documentation to use correct mapping table macro.
v2: Added numerous extra PIN_MAP_*() special-case macros.
Fixed kerneldoc typo. Delete pinctrl_get_pin_id() and
replace it with pin_get_from_name(). Various minor fixes.
Updates due to rebase.
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/core.c')
-rw-r--r-- | drivers/pinctrl/core.c | 154 |
1 files changed, 128 insertions, 26 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index c6f3ca32189e..ec3b8cc188af 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -502,6 +502,9 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
502 | if (IS_ERR(state)) | 502 | if (IS_ERR(state)) |
503 | return PTR_ERR(state); | 503 | return PTR_ERR(state); |
504 | 504 | ||
505 | if (map->type == PIN_MAP_TYPE_DUMMY_STATE) | ||
506 | return 0; | ||
507 | |||
505 | setting = kzalloc(sizeof(*setting), GFP_KERNEL); | 508 | setting = kzalloc(sizeof(*setting), GFP_KERNEL); |
506 | if (setting == NULL) { | 509 | if (setting == NULL) { |
507 | dev_err(p->dev, | 510 | dev_err(p->dev, |
@@ -509,6 +512,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
509 | return -ENOMEM; | 512 | return -ENOMEM; |
510 | } | 513 | } |
511 | 514 | ||
515 | setting->type = map->type; | ||
516 | |||
512 | setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); | 517 | setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); |
513 | if (setting->pctldev == NULL) { | 518 | if (setting->pctldev == NULL) { |
514 | dev_err(p->dev, "unknown pinctrl device %s in map entry", | 519 | dev_err(p->dev, "unknown pinctrl device %s in map entry", |
@@ -518,7 +523,18 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
518 | return -ENODEV; | 523 | return -ENODEV; |
519 | } | 524 | } |
520 | 525 | ||
521 | ret = pinmux_map_to_setting(map, setting); | 526 | switch (map->type) { |
527 | case PIN_MAP_TYPE_MUX_GROUP: | ||
528 | ret = pinmux_map_to_setting(map, setting); | ||
529 | break; | ||
530 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
531 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
532 | ret = pinconf_map_to_setting(map, setting); | ||
533 | break; | ||
534 | default: | ||
535 | ret = -EINVAL; | ||
536 | break; | ||
537 | } | ||
522 | if (ret < 0) { | 538 | if (ret < 0) { |
523 | kfree(setting); | 539 | kfree(setting); |
524 | return ret; | 540 | return ret; |
@@ -533,7 +549,7 @@ static struct pinctrl *find_pinctrl(struct device *dev) | |||
533 | { | 549 | { |
534 | struct pinctrl *p; | 550 | struct pinctrl *p; |
535 | 551 | ||
536 | list_for_each_entry(p, &pinctrldev_list, node) | 552 | list_for_each_entry(p, &pinctrl_list, node) |
537 | if (p->dev == dev) | 553 | if (p->dev == dev) |
538 | return p; | 554 | return p; |
539 | 555 | ||
@@ -626,9 +642,19 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist) | |||
626 | 642 | ||
627 | list_for_each_entry_safe(state, n1, &p->states, node) { | 643 | list_for_each_entry_safe(state, n1, &p->states, node) { |
628 | list_for_each_entry_safe(setting, n2, &state->settings, node) { | 644 | list_for_each_entry_safe(setting, n2, &state->settings, node) { |
629 | if (state == p->state) | 645 | switch (setting->type) { |
630 | pinmux_disable_setting(setting); | 646 | case PIN_MAP_TYPE_MUX_GROUP: |
631 | pinmux_free_setting(setting); | 647 | if (state == p->state) |
648 | pinmux_disable_setting(setting); | ||
649 | pinmux_free_setting(setting); | ||
650 | break; | ||
651 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
652 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
653 | pinconf_free_setting(setting); | ||
654 | break; | ||
655 | default: | ||
656 | break; | ||
657 | } | ||
632 | list_del(&setting->node); | 658 | list_del(&setting->node); |
633 | kfree(setting); | 659 | kfree(setting); |
634 | } | 660 | } |
@@ -703,9 +729,13 @@ static int pinctrl_select_state_locked(struct pinctrl *p, | |||
703 | */ | 729 | */ |
704 | list_for_each_entry(setting, &p->state->settings, node) { | 730 | list_for_each_entry(setting, &p->state->settings, node) { |
705 | bool found = false; | 731 | bool found = false; |
732 | if (setting->type != PIN_MAP_TYPE_MUX_GROUP) | ||
733 | continue; | ||
706 | list_for_each_entry(setting2, &state->settings, node) { | 734 | list_for_each_entry(setting2, &state->settings, node) { |
707 | if (setting2->group_selector == | 735 | if (setting2->type != PIN_MAP_TYPE_MUX_GROUP) |
708 | setting->group_selector) { | 736 | continue; |
737 | if (setting2->data.mux.group == | ||
738 | setting->data.mux.group) { | ||
709 | found = true; | 739 | found = true; |
710 | break; | 740 | break; |
711 | } | 741 | } |
@@ -719,7 +749,18 @@ static int pinctrl_select_state_locked(struct pinctrl *p, | |||
719 | 749 | ||
720 | /* Apply all the settings for the new state */ | 750 | /* Apply all the settings for the new state */ |
721 | list_for_each_entry(setting, &state->settings, node) { | 751 | list_for_each_entry(setting, &state->settings, node) { |
722 | ret = pinmux_enable_setting(setting); | 752 | switch (setting->type) { |
753 | case PIN_MAP_TYPE_MUX_GROUP: | ||
754 | ret = pinmux_enable_setting(setting); | ||
755 | break; | ||
756 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
757 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
758 | ret = pinconf_apply_setting(setting); | ||
759 | break; | ||
760 | default: | ||
761 | ret = -EINVAL; | ||
762 | break; | ||
763 | } | ||
723 | if (ret < 0) { | 764 | if (ret < 0) { |
724 | /* FIXME: Difficult to return to prev state */ | 765 | /* FIXME: Difficult to return to prev state */ |
725 | return ret; | 766 | return ret; |
@@ -756,33 +797,48 @@ EXPORT_SYMBOL_GPL(pinctrl_select_state); | |||
756 | int pinctrl_register_mappings(struct pinctrl_map const *maps, | 797 | int pinctrl_register_mappings(struct pinctrl_map const *maps, |
757 | unsigned num_maps) | 798 | unsigned num_maps) |
758 | { | 799 | { |
759 | int i; | 800 | int i, ret; |
760 | struct pinctrl_maps *maps_node; | 801 | struct pinctrl_maps *maps_node; |
761 | 802 | ||
762 | pr_debug("add %d pinmux maps\n", num_maps); | 803 | pr_debug("add %d pinmux maps\n", num_maps); |
763 | 804 | ||
764 | /* First sanity check the new mapping */ | 805 | /* First sanity check the new mapping */ |
765 | for (i = 0; i < num_maps; i++) { | 806 | for (i = 0; i < num_maps; i++) { |
807 | if (!maps[i].dev_name) { | ||
808 | pr_err("failed to register map %s (%d): no device given\n", | ||
809 | maps[i].name, i); | ||
810 | return -EINVAL; | ||
811 | } | ||
812 | |||
766 | if (!maps[i].name) { | 813 | if (!maps[i].name) { |
767 | pr_err("failed to register map %d: no map name given\n", | 814 | pr_err("failed to register map %d: no map name given\n", |
768 | i); | 815 | i); |
769 | return -EINVAL; | 816 | return -EINVAL; |
770 | } | 817 | } |
771 | 818 | ||
772 | if (!maps[i].ctrl_dev_name) { | 819 | if (maps[i].type != PIN_MAP_TYPE_DUMMY_STATE && |
820 | !maps[i].ctrl_dev_name) { | ||
773 | pr_err("failed to register map %s (%d): no pin control device given\n", | 821 | pr_err("failed to register map %s (%d): no pin control device given\n", |
774 | maps[i].name, i); | 822 | maps[i].name, i); |
775 | return -EINVAL; | 823 | return -EINVAL; |
776 | } | 824 | } |
777 | 825 | ||
778 | if (!maps[i].function) { | 826 | switch (maps[i].type) { |
779 | pr_err("failed to register map %s (%d): no function ID given\n", | 827 | case PIN_MAP_TYPE_DUMMY_STATE: |
780 | maps[i].name, i); | 828 | break; |
781 | return -EINVAL; | 829 | case PIN_MAP_TYPE_MUX_GROUP: |
782 | } | 830 | ret = pinmux_validate_map(&maps[i], i); |
783 | 831 | if (ret < 0) | |
784 | if (!maps[i].dev_name) { | 832 | return 0; |
785 | pr_err("failed to register map %s (%d): no device given\n", | 833 | break; |
834 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
835 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
836 | ret = pinconf_validate_map(&maps[i], i); | ||
837 | if (ret < 0) | ||
838 | return 0; | ||
839 | break; | ||
840 | default: | ||
841 | pr_err("failed to register map %s (%d): invalid type given\n", | ||
786 | maps[i].name, i); | 842 | maps[i].name, i); |
787 | return -EINVAL; | 843 | return -EINVAL; |
788 | } | 844 | } |
@@ -934,6 +990,22 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) | |||
934 | return 0; | 990 | return 0; |
935 | } | 991 | } |
936 | 992 | ||
993 | static inline const char *map_type(enum pinctrl_map_type type) | ||
994 | { | ||
995 | static const char * const names[] = { | ||
996 | "INVALID", | ||
997 | "DUMMY_STATE", | ||
998 | "MUX_GROUP", | ||
999 | "CONFIGS_PIN", | ||
1000 | "CONFIGS_GROUP", | ||
1001 | }; | ||
1002 | |||
1003 | if (type >= ARRAY_SIZE(names)) | ||
1004 | return "UNKNOWN"; | ||
1005 | |||
1006 | return names[type]; | ||
1007 | } | ||
1008 | |||
937 | static int pinctrl_maps_show(struct seq_file *s, void *what) | 1009 | static int pinctrl_maps_show(struct seq_file *s, void *what) |
938 | { | 1010 | { |
939 | struct pinctrl_maps *maps_node; | 1011 | struct pinctrl_maps *maps_node; |
@@ -945,12 +1017,27 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) | |||
945 | mutex_lock(&pinctrl_mutex); | 1017 | mutex_lock(&pinctrl_mutex); |
946 | 1018 | ||
947 | for_each_maps(maps_node, i, map) { | 1019 | for_each_maps(maps_node, i, map) { |
948 | seq_printf(s, "%s:\n", map->name); | 1020 | seq_printf(s, "device %s\nstate %s\ntype %s (%d)\n", |
949 | seq_printf(s, " device: %s\n", map->dev_name); | 1021 | map->dev_name, map->name, map_type(map->type), |
950 | seq_printf(s, " controlling device %s\n", map->ctrl_dev_name); | 1022 | map->type); |
951 | seq_printf(s, " function: %s\n", map->function); | 1023 | |
952 | seq_printf(s, " group: %s\n", map->group ? map->group : | 1024 | if (map->type != PIN_MAP_TYPE_DUMMY_STATE) |
953 | "(default)"); | 1025 | seq_printf(s, "controlling device %s\n", |
1026 | map->ctrl_dev_name); | ||
1027 | |||
1028 | switch (map->type) { | ||
1029 | case PIN_MAP_TYPE_MUX_GROUP: | ||
1030 | pinmux_show_map(s, map); | ||
1031 | break; | ||
1032 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
1033 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
1034 | pinconf_show_map(s, map); | ||
1035 | break; | ||
1036 | default: | ||
1037 | break; | ||
1038 | } | ||
1039 | |||
1040 | seq_printf(s, "\n"); | ||
954 | } | 1041 | } |
955 | 1042 | ||
956 | mutex_unlock(&pinctrl_mutex); | 1043 | mutex_unlock(&pinctrl_mutex); |
@@ -977,8 +1064,23 @@ static int pinctrl_show(struct seq_file *s, void *what) | |||
977 | seq_printf(s, " state: %s\n", state->name); | 1064 | seq_printf(s, " state: %s\n", state->name); |
978 | 1065 | ||
979 | list_for_each_entry(setting, &state->settings, node) { | 1066 | list_for_each_entry(setting, &state->settings, node) { |
980 | seq_printf(s, " "); | 1067 | struct pinctrl_dev *pctldev = setting->pctldev; |
981 | pinmux_dbg_show(s, setting); | 1068 | |
1069 | seq_printf(s, " type: %s controller %s ", | ||
1070 | map_type(setting->type), | ||
1071 | pinctrl_dev_get_name(pctldev)); | ||
1072 | |||
1073 | switch (setting->type) { | ||
1074 | case PIN_MAP_TYPE_MUX_GROUP: | ||
1075 | pinmux_show_setting(s, setting); | ||
1076 | break; | ||
1077 | case PIN_MAP_TYPE_CONFIGS_PIN: | ||
1078 | case PIN_MAP_TYPE_CONFIGS_GROUP: | ||
1079 | pinconf_show_setting(s, setting); | ||
1080 | break; | ||
1081 | default: | ||
1082 | break; | ||
1083 | } | ||
982 | } | 1084 | } |
983 | } | 1085 | } |
984 | } | 1086 | } |