diff options
Diffstat (limited to 'drivers/pinctrl/core.c')
| -rw-r--r-- | drivers/pinctrl/core.c | 175 |
1 files changed, 149 insertions, 26 deletions
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index df6296c5f47b..5cd5a5a3a403 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
| @@ -23,9 +23,11 @@ | |||
| 23 | #include <linux/sysfs.h> | 23 | #include <linux/sysfs.h> |
| 24 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
| 25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
| 26 | #include <linux/pinctrl/consumer.h> | ||
| 26 | #include <linux/pinctrl/pinctrl.h> | 27 | #include <linux/pinctrl/pinctrl.h> |
| 27 | #include <linux/pinctrl/machine.h> | 28 | #include <linux/pinctrl/machine.h> |
| 28 | #include "core.h" | 29 | #include "core.h" |
| 30 | #include "devicetree.h" | ||
| 29 | #include "pinmux.h" | 31 | #include "pinmux.h" |
| 30 | #include "pinconf.h" | 32 | #include "pinconf.h" |
| 31 | 33 | ||
| @@ -45,7 +47,7 @@ struct pinctrl_maps { | |||
| 45 | DEFINE_MUTEX(pinctrl_mutex); | 47 | DEFINE_MUTEX(pinctrl_mutex); |
| 46 | 48 | ||
| 47 | /* Global list of pin control devices (struct pinctrl_dev) */ | 49 | /* Global list of pin control devices (struct pinctrl_dev) */ |
| 48 | static LIST_HEAD(pinctrldev_list); | 50 | LIST_HEAD(pinctrldev_list); |
| 49 | 51 | ||
| 50 | /* List of pin controller handles (struct pinctrl) */ | 52 | /* List of pin controller handles (struct pinctrl) */ |
| 51 | static LIST_HEAD(pinctrl_list); | 53 | static LIST_HEAD(pinctrl_list); |
| @@ -124,6 +126,25 @@ int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) | |||
| 124 | } | 126 | } |
| 125 | 127 | ||
| 126 | /** | 128 | /** |
| 129 | * pin_get_name_from_id() - look up a pin name from a pin id | ||
| 130 | * @pctldev: the pin control device to lookup the pin on | ||
| 131 | * @name: the name of the pin to look up | ||
| 132 | */ | ||
| 133 | const char *pin_get_name(struct pinctrl_dev *pctldev, const unsigned pin) | ||
| 134 | { | ||
| 135 | const struct pin_desc *desc; | ||
| 136 | |||
| 137 | desc = pin_desc_get(pctldev, pin); | ||
| 138 | if (desc == NULL) { | ||
| 139 | dev_err(pctldev->dev, "failed to get pin(%d) name\n", | ||
| 140 | pin); | ||
| 141 | return NULL; | ||
| 142 | } | ||
| 143 | |||
| 144 | return desc->name; | ||
| 145 | } | ||
| 146 | |||
| 147 | /** | ||
| 127 | * pin_is_valid() - check if pin exists on controller | 148 | * pin_is_valid() - check if pin exists on controller |
| 128 | * @pctldev: the pin control device to check the pin on | 149 | * @pctldev: the pin control device to check the pin on |
| 129 | * @pin: pin to check, use the local pin controller index number | 150 | * @pin: pin to check, use the local pin controller index number |
| @@ -318,9 +339,10 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, | |||
| 318 | const char *pin_group) | 339 | const char *pin_group) |
| 319 | { | 340 | { |
| 320 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; | 341 | const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; |
| 342 | unsigned ngroups = pctlops->get_groups_count(pctldev); | ||
| 321 | unsigned group_selector = 0; | 343 | unsigned group_selector = 0; |
| 322 | 344 | ||
| 323 | while (pctlops->list_groups(pctldev, group_selector) >= 0) { | 345 | while (group_selector < ngroups) { |
| 324 | const char *gname = pctlops->get_group_name(pctldev, | 346 | const char *gname = pctlops->get_group_name(pctldev, |
| 325 | group_selector); | 347 | group_selector); |
| 326 | if (!strcmp(gname, pin_group)) { | 348 | if (!strcmp(gname, pin_group)) { |
| @@ -516,11 +538,14 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) | |||
| 516 | 538 | ||
| 517 | setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); | 539 | setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); |
| 518 | if (setting->pctldev == NULL) { | 540 | if (setting->pctldev == NULL) { |
| 519 | dev_err(p->dev, "unknown pinctrl device %s in map entry", | 541 | dev_info(p->dev, "unknown pinctrl device %s in map entry, deferring probe", |
| 520 | map->ctrl_dev_name); | 542 | map->ctrl_dev_name); |
| 521 | kfree(setting); | 543 | kfree(setting); |
| 522 | /* Eventually, this should trigger deferred probe */ | 544 | /* |
| 523 | return -ENODEV; | 545 | * OK let us guess that the driver is not there yet, and |
| 546 | * let's defer obtaining this pinctrl handle to later... | ||
| 547 | */ | ||
| 548 | return -EPROBE_DEFER; | ||
| 524 | } | 549 | } |
| 525 | 550 | ||
| 526 | switch (map->type) { | 551 | switch (map->type) { |
| @@ -579,6 +604,13 @@ static struct pinctrl *create_pinctrl(struct device *dev) | |||
| 579 | } | 604 | } |
| 580 | p->dev = dev; | 605 | p->dev = dev; |
| 581 | INIT_LIST_HEAD(&p->states); | 606 | INIT_LIST_HEAD(&p->states); |
| 607 | INIT_LIST_HEAD(&p->dt_maps); | ||
| 608 | |||
| 609 | ret = pinctrl_dt_to_map(p); | ||
| 610 | if (ret < 0) { | ||
| 611 | kfree(p); | ||
| 612 | return ERR_PTR(ret); | ||
| 613 | } | ||
| 582 | 614 | ||
| 583 | devname = dev_name(dev); | 615 | devname = dev_name(dev); |
| 584 | 616 | ||
| @@ -662,6 +694,8 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist) | |||
| 662 | kfree(state); | 694 | kfree(state); |
| 663 | } | 695 | } |
| 664 | 696 | ||
| 697 | pinctrl_dt_free_maps(p); | ||
| 698 | |||
| 665 | if (inlist) | 699 | if (inlist) |
| 666 | list_del(&p->node); | 700 | list_del(&p->node); |
| 667 | kfree(p); | 701 | kfree(p); |
| @@ -787,15 +821,63 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) | |||
| 787 | } | 821 | } |
| 788 | EXPORT_SYMBOL_GPL(pinctrl_select_state); | 822 | EXPORT_SYMBOL_GPL(pinctrl_select_state); |
| 789 | 823 | ||
| 824 | static void devm_pinctrl_release(struct device *dev, void *res) | ||
| 825 | { | ||
| 826 | pinctrl_put(*(struct pinctrl **)res); | ||
| 827 | } | ||
| 828 | |||
| 790 | /** | 829 | /** |
| 791 | * pinctrl_register_mappings() - register a set of pin controller mappings | 830 | * struct devm_pinctrl_get() - Resource managed pinctrl_get() |
| 792 | * @maps: the pincontrol mappings table to register. This should probably be | 831 | * @dev: the device to obtain the handle for |
| 793 | * marked with __initdata so it can be discarded after boot. This | 832 | * |
| 794 | * function will perform a shallow copy for the mapping entries. | 833 | * If there is a need to explicitly destroy the returned struct pinctrl, |
| 795 | * @num_maps: the number of maps in the mapping table | 834 | * devm_pinctrl_put() should be used, rather than plain pinctrl_put(). |
| 796 | */ | 835 | */ |
| 797 | int pinctrl_register_mappings(struct pinctrl_map const *maps, | 836 | struct pinctrl *devm_pinctrl_get(struct device *dev) |
| 798 | unsigned num_maps) | 837 | { |
| 838 | struct pinctrl **ptr, *p; | ||
| 839 | |||
| 840 | ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL); | ||
| 841 | if (!ptr) | ||
| 842 | return ERR_PTR(-ENOMEM); | ||
| 843 | |||
| 844 | p = pinctrl_get(dev); | ||
| 845 | if (!IS_ERR(p)) { | ||
| 846 | *ptr = p; | ||
| 847 | devres_add(dev, ptr); | ||
| 848 | } else { | ||
| 849 | devres_free(ptr); | ||
| 850 | } | ||
| 851 | |||
| 852 | return p; | ||
| 853 | } | ||
| 854 | EXPORT_SYMBOL_GPL(devm_pinctrl_get); | ||
| 855 | |||
| 856 | static int devm_pinctrl_match(struct device *dev, void *res, void *data) | ||
| 857 | { | ||
| 858 | struct pinctrl **p = res; | ||
| 859 | |||
| 860 | return *p == data; | ||
| 861 | } | ||
| 862 | |||
| 863 | /** | ||
| 864 | * devm_pinctrl_put() - Resource managed pinctrl_put() | ||
| 865 | * @p: the pinctrl handle to release | ||
| 866 | * | ||
| 867 | * Deallocate a struct pinctrl obtained via devm_pinctrl_get(). Normally | ||
| 868 | * this function will not need to be called and the resource management | ||
| 869 | * code will ensure that the resource is freed. | ||
| 870 | */ | ||
| 871 | void devm_pinctrl_put(struct pinctrl *p) | ||
| 872 | { | ||
| 873 | WARN_ON(devres_destroy(p->dev, devm_pinctrl_release, | ||
| 874 | devm_pinctrl_match, p)); | ||
| 875 | pinctrl_put(p); | ||
| 876 | } | ||
| 877 | EXPORT_SYMBOL_GPL(devm_pinctrl_put); | ||
| 878 | |||
| 879 | int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, | ||
| 880 | bool dup, bool locked) | ||
| 799 | { | 881 | { |
| 800 | int i, ret; | 882 | int i, ret; |
| 801 | struct pinctrl_maps *maps_node; | 883 | struct pinctrl_maps *maps_node; |
| @@ -851,20 +933,52 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, | |||
| 851 | } | 933 | } |
| 852 | 934 | ||
| 853 | maps_node->num_maps = num_maps; | 935 | maps_node->num_maps = num_maps; |
| 854 | maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL); | 936 | if (dup) { |
| 855 | if (!maps_node->maps) { | 937 | maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, |
| 856 | pr_err("failed to duplicate mapping table\n"); | 938 | GFP_KERNEL); |
| 857 | kfree(maps_node); | 939 | if (!maps_node->maps) { |
| 858 | return -ENOMEM; | 940 | pr_err("failed to duplicate mapping table\n"); |
| 941 | kfree(maps_node); | ||
| 942 | return -ENOMEM; | ||
| 943 | } | ||
| 944 | } else { | ||
| 945 | maps_node->maps = maps; | ||
| 859 | } | 946 | } |
| 860 | 947 | ||
| 861 | mutex_lock(&pinctrl_mutex); | 948 | if (!locked) |
| 949 | mutex_lock(&pinctrl_mutex); | ||
| 862 | list_add_tail(&maps_node->node, &pinctrl_maps); | 950 | list_add_tail(&maps_node->node, &pinctrl_maps); |
| 863 | mutex_unlock(&pinctrl_mutex); | 951 | if (!locked) |
| 952 | mutex_unlock(&pinctrl_mutex); | ||
| 864 | 953 | ||
| 865 | return 0; | 954 | return 0; |
| 866 | } | 955 | } |
| 867 | 956 | ||
| 957 | /** | ||
| 958 | * pinctrl_register_mappings() - register a set of pin controller mappings | ||
| 959 | * @maps: the pincontrol mappings table to register. This should probably be | ||
| 960 | * marked with __initdata so it can be discarded after boot. This | ||
| 961 | * function will perform a shallow copy for the mapping entries. | ||
| 962 | * @num_maps: the number of maps in the mapping table | ||
| 963 | */ | ||
| 964 | int pinctrl_register_mappings(struct pinctrl_map const *maps, | ||
| 965 | unsigned num_maps) | ||
| 966 | { | ||
| 967 | return pinctrl_register_map(maps, num_maps, true, false); | ||
| 968 | } | ||
| 969 | |||
| 970 | void pinctrl_unregister_map(struct pinctrl_map const *map) | ||
| 971 | { | ||
| 972 | struct pinctrl_maps *maps_node; | ||
| 973 | |||
| 974 | list_for_each_entry(maps_node, &pinctrl_maps, node) { | ||
| 975 | if (maps_node->maps == map) { | ||
| 976 | list_del(&maps_node->node); | ||
| 977 | return; | ||
| 978 | } | ||
| 979 | } | ||
| 980 | } | ||
| 981 | |||
| 868 | #ifdef CONFIG_DEBUG_FS | 982 | #ifdef CONFIG_DEBUG_FS |
| 869 | 983 | ||
| 870 | static int pinctrl_pins_show(struct seq_file *s, void *what) | 984 | static int pinctrl_pins_show(struct seq_file *s, void *what) |
| @@ -906,15 +1020,17 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) | |||
| 906 | { | 1020 | { |
| 907 | struct pinctrl_dev *pctldev = s->private; | 1021 | struct pinctrl_dev *pctldev = s->private; |
| 908 | const struct pinctrl_ops *ops = pctldev->desc->pctlops; | 1022 | const struct pinctrl_ops *ops = pctldev->desc->pctlops; |
| 909 | unsigned selector = 0; | 1023 | unsigned ngroups, selector = 0; |
| 910 | 1024 | ||
| 1025 | ngroups = ops->get_groups_count(pctldev); | ||
| 911 | mutex_lock(&pinctrl_mutex); | 1026 | mutex_lock(&pinctrl_mutex); |
| 912 | 1027 | ||
| 913 | seq_puts(s, "registered pin groups:\n"); | 1028 | seq_puts(s, "registered pin groups:\n"); |
| 914 | while (ops->list_groups(pctldev, selector) >= 0) { | 1029 | while (selector < ngroups) { |
| 915 | const unsigned *pins; | 1030 | const unsigned *pins; |
| 916 | unsigned num_pins; | 1031 | unsigned num_pins; |
| 917 | const char *gname = ops->get_group_name(pctldev, selector); | 1032 | const char *gname = ops->get_group_name(pctldev, selector); |
| 1033 | const char *pname; | ||
| 918 | int ret; | 1034 | int ret; |
| 919 | int i; | 1035 | int i; |
| 920 | 1036 | ||
| @@ -924,10 +1040,14 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) | |||
| 924 | seq_printf(s, "%s [ERROR GETTING PINS]\n", | 1040 | seq_printf(s, "%s [ERROR GETTING PINS]\n", |
| 925 | gname); | 1041 | gname); |
| 926 | else { | 1042 | else { |
| 927 | seq_printf(s, "group: %s, pins = [ ", gname); | 1043 | seq_printf(s, "group: %s\n", gname); |
| 928 | for (i = 0; i < num_pins; i++) | 1044 | for (i = 0; i < num_pins; i++) { |
| 929 | seq_printf(s, "%d ", pins[i]); | 1045 | pname = pin_get_name(pctldev, pins[i]); |
| 930 | seq_puts(s, "]\n"); | 1046 | if (WARN_ON(!pname)) |
| 1047 | return -EINVAL; | ||
| 1048 | seq_printf(s, "pin %d (%s)\n", pins[i], pname); | ||
| 1049 | } | ||
| 1050 | seq_puts(s, "\n"); | ||
| 931 | } | 1051 | } |
| 932 | selector++; | 1052 | selector++; |
| 933 | } | 1053 | } |
| @@ -1226,11 +1346,14 @@ static int pinctrl_check_ops(struct pinctrl_dev *pctldev) | |||
| 1226 | const struct pinctrl_ops *ops = pctldev->desc->pctlops; | 1346 | const struct pinctrl_ops *ops = pctldev->desc->pctlops; |
| 1227 | 1347 | ||
| 1228 | if (!ops || | 1348 | if (!ops || |
| 1229 | !ops->list_groups || | 1349 | !ops->get_groups_count || |
| 1230 | !ops->get_group_name || | 1350 | !ops->get_group_name || |
| 1231 | !ops->get_group_pins) | 1351 | !ops->get_group_pins) |
| 1232 | return -EINVAL; | 1352 | return -EINVAL; |
| 1233 | 1353 | ||
| 1354 | if (ops->dt_node_to_map && !ops->dt_free_map) | ||
| 1355 | return -EINVAL; | ||
| 1356 | |||
| 1234 | return 0; | 1357 | return 0; |
| 1235 | } | 1358 | } |
| 1236 | 1359 | ||
