Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pinctrl: core device tree mapping table parsing support

During pinctrl_get(), if the client device has a device tree node, look
for the common pinctrl properties there. If found, parse the referenced
device tree nodes, with the help of the pinctrl drivers, and generate
mapping table entries from them.

During pinctrl_put(), free any results of device tree parsing.

Acked-by: Dong Aisheng <dong.aisheng@linaro.org>
Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

authored by

Stephen Warren and committed by
Linus Walleij
57291ce2 d26bc49f

+357 -18
+1
drivers/pinctrl/Makefile
··· 5 5 obj-$(CONFIG_PINCTRL) += core.o 6 6 obj-$(CONFIG_PINMUX) += pinmux.o 7 7 obj-$(CONFIG_PINCONF) += pinconf.o 8 + obj-$(CONFIG_OF) += devicetree.o 8 9 obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o 9 10 obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o 10 11 obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
+55 -17
drivers/pinctrl/core.c
··· 26 26 #include <linux/pinctrl/pinctrl.h> 27 27 #include <linux/pinctrl/machine.h> 28 28 #include "core.h" 29 + #include "devicetree.h" 29 30 #include "pinmux.h" 30 31 #include "pinconf.h" 31 32 ··· 46 45 DEFINE_MUTEX(pinctrl_mutex); 47 46 48 47 /* Global list of pin control devices (struct pinctrl_dev) */ 49 - static LIST_HEAD(pinctrldev_list); 48 + LIST_HEAD(pinctrldev_list); 50 49 51 50 /* List of pin controller handles (struct pinctrl) */ 52 51 static LIST_HEAD(pinctrl_list); ··· 580 579 } 581 580 p->dev = dev; 582 581 INIT_LIST_HEAD(&p->states); 582 + INIT_LIST_HEAD(&p->dt_maps); 583 + 584 + ret = pinctrl_dt_to_map(p); 585 + if (ret < 0) { 586 + kfree(p); 587 + return ERR_PTR(ret); 588 + } 583 589 584 590 devname = dev_name(dev); 585 591 ··· 669 661 list_del(&state->node); 670 662 kfree(state); 671 663 } 664 + 665 + pinctrl_dt_free_maps(p); 672 666 673 667 if (inlist) 674 668 list_del(&p->node); ··· 797 787 } 798 788 EXPORT_SYMBOL_GPL(pinctrl_select_state); 799 789 800 - /** 801 - * pinctrl_register_mappings() - register a set of pin controller mappings 802 - * @maps: the pincontrol mappings table to register. This should probably be 803 - * marked with __initdata so it can be discarded after boot. This 804 - * function will perform a shallow copy for the mapping entries. 805 - * @num_maps: the number of maps in the mapping table 806 - */ 807 - int pinctrl_register_mappings(struct pinctrl_map const *maps, 808 - unsigned num_maps) 790 + int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, 791 + bool dup, bool locked) 809 792 { 810 793 int i, ret; 811 794 struct pinctrl_maps *maps_node; ··· 854 851 } 855 852 856 853 maps_node->num_maps = num_maps; 857 - maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL); 858 - if (!maps_node->maps) { 859 - pr_err("failed to duplicate mapping table\n"); 860 - kfree(maps_node); 861 - return -ENOMEM; 854 + if (dup) { 855 + maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, 856 + GFP_KERNEL); 857 + if (!maps_node->maps) { 858 + pr_err("failed to duplicate mapping table\n"); 859 + kfree(maps_node); 860 + return -ENOMEM; 861 + } 862 + } else { 863 + maps_node->maps = maps; 862 864 } 863 865 864 - mutex_lock(&pinctrl_mutex); 866 + if (!locked) 867 + mutex_lock(&pinctrl_mutex); 865 868 list_add_tail(&maps_node->node, &pinctrl_maps); 866 - mutex_unlock(&pinctrl_mutex); 869 + if (!locked) 870 + mutex_unlock(&pinctrl_mutex); 867 871 868 872 return 0; 873 + } 874 + 875 + /** 876 + * pinctrl_register_mappings() - register a set of pin controller mappings 877 + * @maps: the pincontrol mappings table to register. This should probably be 878 + * marked with __initdata so it can be discarded after boot. This 879 + * function will perform a shallow copy for the mapping entries. 880 + * @num_maps: the number of maps in the mapping table 881 + */ 882 + int pinctrl_register_mappings(struct pinctrl_map const *maps, 883 + unsigned num_maps) 884 + { 885 + return pinctrl_register_map(maps, num_maps, true, false); 886 + } 887 + 888 + void pinctrl_unregister_map(struct pinctrl_map const *map) 889 + { 890 + struct pinctrl_maps *maps_node; 891 + 892 + list_for_each_entry(maps_node, &pinctrl_maps, node) { 893 + if (maps_node->maps == map) { 894 + list_del(&maps_node->node); 895 + return; 896 + } 897 + } 869 898 } 870 899 871 900 #ifdef CONFIG_DEBUG_FS ··· 1264 1229 !ops->list_groups || 1265 1230 !ops->get_group_name || 1266 1231 !ops->get_group_pins) 1232 + return -EINVAL; 1233 + 1234 + if (ops->dt_node_to_map && !ops->dt_free_map) 1267 1235 return -EINVAL; 1268 1236 1269 1237 return 0;
+10 -1
drivers/pinctrl/core.h
··· 52 52 * @dev: the device using this pin control handle 53 53 * @states: a list of states for this device 54 54 * @state: the current state 55 + * @dt_maps: the mapping table chunks dynamically parsed from device tree for 56 + * this device, if any 55 57 */ 56 58 struct pinctrl { 57 59 struct list_head node; 58 60 struct device *dev; 59 61 struct list_head states; 60 62 struct pinctrl_state *state; 63 + struct list_head dt_maps; 61 64 }; 62 65 63 66 /** ··· 103 100 * struct pinctrl_setting - an individual mux or config setting 104 101 * @node: list node for struct pinctrl_settings's @settings field 105 102 * @type: the type of setting 106 - * @pctldev: pin control device handling to be programmed 103 + * @pctldev: pin control device handling to be programmed. Not used for 104 + * PIN_MAP_TYPE_DUMMY_STATE. 107 105 * @data: Data specific to the setting type 108 106 */ 109 107 struct pinctrl_setting { ··· 157 153 return radix_tree_lookup(&pctldev->pin_desc_tree, pin); 158 154 } 159 155 156 + int pinctrl_register_map(struct pinctrl_map const *maps, unsigned num_maps, 157 + bool dup, bool locked); 158 + void pinctrl_unregister_map(struct pinctrl_map const *map); 159 + 160 160 extern struct mutex pinctrl_mutex; 161 + extern struct list_head pinctrldev_list;
+249
drivers/pinctrl/devicetree.c
··· 1 + /* 2 + * Device tree integration for the pin control subsystem 3 + * 4 + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + 19 + #include <linux/device.h> 20 + #include <linux/of.h> 21 + #include <linux/pinctrl/pinctrl.h> 22 + #include <linux/slab.h> 23 + 24 + #include "core.h" 25 + #include "devicetree.h" 26 + 27 + /** 28 + * struct pinctrl_dt_map - mapping table chunk parsed from device tree 29 + * @node: list node for struct pinctrl's @dt_maps field 30 + * @pctldev: the pin controller that allocated this struct, and will free it 31 + * @maps: the mapping table entries 32 + */ 33 + struct pinctrl_dt_map { 34 + struct list_head node; 35 + struct pinctrl_dev *pctldev; 36 + struct pinctrl_map *map; 37 + unsigned num_maps; 38 + }; 39 + 40 + static void dt_free_map(struct pinctrl_dev *pctldev, 41 + struct pinctrl_map *map, unsigned num_maps) 42 + { 43 + if (pctldev) { 44 + struct pinctrl_ops *ops = pctldev->desc->pctlops; 45 + ops->dt_free_map(pctldev, map, num_maps); 46 + } else { 47 + /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ 48 + kfree(map); 49 + } 50 + } 51 + 52 + void pinctrl_dt_free_maps(struct pinctrl *p) 53 + { 54 + struct pinctrl_dt_map *dt_map, *n1; 55 + 56 + list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) { 57 + pinctrl_unregister_map(dt_map->map); 58 + list_del(&dt_map->node); 59 + dt_free_map(dt_map->pctldev, dt_map->map, 60 + dt_map->num_maps); 61 + kfree(dt_map); 62 + } 63 + 64 + of_node_put(p->dev->of_node); 65 + } 66 + 67 + static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, 68 + struct pinctrl_dev *pctldev, 69 + struct pinctrl_map *map, unsigned num_maps) 70 + { 71 + int i; 72 + struct pinctrl_dt_map *dt_map; 73 + 74 + /* Initialize common mapping table entry fields */ 75 + for (i = 0; i < num_maps; i++) { 76 + map[i].dev_name = dev_name(p->dev); 77 + map[i].name = statename; 78 + if (pctldev) 79 + map[i].ctrl_dev_name = dev_name(pctldev->dev); 80 + } 81 + 82 + /* Remember the converted mapping table entries */ 83 + dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL); 84 + if (!dt_map) { 85 + dev_err(p->dev, "failed to alloc struct pinctrl_dt_map\n"); 86 + dt_free_map(pctldev, map, num_maps); 87 + return -ENOMEM; 88 + } 89 + 90 + dt_map->pctldev = pctldev; 91 + dt_map->map = map; 92 + dt_map->num_maps = num_maps; 93 + list_add_tail(&dt_map->node, &p->dt_maps); 94 + 95 + return pinctrl_register_map(map, num_maps, false, true); 96 + } 97 + 98 + static struct pinctrl_dev *find_pinctrl_by_of_node(struct device_node *np) 99 + { 100 + struct pinctrl_dev *pctldev; 101 + 102 + list_for_each_entry(pctldev, &pinctrldev_list, node) 103 + if (pctldev->dev->of_node == np) 104 + return pctldev; 105 + 106 + return NULL; 107 + } 108 + 109 + static int dt_to_map_one_config(struct pinctrl *p, const char *statename, 110 + struct device_node *np_config) 111 + { 112 + struct device_node *np_pctldev; 113 + struct pinctrl_dev *pctldev; 114 + struct pinctrl_ops *ops; 115 + int ret; 116 + struct pinctrl_map *map; 117 + unsigned num_maps; 118 + 119 + /* Find the pin controller containing np_config */ 120 + np_pctldev = of_node_get(np_config); 121 + for (;;) { 122 + np_pctldev = of_get_next_parent(np_pctldev); 123 + if (!np_pctldev || of_node_is_root(np_pctldev)) { 124 + dev_err(p->dev, "could not find pctldev for node %s\n", 125 + np_config->full_name); 126 + of_node_put(np_pctldev); 127 + /* FIXME: This should trigger deferrered probe */ 128 + return -ENODEV; 129 + } 130 + pctldev = find_pinctrl_by_of_node(np_pctldev); 131 + if (pctldev) 132 + break; 133 + } 134 + of_node_put(np_pctldev); 135 + 136 + /* 137 + * Call pinctrl driver to parse device tree node, and 138 + * generate mapping table entries 139 + */ 140 + ops = pctldev->desc->pctlops; 141 + if (!ops->dt_node_to_map) { 142 + dev_err(p->dev, "pctldev %s doesn't support DT\n", 143 + dev_name(pctldev->dev)); 144 + return -ENODEV; 145 + } 146 + ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps); 147 + if (ret < 0) 148 + return ret; 149 + 150 + /* Stash the mapping table chunk away for later use */ 151 + return dt_remember_or_free_map(p, statename, pctldev, map, num_maps); 152 + } 153 + 154 + static int dt_remember_dummy_state(struct pinctrl *p, const char *statename) 155 + { 156 + struct pinctrl_map *map; 157 + 158 + map = kzalloc(sizeof(*map), GFP_KERNEL); 159 + if (!map) { 160 + dev_err(p->dev, "failed to alloc struct pinctrl_map\n"); 161 + return -ENOMEM; 162 + } 163 + 164 + /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */ 165 + map->type = PIN_MAP_TYPE_DUMMY_STATE; 166 + 167 + return dt_remember_or_free_map(p, statename, NULL, map, 1); 168 + } 169 + 170 + int pinctrl_dt_to_map(struct pinctrl *p) 171 + { 172 + struct device_node *np = p->dev->of_node; 173 + int state, ret; 174 + char *propname; 175 + struct property *prop; 176 + const char *statename; 177 + const __be32 *list; 178 + int size, config; 179 + phandle phandle; 180 + struct device_node *np_config; 181 + 182 + /* CONFIG_OF enabled, p->dev not instantiated from DT */ 183 + if (!np) { 184 + dev_dbg(p->dev, "no of_node; not parsing pinctrl DT\n"); 185 + return 0; 186 + } 187 + 188 + /* We may store pointers to property names within the node */ 189 + of_node_get(np); 190 + 191 + /* For each defined state ID */ 192 + for (state = 0; ; state++) { 193 + /* Retrieve the pinctrl-* property */ 194 + propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); 195 + prop = of_find_property(np, propname, &size); 196 + kfree(propname); 197 + if (!prop) 198 + break; 199 + list = prop->value; 200 + size /= sizeof(*list); 201 + 202 + /* Determine whether pinctrl-names property names the state */ 203 + ret = of_property_read_string_index(np, "pinctrl-names", 204 + state, &statename); 205 + /* 206 + * If not, statename is just the integer state ID. But rather 207 + * than dynamically allocate it and have to free it later, 208 + * just point part way into the property name for the string. 209 + */ 210 + if (ret < 0) { 211 + /* strlen("pinctrl-") == 8 */ 212 + statename = prop->name + 8; 213 + } 214 + 215 + /* For every referenced pin configuration node in it */ 216 + for (config = 0; config < size; config++) { 217 + phandle = be32_to_cpup(list++); 218 + 219 + /* Look up the pin configuration node */ 220 + np_config = of_find_node_by_phandle(phandle); 221 + if (!np_config) { 222 + dev_err(p->dev, 223 + "prop %s index %i invalid phandle\n", 224 + prop->name, config); 225 + ret = -EINVAL; 226 + goto err; 227 + } 228 + 229 + /* Parse the node */ 230 + ret = dt_to_map_one_config(p, statename, np_config); 231 + of_node_put(np_config); 232 + if (ret < 0) 233 + goto err; 234 + } 235 + 236 + /* No entries in DT? Generate a dummy state table entry */ 237 + if (!size) { 238 + ret = dt_remember_dummy_state(p, statename); 239 + if (ret < 0) 240 + goto err; 241 + } 242 + } 243 + 244 + return 0; 245 + 246 + err: 247 + pinctrl_dt_free_maps(p); 248 + return ret; 249 + }
+35
drivers/pinctrl/devicetree.h
··· 1 + /* 2 + * Internal interface to pinctrl device tree integration 3 + * 4 + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + 19 + #ifdef CONFIG_OF 20 + 21 + void pinctrl_dt_free_maps(struct pinctrl *p); 22 + int pinctrl_dt_to_map(struct pinctrl *p); 23 + 24 + #else 25 + 26 + static inline int pinctrl_dt_to_map(struct pinctrl *p) 27 + { 28 + return 0; 29 + } 30 + 31 + static inline void pinctrl_dt_free_maps(struct pinctrl *p) 32 + { 33 + } 34 + 35 + #endif
+7
include/linux/pinctrl/pinctrl.h
··· 21 21 22 22 struct device; 23 23 struct pinctrl_dev; 24 + struct pinctrl_map; 24 25 struct pinmux_ops; 25 26 struct pinconf_ops; 26 27 struct gpio_chip; 28 + struct device_node; 27 29 28 30 /** 29 31 * struct pinctrl_pin_desc - boards/machines provide information on their ··· 85 83 unsigned *num_pins); 86 84 void (*pin_dbg_show) (struct pinctrl_dev *pctldev, struct seq_file *s, 87 85 unsigned offset); 86 + int (*dt_node_to_map) (struct pinctrl_dev *pctldev, 87 + struct device_node *np_config, 88 + struct pinctrl_map **map, unsigned *num_maps); 89 + void (*dt_free_map) (struct pinctrl_dev *pctldev, 90 + struct pinctrl_map *map, unsigned num_maps); 88 91 }; 89 92 90 93 /**