| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Device tree integration for the pin control subsystem |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * 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 | 6 | */ |
|---|
| 18 | 7 | |
|---|
| 19 | 8 | #include <linux/device.h> |
|---|
| .. | .. |
|---|
| 28 | 17 | * struct pinctrl_dt_map - mapping table chunk parsed from device tree |
|---|
| 29 | 18 | * @node: list node for struct pinctrl's @dt_maps field |
|---|
| 30 | 19 | * @pctldev: the pin controller that allocated this struct, and will free it |
|---|
| 31 | | - * @maps: the mapping table entries |
|---|
| 20 | + * @map: the mapping table entries |
|---|
| 21 | + * @num_maps: number of mapping table entries |
|---|
| 32 | 22 | */ |
|---|
| 33 | 23 | struct pinctrl_dt_map { |
|---|
| 34 | 24 | struct list_head node; |
|---|
| .. | .. |
|---|
| 62 | 52 | struct pinctrl_dt_map *dt_map, *n1; |
|---|
| 63 | 53 | |
|---|
| 64 | 54 | list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) { |
|---|
| 65 | | - pinctrl_unregister_map(dt_map->map); |
|---|
| 55 | + pinctrl_unregister_mappings(dt_map->map); |
|---|
| 66 | 56 | list_del(&dt_map->node); |
|---|
| 67 | 57 | dt_free_map(dt_map->pctldev, dt_map->map, |
|---|
| 68 | 58 | dt_map->num_maps); |
|---|
| .. | .. |
|---|
| 103 | 93 | dt_map->num_maps = num_maps; |
|---|
| 104 | 94 | list_add_tail(&dt_map->node, &p->dt_maps); |
|---|
| 105 | 95 | |
|---|
| 106 | | - return pinctrl_register_map(map, num_maps, false); |
|---|
| 96 | + return pinctrl_register_mappings(map, num_maps); |
|---|
| 107 | 97 | |
|---|
| 108 | 98 | err_free_map: |
|---|
| 109 | 99 | dt_free_map(pctldev, map, num_maps); |
|---|
| .. | .. |
|---|
| 114 | 104 | { |
|---|
| 115 | 105 | return get_pinctrl_dev_from_of_node(np); |
|---|
| 116 | 106 | } |
|---|
| 107 | +EXPORT_SYMBOL_GPL(of_pinctrl_get); |
|---|
| 117 | 108 | |
|---|
| 118 | 109 | static int dt_to_map_one_config(struct pinctrl *p, |
|---|
| 119 | 110 | struct pinctrl_dev *hog_pctldev, |
|---|
| .. | .. |
|---|
| 139 | 130 | if (!np_pctldev || of_node_is_root(np_pctldev)) { |
|---|
| 140 | 131 | of_node_put(np_pctldev); |
|---|
| 141 | 132 | ret = driver_deferred_probe_check_state(p->dev); |
|---|
| 142 | | - /* keep deferring if modules are enabled unless we've timed out */ |
|---|
| 143 | | - if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret == -ENODEV) |
|---|
| 133 | + /* keep deferring if modules are enabled */ |
|---|
| 134 | + if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret < 0) |
|---|
| 144 | 135 | ret = -EPROBE_DEFER; |
|---|
| 145 | | - |
|---|
| 146 | 136 | return ret; |
|---|
| 147 | 137 | } |
|---|
| 148 | 138 | /* If we're creating a hog we can use the passed pctldev */ |
|---|
| .. | .. |
|---|
| 174 | 164 | ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps); |
|---|
| 175 | 165 | if (ret < 0) |
|---|
| 176 | 166 | return ret; |
|---|
| 167 | + else if (num_maps == 0) { |
|---|
| 168 | + /* |
|---|
| 169 | + * If we have no valid maps (maybe caused by empty pinctrl node |
|---|
| 170 | + * or typing error) ther is no need remember this, so just |
|---|
| 171 | + * return. |
|---|
| 172 | + */ |
|---|
| 173 | + dev_info(p->dev, |
|---|
| 174 | + "there is not valid maps for state %s\n", statename); |
|---|
| 175 | + return 0; |
|---|
| 176 | + } |
|---|
| 177 | 177 | |
|---|
| 178 | 178 | /* Stash the mapping table chunk away for later use */ |
|---|
| 179 | 179 | return dt_remember_or_free_map(p, statename, pctldev, map, num_maps); |
|---|
| .. | .. |
|---|
| 191 | 191 | map->type = PIN_MAP_TYPE_DUMMY_STATE; |
|---|
| 192 | 192 | |
|---|
| 193 | 193 | return dt_remember_or_free_map(p, statename, NULL, map, 1); |
|---|
| 194 | | -} |
|---|
| 195 | | - |
|---|
| 196 | | -bool pinctrl_dt_has_hogs(struct pinctrl_dev *pctldev) |
|---|
| 197 | | -{ |
|---|
| 198 | | - struct device_node *np; |
|---|
| 199 | | - struct property *prop; |
|---|
| 200 | | - int size; |
|---|
| 201 | | - |
|---|
| 202 | | - np = pctldev->dev->of_node; |
|---|
| 203 | | - if (!np) |
|---|
| 204 | | - return false; |
|---|
| 205 | | - |
|---|
| 206 | | - prop = of_find_property(np, "pinctrl-0", &size); |
|---|
| 207 | | - |
|---|
| 208 | | - return prop ? true : false; |
|---|
| 209 | 194 | } |
|---|
| 210 | 195 | |
|---|
| 211 | 196 | int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev) |
|---|
| .. | .. |
|---|
| 235 | 220 | for (state = 0; ; state++) { |
|---|
| 236 | 221 | /* Retrieve the pinctrl-* property */ |
|---|
| 237 | 222 | propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); |
|---|
| 223 | + if (!propname) |
|---|
| 224 | + return -ENOMEM; |
|---|
| 238 | 225 | prop = of_find_property(np, propname, &size); |
|---|
| 239 | 226 | kfree(propname); |
|---|
| 240 | 227 | if (!prop) { |
|---|
| .. | .. |
|---|
| 255 | 242 | * than dynamically allocate it and have to free it later, |
|---|
| 256 | 243 | * just point part way into the property name for the string. |
|---|
| 257 | 244 | */ |
|---|
| 258 | | - if (ret < 0) { |
|---|
| 259 | | - /* strlen("pinctrl-") == 8 */ |
|---|
| 260 | | - statename = prop->name + 8; |
|---|
| 261 | | - } |
|---|
| 245 | + if (ret < 0) |
|---|
| 246 | + statename = prop->name + strlen("pinctrl-"); |
|---|
| 262 | 247 | |
|---|
| 263 | 248 | /* For every referenced pin configuration node in it */ |
|---|
| 264 | 249 | for (config = 0; config < size; config++) { |
|---|
| .. | .. |
|---|
| 414 | 399 | * @np: pointer to device node with the property |
|---|
| 415 | 400 | * @list_name: property that contains the list |
|---|
| 416 | 401 | * @index: index within the list |
|---|
| 417 | | - * @out_arts: entries in the list pointed by index |
|---|
| 402 | + * @out_args: entries in the list pointed by index |
|---|
| 418 | 403 | * |
|---|
| 419 | 404 | * Finds the selected element in a pinctrl array consisting of an index |
|---|
| 420 | 405 | * within the controller and a number of u32 entries specified for each |
|---|