1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Device tree integration for the pin control subsystem
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/device.h>
9*4882a593Smuzhiyun #include <linux/of.h>
10*4882a593Smuzhiyun #include <linux/pinctrl/pinctrl.h>
11*4882a593Smuzhiyun #include <linux/slab.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include "core.h"
14*4882a593Smuzhiyun #include "devicetree.h"
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun /**
17*4882a593Smuzhiyun * struct pinctrl_dt_map - mapping table chunk parsed from device tree
18*4882a593Smuzhiyun * @node: list node for struct pinctrl's @dt_maps field
19*4882a593Smuzhiyun * @pctldev: the pin controller that allocated this struct, and will free it
20*4882a593Smuzhiyun * @map: the mapping table entries
21*4882a593Smuzhiyun * @num_maps: number of mapping table entries
22*4882a593Smuzhiyun */
23*4882a593Smuzhiyun struct pinctrl_dt_map {
24*4882a593Smuzhiyun struct list_head node;
25*4882a593Smuzhiyun struct pinctrl_dev *pctldev;
26*4882a593Smuzhiyun struct pinctrl_map *map;
27*4882a593Smuzhiyun unsigned num_maps;
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
dt_free_map(struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned num_maps)30*4882a593Smuzhiyun static void dt_free_map(struct pinctrl_dev *pctldev,
31*4882a593Smuzhiyun struct pinctrl_map *map, unsigned num_maps)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun int i;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun for (i = 0; i < num_maps; ++i) {
36*4882a593Smuzhiyun kfree_const(map[i].dev_name);
37*4882a593Smuzhiyun map[i].dev_name = NULL;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun if (pctldev) {
41*4882a593Smuzhiyun const struct pinctrl_ops *ops = pctldev->desc->pctlops;
42*4882a593Smuzhiyun if (ops->dt_free_map)
43*4882a593Smuzhiyun ops->dt_free_map(pctldev, map, num_maps);
44*4882a593Smuzhiyun } else {
45*4882a593Smuzhiyun /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
46*4882a593Smuzhiyun kfree(map);
47*4882a593Smuzhiyun }
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
pinctrl_dt_free_maps(struct pinctrl * p)50*4882a593Smuzhiyun void pinctrl_dt_free_maps(struct pinctrl *p)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun struct pinctrl_dt_map *dt_map, *n1;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun list_for_each_entry_safe(dt_map, n1, &p->dt_maps, node) {
55*4882a593Smuzhiyun pinctrl_unregister_mappings(dt_map->map);
56*4882a593Smuzhiyun list_del(&dt_map->node);
57*4882a593Smuzhiyun dt_free_map(dt_map->pctldev, dt_map->map,
58*4882a593Smuzhiyun dt_map->num_maps);
59*4882a593Smuzhiyun kfree(dt_map);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun of_node_put(p->dev->of_node);
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
dt_remember_or_free_map(struct pinctrl * p,const char * statename,struct pinctrl_dev * pctldev,struct pinctrl_map * map,unsigned num_maps)65*4882a593Smuzhiyun static int dt_remember_or_free_map(struct pinctrl *p, const char *statename,
66*4882a593Smuzhiyun struct pinctrl_dev *pctldev,
67*4882a593Smuzhiyun struct pinctrl_map *map, unsigned num_maps)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun int i;
70*4882a593Smuzhiyun struct pinctrl_dt_map *dt_map;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* Initialize common mapping table entry fields */
73*4882a593Smuzhiyun for (i = 0; i < num_maps; i++) {
74*4882a593Smuzhiyun const char *devname;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun devname = kstrdup_const(dev_name(p->dev), GFP_KERNEL);
77*4882a593Smuzhiyun if (!devname)
78*4882a593Smuzhiyun goto err_free_map;
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun map[i].dev_name = devname;
81*4882a593Smuzhiyun map[i].name = statename;
82*4882a593Smuzhiyun if (pctldev)
83*4882a593Smuzhiyun map[i].ctrl_dev_name = dev_name(pctldev->dev);
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /* Remember the converted mapping table entries */
87*4882a593Smuzhiyun dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL);
88*4882a593Smuzhiyun if (!dt_map)
89*4882a593Smuzhiyun goto err_free_map;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun dt_map->pctldev = pctldev;
92*4882a593Smuzhiyun dt_map->map = map;
93*4882a593Smuzhiyun dt_map->num_maps = num_maps;
94*4882a593Smuzhiyun list_add_tail(&dt_map->node, &p->dt_maps);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun return pinctrl_register_mappings(map, num_maps);
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun err_free_map:
99*4882a593Smuzhiyun dt_free_map(pctldev, map, num_maps);
100*4882a593Smuzhiyun return -ENOMEM;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
of_pinctrl_get(struct device_node * np)103*4882a593Smuzhiyun struct pinctrl_dev *of_pinctrl_get(struct device_node *np)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun return get_pinctrl_dev_from_of_node(np);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(of_pinctrl_get);
108*4882a593Smuzhiyun
dt_to_map_one_config(struct pinctrl * p,struct pinctrl_dev * hog_pctldev,const char * statename,struct device_node * np_config)109*4882a593Smuzhiyun static int dt_to_map_one_config(struct pinctrl *p,
110*4882a593Smuzhiyun struct pinctrl_dev *hog_pctldev,
111*4882a593Smuzhiyun const char *statename,
112*4882a593Smuzhiyun struct device_node *np_config)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun struct pinctrl_dev *pctldev = NULL;
115*4882a593Smuzhiyun struct device_node *np_pctldev;
116*4882a593Smuzhiyun const struct pinctrl_ops *ops;
117*4882a593Smuzhiyun int ret;
118*4882a593Smuzhiyun struct pinctrl_map *map;
119*4882a593Smuzhiyun unsigned num_maps;
120*4882a593Smuzhiyun bool allow_default = false;
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun /* Find the pin controller containing np_config */
123*4882a593Smuzhiyun np_pctldev = of_node_get(np_config);
124*4882a593Smuzhiyun for (;;) {
125*4882a593Smuzhiyun if (!allow_default)
126*4882a593Smuzhiyun allow_default = of_property_read_bool(np_pctldev,
127*4882a593Smuzhiyun "pinctrl-use-default");
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun np_pctldev = of_get_next_parent(np_pctldev);
130*4882a593Smuzhiyun if (!np_pctldev || of_node_is_root(np_pctldev)) {
131*4882a593Smuzhiyun of_node_put(np_pctldev);
132*4882a593Smuzhiyun ret = driver_deferred_probe_check_state(p->dev);
133*4882a593Smuzhiyun /* keep deferring if modules are enabled */
134*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_MODULES) && !allow_default && ret < 0)
135*4882a593Smuzhiyun ret = -EPROBE_DEFER;
136*4882a593Smuzhiyun return ret;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun /* If we're creating a hog we can use the passed pctldev */
139*4882a593Smuzhiyun if (hog_pctldev && (np_pctldev == p->dev->of_node)) {
140*4882a593Smuzhiyun pctldev = hog_pctldev;
141*4882a593Smuzhiyun break;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun pctldev = get_pinctrl_dev_from_of_node(np_pctldev);
144*4882a593Smuzhiyun if (pctldev)
145*4882a593Smuzhiyun break;
146*4882a593Smuzhiyun /* Do not defer probing of hogs (circular loop) */
147*4882a593Smuzhiyun if (np_pctldev == p->dev->of_node) {
148*4882a593Smuzhiyun of_node_put(np_pctldev);
149*4882a593Smuzhiyun return -ENODEV;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun of_node_put(np_pctldev);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /*
155*4882a593Smuzhiyun * Call pinctrl driver to parse device tree node, and
156*4882a593Smuzhiyun * generate mapping table entries
157*4882a593Smuzhiyun */
158*4882a593Smuzhiyun ops = pctldev->desc->pctlops;
159*4882a593Smuzhiyun if (!ops->dt_node_to_map) {
160*4882a593Smuzhiyun dev_err(p->dev, "pctldev %s doesn't support DT\n",
161*4882a593Smuzhiyun dev_name(pctldev->dev));
162*4882a593Smuzhiyun return -ENODEV;
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun ret = ops->dt_node_to_map(pctldev, np_config, &map, &num_maps);
165*4882a593Smuzhiyun if (ret < 0)
166*4882a593Smuzhiyun return ret;
167*4882a593Smuzhiyun else if (num_maps == 0) {
168*4882a593Smuzhiyun /*
169*4882a593Smuzhiyun * If we have no valid maps (maybe caused by empty pinctrl node
170*4882a593Smuzhiyun * or typing error) ther is no need remember this, so just
171*4882a593Smuzhiyun * return.
172*4882a593Smuzhiyun */
173*4882a593Smuzhiyun dev_info(p->dev,
174*4882a593Smuzhiyun "there is not valid maps for state %s\n", statename);
175*4882a593Smuzhiyun return 0;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun /* Stash the mapping table chunk away for later use */
179*4882a593Smuzhiyun return dt_remember_or_free_map(p, statename, pctldev, map, num_maps);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
dt_remember_dummy_state(struct pinctrl * p,const char * statename)182*4882a593Smuzhiyun static int dt_remember_dummy_state(struct pinctrl *p, const char *statename)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun struct pinctrl_map *map;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun map = kzalloc(sizeof(*map), GFP_KERNEL);
187*4882a593Smuzhiyun if (!map)
188*4882a593Smuzhiyun return -ENOMEM;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* There is no pctldev for PIN_MAP_TYPE_DUMMY_STATE */
191*4882a593Smuzhiyun map->type = PIN_MAP_TYPE_DUMMY_STATE;
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun return dt_remember_or_free_map(p, statename, NULL, map, 1);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
pinctrl_dt_to_map(struct pinctrl * p,struct pinctrl_dev * pctldev)196*4882a593Smuzhiyun int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun struct device_node *np = p->dev->of_node;
199*4882a593Smuzhiyun int state, ret;
200*4882a593Smuzhiyun char *propname;
201*4882a593Smuzhiyun struct property *prop;
202*4882a593Smuzhiyun const char *statename;
203*4882a593Smuzhiyun const __be32 *list;
204*4882a593Smuzhiyun int size, config;
205*4882a593Smuzhiyun phandle phandle;
206*4882a593Smuzhiyun struct device_node *np_config;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* CONFIG_OF enabled, p->dev not instantiated from DT */
209*4882a593Smuzhiyun if (!np) {
210*4882a593Smuzhiyun if (of_have_populated_dt())
211*4882a593Smuzhiyun dev_dbg(p->dev,
212*4882a593Smuzhiyun "no of_node; not parsing pinctrl DT\n");
213*4882a593Smuzhiyun return 0;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* We may store pointers to property names within the node */
217*4882a593Smuzhiyun of_node_get(np);
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /* For each defined state ID */
220*4882a593Smuzhiyun for (state = 0; ; state++) {
221*4882a593Smuzhiyun /* Retrieve the pinctrl-* property */
222*4882a593Smuzhiyun propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
223*4882a593Smuzhiyun if (!propname)
224*4882a593Smuzhiyun return -ENOMEM;
225*4882a593Smuzhiyun prop = of_find_property(np, propname, &size);
226*4882a593Smuzhiyun kfree(propname);
227*4882a593Smuzhiyun if (!prop) {
228*4882a593Smuzhiyun if (state == 0) {
229*4882a593Smuzhiyun of_node_put(np);
230*4882a593Smuzhiyun return -ENODEV;
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun break;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun list = prop->value;
235*4882a593Smuzhiyun size /= sizeof(*list);
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* Determine whether pinctrl-names property names the state */
238*4882a593Smuzhiyun ret = of_property_read_string_index(np, "pinctrl-names",
239*4882a593Smuzhiyun state, &statename);
240*4882a593Smuzhiyun /*
241*4882a593Smuzhiyun * If not, statename is just the integer state ID. But rather
242*4882a593Smuzhiyun * than dynamically allocate it and have to free it later,
243*4882a593Smuzhiyun * just point part way into the property name for the string.
244*4882a593Smuzhiyun */
245*4882a593Smuzhiyun if (ret < 0)
246*4882a593Smuzhiyun statename = prop->name + strlen("pinctrl-");
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun /* For every referenced pin configuration node in it */
249*4882a593Smuzhiyun for (config = 0; config < size; config++) {
250*4882a593Smuzhiyun phandle = be32_to_cpup(list++);
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* Look up the pin configuration node */
253*4882a593Smuzhiyun np_config = of_find_node_by_phandle(phandle);
254*4882a593Smuzhiyun if (!np_config) {
255*4882a593Smuzhiyun dev_err(p->dev,
256*4882a593Smuzhiyun "prop %s index %i invalid phandle\n",
257*4882a593Smuzhiyun prop->name, config);
258*4882a593Smuzhiyun ret = -EINVAL;
259*4882a593Smuzhiyun goto err;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun /* Parse the node */
263*4882a593Smuzhiyun ret = dt_to_map_one_config(p, pctldev, statename,
264*4882a593Smuzhiyun np_config);
265*4882a593Smuzhiyun of_node_put(np_config);
266*4882a593Smuzhiyun if (ret < 0)
267*4882a593Smuzhiyun goto err;
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* No entries in DT? Generate a dummy state table entry */
271*4882a593Smuzhiyun if (!size) {
272*4882a593Smuzhiyun ret = dt_remember_dummy_state(p, statename);
273*4882a593Smuzhiyun if (ret < 0)
274*4882a593Smuzhiyun goto err;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun return 0;
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun err:
281*4882a593Smuzhiyun pinctrl_dt_free_maps(p);
282*4882a593Smuzhiyun return ret;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /*
286*4882a593Smuzhiyun * For pinctrl binding, typically #pinctrl-cells is for the pin controller
287*4882a593Smuzhiyun * device, so either parent or grandparent. See pinctrl-bindings.txt.
288*4882a593Smuzhiyun */
pinctrl_find_cells_size(const struct device_node * np)289*4882a593Smuzhiyun static int pinctrl_find_cells_size(const struct device_node *np)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun const char *cells_name = "#pinctrl-cells";
292*4882a593Smuzhiyun int cells_size, error;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun error = of_property_read_u32(np->parent, cells_name, &cells_size);
295*4882a593Smuzhiyun if (error) {
296*4882a593Smuzhiyun error = of_property_read_u32(np->parent->parent,
297*4882a593Smuzhiyun cells_name, &cells_size);
298*4882a593Smuzhiyun if (error)
299*4882a593Smuzhiyun return -ENOENT;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun return cells_size;
303*4882a593Smuzhiyun }
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun /**
306*4882a593Smuzhiyun * pinctrl_get_list_and_count - Gets the list and it's cell size and number
307*4882a593Smuzhiyun * @np: pointer to device node with the property
308*4882a593Smuzhiyun * @list_name: property that contains the list
309*4882a593Smuzhiyun * @list: pointer for the list found
310*4882a593Smuzhiyun * @cells_size: pointer for the cell size found
311*4882a593Smuzhiyun * @nr_elements: pointer for the number of elements found
312*4882a593Smuzhiyun *
313*4882a593Smuzhiyun * Typically np is a single pinctrl entry containing the list.
314*4882a593Smuzhiyun */
pinctrl_get_list_and_count(const struct device_node * np,const char * list_name,const __be32 ** list,int * cells_size,int * nr_elements)315*4882a593Smuzhiyun static int pinctrl_get_list_and_count(const struct device_node *np,
316*4882a593Smuzhiyun const char *list_name,
317*4882a593Smuzhiyun const __be32 **list,
318*4882a593Smuzhiyun int *cells_size,
319*4882a593Smuzhiyun int *nr_elements)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun int size;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun *cells_size = 0;
324*4882a593Smuzhiyun *nr_elements = 0;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun *list = of_get_property(np, list_name, &size);
327*4882a593Smuzhiyun if (!*list)
328*4882a593Smuzhiyun return -ENOENT;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun *cells_size = pinctrl_find_cells_size(np);
331*4882a593Smuzhiyun if (*cells_size < 0)
332*4882a593Smuzhiyun return -ENOENT;
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* First element is always the index within the pinctrl device */
335*4882a593Smuzhiyun *nr_elements = (size / sizeof(**list)) / (*cells_size + 1);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun return 0;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /**
341*4882a593Smuzhiyun * pinctrl_count_index_with_args - Count number of elements in a pinctrl entry
342*4882a593Smuzhiyun * @np: pointer to device node with the property
343*4882a593Smuzhiyun * @list_name: property that contains the list
344*4882a593Smuzhiyun *
345*4882a593Smuzhiyun * Counts the number of elements in a pinctrl array consisting of an index
346*4882a593Smuzhiyun * within the controller and a number of u32 entries specified for each
347*4882a593Smuzhiyun * entry. Note that device_node is always for the parent pin controller device.
348*4882a593Smuzhiyun */
pinctrl_count_index_with_args(const struct device_node * np,const char * list_name)349*4882a593Smuzhiyun int pinctrl_count_index_with_args(const struct device_node *np,
350*4882a593Smuzhiyun const char *list_name)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun const __be32 *list;
353*4882a593Smuzhiyun int size, nr_cells, error;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun error = pinctrl_get_list_and_count(np, list_name, &list,
356*4882a593Smuzhiyun &nr_cells, &size);
357*4882a593Smuzhiyun if (error)
358*4882a593Smuzhiyun return error;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return size;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pinctrl_count_index_with_args);
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun /**
365*4882a593Smuzhiyun * pinctrl_copy_args - Populates of_phandle_args based on index
366*4882a593Smuzhiyun * @np: pointer to device node with the property
367*4882a593Smuzhiyun * @list: pointer to a list with the elements
368*4882a593Smuzhiyun * @index: entry within the list of elements
369*4882a593Smuzhiyun * @nr_cells: number of cells in the list
370*4882a593Smuzhiyun * @nr_elem: number of elements for each entry in the list
371*4882a593Smuzhiyun * @out_args: returned values
372*4882a593Smuzhiyun *
373*4882a593Smuzhiyun * Populates the of_phandle_args based on the index in the list.
374*4882a593Smuzhiyun */
pinctrl_copy_args(const struct device_node * np,const __be32 * list,int index,int nr_cells,int nr_elem,struct of_phandle_args * out_args)375*4882a593Smuzhiyun static int pinctrl_copy_args(const struct device_node *np,
376*4882a593Smuzhiyun const __be32 *list,
377*4882a593Smuzhiyun int index, int nr_cells, int nr_elem,
378*4882a593Smuzhiyun struct of_phandle_args *out_args)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun int i;
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun memset(out_args, 0, sizeof(*out_args));
383*4882a593Smuzhiyun out_args->np = (struct device_node *)np;
384*4882a593Smuzhiyun out_args->args_count = nr_cells + 1;
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun if (index >= nr_elem)
387*4882a593Smuzhiyun return -EINVAL;
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun list += index * (nr_cells + 1);
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun for (i = 0; i < nr_cells + 1; i++)
392*4882a593Smuzhiyun out_args->args[i] = be32_to_cpup(list++);
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun return 0;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /**
398*4882a593Smuzhiyun * pinctrl_parse_index_with_args - Find a node pointed by index in a list
399*4882a593Smuzhiyun * @np: pointer to device node with the property
400*4882a593Smuzhiyun * @list_name: property that contains the list
401*4882a593Smuzhiyun * @index: index within the list
402*4882a593Smuzhiyun * @out_args: entries in the list pointed by index
403*4882a593Smuzhiyun *
404*4882a593Smuzhiyun * Finds the selected element in a pinctrl array consisting of an index
405*4882a593Smuzhiyun * within the controller and a number of u32 entries specified for each
406*4882a593Smuzhiyun * entry. Note that device_node is always for the parent pin controller device.
407*4882a593Smuzhiyun */
pinctrl_parse_index_with_args(const struct device_node * np,const char * list_name,int index,struct of_phandle_args * out_args)408*4882a593Smuzhiyun int pinctrl_parse_index_with_args(const struct device_node *np,
409*4882a593Smuzhiyun const char *list_name, int index,
410*4882a593Smuzhiyun struct of_phandle_args *out_args)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun const __be32 *list;
413*4882a593Smuzhiyun int nr_elem, nr_cells, error;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun error = pinctrl_get_list_and_count(np, list_name, &list,
416*4882a593Smuzhiyun &nr_cells, &nr_elem);
417*4882a593Smuzhiyun if (error || !nr_cells)
418*4882a593Smuzhiyun return error;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun error = pinctrl_copy_args(np, list, index, nr_cells, nr_elem,
421*4882a593Smuzhiyun out_args);
422*4882a593Smuzhiyun if (error)
423*4882a593Smuzhiyun return error;
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun return 0;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(pinctrl_parse_index_with_args);
428