xref: /OK3568_Linux_fs/kernel/drivers/pinctrl/devicetree.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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