xref: /rk3399_rockchip-uboot/drivers/pinctrl/pinctrl-generic.c (revision 2c936374c81a24a461cf71725a1e9ce439e048ed)
1d90a5a30SMasahiro Yamada /*
2d90a5a30SMasahiro Yamada  * Copyright (C) 2015  Masahiro Yamada <yamada.masahiro@socionext.com>
3d90a5a30SMasahiro Yamada  *
4d90a5a30SMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0+
5d90a5a30SMasahiro Yamada  */
6d90a5a30SMasahiro Yamada 
7d90a5a30SMasahiro Yamada #include <common.h>
8d90a5a30SMasahiro Yamada #include <linux/compat.h>
9d90a5a30SMasahiro Yamada #include <dm/device.h>
10d90a5a30SMasahiro Yamada #include <dm/pinctrl.h>
11d90a5a30SMasahiro Yamada 
12d90a5a30SMasahiro Yamada DECLARE_GLOBAL_DATA_PTR;
13d90a5a30SMasahiro Yamada 
14d90a5a30SMasahiro Yamada /**
15d90a5a30SMasahiro Yamada  * pinctrl_pin_name_to_selector() - return the pin selector for a pin
16d90a5a30SMasahiro Yamada  *
17d90a5a30SMasahiro Yamada  * @dev: pin controller device
18d90a5a30SMasahiro Yamada  * @pin: the pin name to look up
19d90a5a30SMasahiro Yamada  * @return: pin selector, or negative error code on failure
20d90a5a30SMasahiro Yamada  */
21d90a5a30SMasahiro Yamada static int pinctrl_pin_name_to_selector(struct udevice *dev, const char *pin)
22d90a5a30SMasahiro Yamada {
23d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
24d90a5a30SMasahiro Yamada 	unsigned npins, selector;
25d90a5a30SMasahiro Yamada 
26d90a5a30SMasahiro Yamada 	if (!ops->get_pins_count || !ops->get_pin_name) {
27d90a5a30SMasahiro Yamada 		dev_dbg(dev, "get_pins_count or get_pin_name missing\n");
28d90a5a30SMasahiro Yamada 		return -ENOSYS;
29d90a5a30SMasahiro Yamada 	}
30d90a5a30SMasahiro Yamada 
31d90a5a30SMasahiro Yamada 	npins = ops->get_pins_count(dev);
32d90a5a30SMasahiro Yamada 
33d90a5a30SMasahiro Yamada 	/* See if this pctldev has this pin */
34d90a5a30SMasahiro Yamada 	for (selector = 0; selector < npins; selector++) {
35d90a5a30SMasahiro Yamada 		const char *pname = ops->get_pin_name(dev, selector);
36d90a5a30SMasahiro Yamada 
37d90a5a30SMasahiro Yamada 		if (!strcmp(pin, pname))
38d90a5a30SMasahiro Yamada 			return selector;
39d90a5a30SMasahiro Yamada 	}
40d90a5a30SMasahiro Yamada 
41d90a5a30SMasahiro Yamada 	return -ENOSYS;
42d90a5a30SMasahiro Yamada }
43d90a5a30SMasahiro Yamada 
44d90a5a30SMasahiro Yamada /**
45d90a5a30SMasahiro Yamada  * pinctrl_group_name_to_selector() - return the group selector for a group
46d90a5a30SMasahiro Yamada  *
47d90a5a30SMasahiro Yamada  * @dev: pin controller device
48d90a5a30SMasahiro Yamada  * @group: the pin group name to look up
49d90a5a30SMasahiro Yamada  * @return: pin group selector, or negative error code on failure
50d90a5a30SMasahiro Yamada  */
51d90a5a30SMasahiro Yamada static int pinctrl_group_name_to_selector(struct udevice *dev,
52d90a5a30SMasahiro Yamada 					  const char *group)
53d90a5a30SMasahiro Yamada {
54d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
55d90a5a30SMasahiro Yamada 	unsigned ngroups, selector;
56d90a5a30SMasahiro Yamada 
57d90a5a30SMasahiro Yamada 	if (!ops->get_groups_count || !ops->get_group_name) {
58d90a5a30SMasahiro Yamada 		dev_dbg(dev, "get_groups_count or get_group_name missing\n");
59d90a5a30SMasahiro Yamada 		return -ENOSYS;
60d90a5a30SMasahiro Yamada 	}
61d90a5a30SMasahiro Yamada 
62d90a5a30SMasahiro Yamada 	ngroups = ops->get_groups_count(dev);
63d90a5a30SMasahiro Yamada 
64d90a5a30SMasahiro Yamada 	/* See if this pctldev has this group */
65d90a5a30SMasahiro Yamada 	for (selector = 0; selector < ngroups; selector++) {
66d90a5a30SMasahiro Yamada 		const char *gname = ops->get_group_name(dev, selector);
67d90a5a30SMasahiro Yamada 
68d90a5a30SMasahiro Yamada 		if (!strcmp(group, gname))
69d90a5a30SMasahiro Yamada 			return selector;
70d90a5a30SMasahiro Yamada 	}
71d90a5a30SMasahiro Yamada 
72d90a5a30SMasahiro Yamada 	return -ENOSYS;
73d90a5a30SMasahiro Yamada }
74d90a5a30SMasahiro Yamada 
75d90a5a30SMasahiro Yamada #if CONFIG_IS_ENABLED(PINMUX)
76d90a5a30SMasahiro Yamada /**
77d90a5a30SMasahiro Yamada  * pinmux_func_name_to_selector() - return the function selector for a function
78d90a5a30SMasahiro Yamada  *
79d90a5a30SMasahiro Yamada  * @dev: pin controller device
80d90a5a30SMasahiro Yamada  * @function: the function name to look up
81d90a5a30SMasahiro Yamada  * @return: function selector, or negative error code on failure
82d90a5a30SMasahiro Yamada  */
83d90a5a30SMasahiro Yamada static int pinmux_func_name_to_selector(struct udevice *dev,
84d90a5a30SMasahiro Yamada 					const char *function)
85d90a5a30SMasahiro Yamada {
86d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
87d90a5a30SMasahiro Yamada 	unsigned nfuncs, selector = 0;
88d90a5a30SMasahiro Yamada 
89d90a5a30SMasahiro Yamada 	if (!ops->get_functions_count || !ops->get_function_name) {
90d90a5a30SMasahiro Yamada 		dev_dbg(dev,
91d90a5a30SMasahiro Yamada 			"get_functions_count or get_function_name missing\n");
92d90a5a30SMasahiro Yamada 		return -ENOSYS;
93d90a5a30SMasahiro Yamada 	}
94d90a5a30SMasahiro Yamada 
95d90a5a30SMasahiro Yamada 	nfuncs = ops->get_functions_count(dev);
96d90a5a30SMasahiro Yamada 
97d90a5a30SMasahiro Yamada 	/* See if this pctldev has this function */
98d90a5a30SMasahiro Yamada 	for (selector = 0; selector < nfuncs; selector++) {
99d90a5a30SMasahiro Yamada 		const char *fname = ops->get_function_name(dev, selector);
100d90a5a30SMasahiro Yamada 
101d90a5a30SMasahiro Yamada 		if (!strcmp(function, fname))
102d90a5a30SMasahiro Yamada 			return selector;
103d90a5a30SMasahiro Yamada 	}
104d90a5a30SMasahiro Yamada 
105d90a5a30SMasahiro Yamada 	return -ENOSYS;
106d90a5a30SMasahiro Yamada }
107d90a5a30SMasahiro Yamada 
108d90a5a30SMasahiro Yamada /**
109d90a5a30SMasahiro Yamada  * pinmux_enable_setting() - enable pin-mux setting for a certain pin/group
110d90a5a30SMasahiro Yamada  *
111d90a5a30SMasahiro Yamada  * @dev: pin controller device
112d90a5a30SMasahiro Yamada  * @is_group: target of operation (true: pin group, false: pin)
113d90a5a30SMasahiro Yamada  * @selector: pin selector or group selector, depending on @is_group
114d90a5a30SMasahiro Yamada  * @func_selector: function selector
115d90a5a30SMasahiro Yamada  * @return: 0 on success, or negative error code on failure
116d90a5a30SMasahiro Yamada  */
117d90a5a30SMasahiro Yamada static int pinmux_enable_setting(struct udevice *dev, bool is_group,
118d90a5a30SMasahiro Yamada 				 unsigned selector, unsigned func_selector)
119d90a5a30SMasahiro Yamada {
120d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
121d90a5a30SMasahiro Yamada 
122d90a5a30SMasahiro Yamada 	if (is_group) {
123d90a5a30SMasahiro Yamada 		if (!ops->pinmux_group_set) {
124d90a5a30SMasahiro Yamada 			dev_dbg(dev, "pinmux_group_set op missing\n");
125d90a5a30SMasahiro Yamada 			return -ENOSYS;
126d90a5a30SMasahiro Yamada 		}
127d90a5a30SMasahiro Yamada 
128d90a5a30SMasahiro Yamada 		return ops->pinmux_group_set(dev, selector, func_selector);
129d90a5a30SMasahiro Yamada 	} else {
130d90a5a30SMasahiro Yamada 		if (!ops->pinmux_set) {
131d90a5a30SMasahiro Yamada 			dev_dbg(dev, "pinmux_set op missing\n");
132d90a5a30SMasahiro Yamada 			return -ENOSYS;
133d90a5a30SMasahiro Yamada 		}
134d90a5a30SMasahiro Yamada 		return ops->pinmux_set(dev, selector, func_selector);
135d90a5a30SMasahiro Yamada 	}
136d90a5a30SMasahiro Yamada }
137d90a5a30SMasahiro Yamada #else
138d90a5a30SMasahiro Yamada static int pinmux_func_name_to_selector(struct udevice *dev,
139d90a5a30SMasahiro Yamada 					const char *function)
140d90a5a30SMasahiro Yamada {
141d90a5a30SMasahiro Yamada 	return 0;
142d90a5a30SMasahiro Yamada }
143d90a5a30SMasahiro Yamada 
144d90a5a30SMasahiro Yamada static int pinmux_enable_setting(struct udevice *dev, bool is_group,
145d90a5a30SMasahiro Yamada 				 unsigned selector, unsigned func_selector)
146d90a5a30SMasahiro Yamada {
147d90a5a30SMasahiro Yamada 	return 0;
148d90a5a30SMasahiro Yamada }
149d90a5a30SMasahiro Yamada #endif
150d90a5a30SMasahiro Yamada 
151d90a5a30SMasahiro Yamada #if CONFIG_IS_ENABLED(PINCONF)
152d90a5a30SMasahiro Yamada /**
153d90a5a30SMasahiro Yamada  * pinconf_prop_name_to_param() - return parameter ID for a property name
154d90a5a30SMasahiro Yamada  *
155d90a5a30SMasahiro Yamada  * @dev: pin controller device
156d90a5a30SMasahiro Yamada  * @property: property name in DTS, such as "bias-pull-up", "slew-rate", etc.
157d90a5a30SMasahiro Yamada  * @default_value: return default value in case no value is specified in DTS
158d90a5a30SMasahiro Yamada  * @return: return pamater ID, or negative error code on failure
159d90a5a30SMasahiro Yamada  */
160d90a5a30SMasahiro Yamada static int pinconf_prop_name_to_param(struct udevice *dev,
161d90a5a30SMasahiro Yamada 				      const char *property, u32 *default_value)
162d90a5a30SMasahiro Yamada {
163d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
164d90a5a30SMasahiro Yamada 	const struct pinconf_param *p, *end;
165d90a5a30SMasahiro Yamada 
166d90a5a30SMasahiro Yamada 	if (!ops->pinconf_num_params || !ops->pinconf_params) {
167d90a5a30SMasahiro Yamada 		dev_dbg(dev, "pinconf_num_params or pinconf_params missing\n");
168d90a5a30SMasahiro Yamada 		return -ENOSYS;
169d90a5a30SMasahiro Yamada 	}
170d90a5a30SMasahiro Yamada 
171d90a5a30SMasahiro Yamada 	p = ops->pinconf_params;
172d90a5a30SMasahiro Yamada 	end = p + ops->pinconf_num_params;
173d90a5a30SMasahiro Yamada 
174d90a5a30SMasahiro Yamada 	/* See if this pctldev supports this parameter */
175d90a5a30SMasahiro Yamada 	for (; p < end; p++) {
176d90a5a30SMasahiro Yamada 		if (!strcmp(property, p->property)) {
177d90a5a30SMasahiro Yamada 			*default_value = p->default_value;
178d90a5a30SMasahiro Yamada 			return p->param;
179d90a5a30SMasahiro Yamada 		}
180d90a5a30SMasahiro Yamada 	}
181d90a5a30SMasahiro Yamada 
182d90a5a30SMasahiro Yamada 	return -ENOSYS;
183d90a5a30SMasahiro Yamada }
184d90a5a30SMasahiro Yamada 
185d90a5a30SMasahiro Yamada /**
186d90a5a30SMasahiro Yamada  * pinconf_enable_setting() - apply pin configuration for a certain pin/group
187d90a5a30SMasahiro Yamada  *
188d90a5a30SMasahiro Yamada  * @dev: pin controller device
189d90a5a30SMasahiro Yamada  * @is_group: target of operation (true: pin group, false: pin)
190d90a5a30SMasahiro Yamada  * @selector: pin selector or group selector, depending on @is_group
191d90a5a30SMasahiro Yamada  * @param: configuration paramter
192d90a5a30SMasahiro Yamada  * @argument: argument taken by some configuration parameters
193d90a5a30SMasahiro Yamada  * @return: 0 on success, or negative error code on failure
194d90a5a30SMasahiro Yamada  */
195d90a5a30SMasahiro Yamada static int pinconf_enable_setting(struct udevice *dev, bool is_group,
196d90a5a30SMasahiro Yamada 				  unsigned selector, unsigned param,
197d90a5a30SMasahiro Yamada 				  u32 argument)
198d90a5a30SMasahiro Yamada {
199d90a5a30SMasahiro Yamada 	const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
200d90a5a30SMasahiro Yamada 
201d90a5a30SMasahiro Yamada 	if (is_group) {
202d90a5a30SMasahiro Yamada 		if (!ops->pinconf_group_set) {
203d90a5a30SMasahiro Yamada 			dev_dbg(dev, "pinconf_group_set op missing\n");
204d90a5a30SMasahiro Yamada 			return -ENOSYS;
205d90a5a30SMasahiro Yamada 		}
206d90a5a30SMasahiro Yamada 
207d90a5a30SMasahiro Yamada 		return ops->pinconf_group_set(dev, selector, param,
208d90a5a30SMasahiro Yamada 					      argument);
209d90a5a30SMasahiro Yamada 	} else {
210d90a5a30SMasahiro Yamada 		if (!ops->pinconf_set) {
211d90a5a30SMasahiro Yamada 			dev_dbg(dev, "pinconf_set op missing\n");
212d90a5a30SMasahiro Yamada 			return -ENOSYS;
213d90a5a30SMasahiro Yamada 		}
214d90a5a30SMasahiro Yamada 		return ops->pinconf_set(dev, selector, param, argument);
215d90a5a30SMasahiro Yamada 	}
216d90a5a30SMasahiro Yamada }
217d90a5a30SMasahiro Yamada #else
218d90a5a30SMasahiro Yamada static int pinconf_prop_name_to_param(struct udevice *dev,
219d90a5a30SMasahiro Yamada 				      const char *property, u32 *default_value)
220d90a5a30SMasahiro Yamada {
221d90a5a30SMasahiro Yamada 	return -ENOSYS;
222d90a5a30SMasahiro Yamada }
223d90a5a30SMasahiro Yamada 
224d90a5a30SMasahiro Yamada static int pinconf_enable_setting(struct udevice *dev, bool is_group,
225d90a5a30SMasahiro Yamada 				  unsigned selector, unsigned param,
226d90a5a30SMasahiro Yamada 				  u32 argument)
227d90a5a30SMasahiro Yamada {
228d90a5a30SMasahiro Yamada 	return 0;
229d90a5a30SMasahiro Yamada }
230d90a5a30SMasahiro Yamada #endif
231d90a5a30SMasahiro Yamada 
232d90a5a30SMasahiro Yamada /**
233d90a5a30SMasahiro Yamada  * pinctrl_generic_set_state_one() - set state for a certain pin/group
234d90a5a30SMasahiro Yamada  * Apply all pin multiplexing and pin configurations specified by @config
235d90a5a30SMasahiro Yamada  * for a given pin or pin group.
236d90a5a30SMasahiro Yamada  *
237d90a5a30SMasahiro Yamada  * @dev: pin controller device
238d90a5a30SMasahiro Yamada  * @config: pseudo device pointing to config node
239d90a5a30SMasahiro Yamada  * @is_group: target of operation (true: pin group, false: pin)
240d90a5a30SMasahiro Yamada  * @selector: pin selector or group selector, depending on @is_group
241d90a5a30SMasahiro Yamada  * @return: 0 on success, or negative error code on failure
242d90a5a30SMasahiro Yamada  */
243d90a5a30SMasahiro Yamada static int pinctrl_generic_set_state_one(struct udevice *dev,
244d90a5a30SMasahiro Yamada 					 struct udevice *config,
245d90a5a30SMasahiro Yamada 					 bool is_group, unsigned selector)
246d90a5a30SMasahiro Yamada {
247d90a5a30SMasahiro Yamada 	const void *fdt = gd->fdt_blob;
248d90a5a30SMasahiro Yamada 	int node_offset = config->of_offset;
249d90a5a30SMasahiro Yamada 	const char *propname;
250d90a5a30SMasahiro Yamada 	const void *value;
251d90a5a30SMasahiro Yamada 	int prop_offset, len, func_selector, param, ret;
252d90a5a30SMasahiro Yamada 	u32 arg, default_val;
253d90a5a30SMasahiro Yamada 
254d90a5a30SMasahiro Yamada 	for (prop_offset = fdt_first_property_offset(fdt, node_offset);
255d90a5a30SMasahiro Yamada 	     prop_offset > 0;
256d90a5a30SMasahiro Yamada 	     prop_offset = fdt_next_property_offset(fdt, prop_offset)) {
257d90a5a30SMasahiro Yamada 		value = fdt_getprop_by_offset(fdt, prop_offset,
258d90a5a30SMasahiro Yamada 					      &propname, &len);
259d90a5a30SMasahiro Yamada 		if (!value)
260d90a5a30SMasahiro Yamada 			return -EINVAL;
261d90a5a30SMasahiro Yamada 
262d90a5a30SMasahiro Yamada 		if (!strcmp(propname, "function")) {
263d90a5a30SMasahiro Yamada 			func_selector = pinmux_func_name_to_selector(dev,
264d90a5a30SMasahiro Yamada 								     value);
265d90a5a30SMasahiro Yamada 			if (func_selector < 0)
266d90a5a30SMasahiro Yamada 				return func_selector;
267d90a5a30SMasahiro Yamada 			ret = pinmux_enable_setting(dev, is_group,
268d90a5a30SMasahiro Yamada 						    selector,
269d90a5a30SMasahiro Yamada 						    func_selector);
270d90a5a30SMasahiro Yamada 		} else {
271d90a5a30SMasahiro Yamada 			param = pinconf_prop_name_to_param(dev, propname,
272d90a5a30SMasahiro Yamada 							   &default_val);
273d90a5a30SMasahiro Yamada 			if (param < 0)
274d90a5a30SMasahiro Yamada 				continue; /* just skip unknown properties */
275d90a5a30SMasahiro Yamada 
276d90a5a30SMasahiro Yamada 			if (len >= sizeof(fdt32_t))
277d90a5a30SMasahiro Yamada 				arg = fdt32_to_cpu(*(fdt32_t *)value);
278d90a5a30SMasahiro Yamada 			else
279d90a5a30SMasahiro Yamada 				arg = default_val;
280d90a5a30SMasahiro Yamada 
281d90a5a30SMasahiro Yamada 			ret = pinconf_enable_setting(dev, is_group,
282d90a5a30SMasahiro Yamada 						     selector, param, arg);
283d90a5a30SMasahiro Yamada 		}
284d90a5a30SMasahiro Yamada 
285d90a5a30SMasahiro Yamada 		if (ret)
286d90a5a30SMasahiro Yamada 			return ret;
287d90a5a30SMasahiro Yamada 	}
288d90a5a30SMasahiro Yamada 
289d90a5a30SMasahiro Yamada 	return 0;
290d90a5a30SMasahiro Yamada }
291d90a5a30SMasahiro Yamada 
292d90a5a30SMasahiro Yamada /**
293d90a5a30SMasahiro Yamada  * pinctrl_generic_set_state_subnode() - apply all settings in config node
294d90a5a30SMasahiro Yamada  *
295d90a5a30SMasahiro Yamada  * @dev: pin controller device
296d90a5a30SMasahiro Yamada  * @config: pseudo device pointing to config node
297d90a5a30SMasahiro Yamada  * @return: 0 on success, or negative error code on failure
298d90a5a30SMasahiro Yamada  */
299d90a5a30SMasahiro Yamada static int pinctrl_generic_set_state_subnode(struct udevice *dev,
300d90a5a30SMasahiro Yamada 					     struct udevice *config)
301d90a5a30SMasahiro Yamada {
302d90a5a30SMasahiro Yamada 	const void *fdt = gd->fdt_blob;
303d90a5a30SMasahiro Yamada 	int node = config->of_offset;
304d90a5a30SMasahiro Yamada 	const char *subnode_target_type = "pins";
305d90a5a30SMasahiro Yamada 	bool is_group = false;
306d90a5a30SMasahiro Yamada 	const char *name;
307d90a5a30SMasahiro Yamada 	int strings_count, selector, i, ret;
308d90a5a30SMasahiro Yamada 
309d90a5a30SMasahiro Yamada 	strings_count = fdt_count_strings(fdt, node, subnode_target_type);
310d90a5a30SMasahiro Yamada 	if (strings_count < 0) {
311d90a5a30SMasahiro Yamada 		subnode_target_type = "groups";
312d90a5a30SMasahiro Yamada 		is_group = true;
313d90a5a30SMasahiro Yamada 		strings_count = fdt_count_strings(fdt, node,
314d90a5a30SMasahiro Yamada 						  subnode_target_type);
315*2c936374SBeniamino Galvani 		if (strings_count < 0) {
316*2c936374SBeniamino Galvani 			/* skip this node; may contain config child nodes */
317*2c936374SBeniamino Galvani 			return 0;
318*2c936374SBeniamino Galvani 		}
319d90a5a30SMasahiro Yamada 	}
320d90a5a30SMasahiro Yamada 
321d90a5a30SMasahiro Yamada 	for (i = 0; i < strings_count; i++) {
322d90a5a30SMasahiro Yamada 		ret = fdt_get_string_index(fdt, node, subnode_target_type,
323d90a5a30SMasahiro Yamada 					   i, &name);
324d90a5a30SMasahiro Yamada 		if (ret < 0)
325d90a5a30SMasahiro Yamada 			return -EINVAL;
326d90a5a30SMasahiro Yamada 
327d90a5a30SMasahiro Yamada 		if (is_group)
328d90a5a30SMasahiro Yamada 			selector = pinctrl_group_name_to_selector(dev, name);
329d90a5a30SMasahiro Yamada 		else
330d90a5a30SMasahiro Yamada 			selector = pinctrl_pin_name_to_selector(dev, name);
331d90a5a30SMasahiro Yamada 		if (selector < 0)
332d90a5a30SMasahiro Yamada 			return selector;
333d90a5a30SMasahiro Yamada 
334d90a5a30SMasahiro Yamada 		ret = pinctrl_generic_set_state_one(dev, config,
335d90a5a30SMasahiro Yamada 						    is_group, selector);
336d90a5a30SMasahiro Yamada 		if (ret)
337d90a5a30SMasahiro Yamada 			return ret;
338d90a5a30SMasahiro Yamada 	}
339d90a5a30SMasahiro Yamada 
340d90a5a30SMasahiro Yamada 	return 0;
341d90a5a30SMasahiro Yamada }
342d90a5a30SMasahiro Yamada 
343d90a5a30SMasahiro Yamada int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
344d90a5a30SMasahiro Yamada {
345d90a5a30SMasahiro Yamada 	struct udevice *child;
346d90a5a30SMasahiro Yamada 	int ret;
347d90a5a30SMasahiro Yamada 
348d90a5a30SMasahiro Yamada 	ret = pinctrl_generic_set_state_subnode(dev, config);
349d90a5a30SMasahiro Yamada 	if (ret)
350d90a5a30SMasahiro Yamada 		return ret;
351d90a5a30SMasahiro Yamada 
352d90a5a30SMasahiro Yamada 	for (device_find_first_child(config, &child);
353d90a5a30SMasahiro Yamada 	     child;
354d90a5a30SMasahiro Yamada 	     device_find_next_child(&child)) {
355d90a5a30SMasahiro Yamada 		ret = pinctrl_generic_set_state_subnode(dev, child);
356d90a5a30SMasahiro Yamada 		if (ret)
357d90a5a30SMasahiro Yamada 			return ret;
358d90a5a30SMasahiro Yamada 	}
359d90a5a30SMasahiro Yamada 
360d90a5a30SMasahiro Yamada 	return 0;
361d90a5a30SMasahiro Yamada }
362