1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2016 IBM Corp.
4  */
5 
6 #include <linux/mfd/syscon.h>
7 #include <linux/platform_device.h>
8 #include <linux/slab.h>
9 #include <linux/string.h>
10 #include "../core.h"
11 #include "pinctrl-aspeed.h"
12 
aspeed_pinctrl_get_groups_count(struct pinctrl_dev * pctldev)13 int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
14 {
15 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
16 
17 	return pdata->pinmux.ngroups;
18 }
19 
aspeed_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)20 const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
21 		unsigned int group)
22 {
23 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
24 
25 	return pdata->pinmux.groups[group].name;
26 }
27 
aspeed_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * npins)28 int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
29 				  unsigned int group, const unsigned int **pins,
30 				  unsigned int *npins)
31 {
32 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
33 
34 	*pins = &pdata->pinmux.groups[group].pins[0];
35 	*npins = pdata->pinmux.groups[group].npins;
36 
37 	return 0;
38 }
39 
aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int offset)40 void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
41 				 struct seq_file *s, unsigned int offset)
42 {
43 	seq_printf(s, " %s", dev_name(pctldev->dev));
44 }
45 
aspeed_pinmux_get_fn_count(struct pinctrl_dev * pctldev)46 int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev)
47 {
48 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
49 
50 	return pdata->pinmux.nfunctions;
51 }
52 
aspeed_pinmux_get_fn_name(struct pinctrl_dev * pctldev,unsigned int function)53 const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev,
54 				      unsigned int function)
55 {
56 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
57 
58 	return pdata->pinmux.functions[function].name;
59 }
60 
aspeed_pinmux_get_fn_groups(struct pinctrl_dev * pctldev,unsigned int function,const char * const ** groups,unsigned int * const num_groups)61 int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev,
62 				unsigned int function,
63 				const char * const **groups,
64 				unsigned int * const num_groups)
65 {
66 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
67 
68 	*groups = pdata->pinmux.functions[function].groups;
69 	*num_groups = pdata->pinmux.functions[function].ngroups;
70 
71 	return 0;
72 }
73 
aspeed_sig_expr_enable(struct aspeed_pinmux_data * ctx,const struct aspeed_sig_expr * expr)74 static int aspeed_sig_expr_enable(struct aspeed_pinmux_data *ctx,
75 				  const struct aspeed_sig_expr *expr)
76 {
77 	int ret;
78 
79 	pr_debug("Enabling signal %s for %s\n", expr->signal,
80 		 expr->function);
81 
82 	ret = aspeed_sig_expr_eval(ctx, expr, true);
83 	if (ret < 0)
84 		return ret;
85 
86 	if (!ret)
87 		return aspeed_sig_expr_set(ctx, expr, true);
88 
89 	return 0;
90 }
91 
aspeed_sig_expr_disable(struct aspeed_pinmux_data * ctx,const struct aspeed_sig_expr * expr)92 static int aspeed_sig_expr_disable(struct aspeed_pinmux_data *ctx,
93 				   const struct aspeed_sig_expr *expr)
94 {
95 	pr_debug("Disabling signal %s for %s\n", expr->signal,
96 		 expr->function);
97 
98 	return aspeed_sig_expr_set(ctx, expr, false);
99 }
100 
101 /**
102  * aspeed_disable_sig() - Disable a signal on a pin by disabling all provided
103  * signal expressions.
104  *
105  * @ctx: The pinmux context
106  * @exprs: The list of signal expressions (from a priority level on a pin)
107  *
108  * Return: 0 if all expressions are disabled, otherwise a negative error code
109  */
aspeed_disable_sig(struct aspeed_pinmux_data * ctx,const struct aspeed_sig_expr ** exprs)110 static int aspeed_disable_sig(struct aspeed_pinmux_data *ctx,
111 			      const struct aspeed_sig_expr **exprs)
112 {
113 	int ret = 0;
114 
115 	if (!exprs)
116 		return true;
117 
118 	while (*exprs && !ret) {
119 		ret = aspeed_sig_expr_disable(ctx, *exprs);
120 		exprs++;
121 	}
122 
123 	return ret;
124 }
125 
126 /**
127  * aspeed_find_expr_by_name - Search for the signal expression needed to
128  * enable the pin's signal for the requested function.
129  *
130  * @exprs: List of signal expressions (haystack)
131  * @name: The name of the requested function (needle)
132  *
133  * Return: A pointer to the signal expression whose function tag matches the
134  * provided name, otherwise NULL.
135  *
136  */
aspeed_find_expr_by_name(const struct aspeed_sig_expr ** exprs,const char * name)137 static const struct aspeed_sig_expr *aspeed_find_expr_by_name(
138 		const struct aspeed_sig_expr **exprs, const char *name)
139 {
140 	while (*exprs) {
141 		if (strcmp((*exprs)->function, name) == 0)
142 			return *exprs;
143 		exprs++;
144 	}
145 
146 	return NULL;
147 }
148 
get_defined_attribute(const struct aspeed_pin_desc * pdesc,const char * (* get)(const struct aspeed_sig_expr *))149 static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc,
150 				   const char *(*get)(
151 					   const struct aspeed_sig_expr *))
152 {
153 	char *found = NULL;
154 	size_t len = 0;
155 	const struct aspeed_sig_expr ***prios, **funcs, *expr;
156 
157 	prios = pdesc->prios;
158 
159 	while ((funcs = *prios)) {
160 		while ((expr = *funcs)) {
161 			const char *str = get(expr);
162 			size_t delta = strlen(str) + 2;
163 			char *expanded;
164 
165 			expanded = krealloc(found, len + delta + 1, GFP_KERNEL);
166 			if (!expanded) {
167 				kfree(found);
168 				return expanded;
169 			}
170 
171 			found = expanded;
172 			found[len] = '\0';
173 			len += delta;
174 
175 			strcat(found, str);
176 			strcat(found, ", ");
177 
178 			funcs++;
179 		}
180 		prios++;
181 	}
182 
183 	if (len < 2) {
184 		kfree(found);
185 		return NULL;
186 	}
187 
188 	found[len - 2] = '\0';
189 
190 	return found;
191 }
192 
aspeed_sig_expr_function(const struct aspeed_sig_expr * expr)193 static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr)
194 {
195 	return expr->function;
196 }
197 
get_defined_functions(const struct aspeed_pin_desc * pdesc)198 static char *get_defined_functions(const struct aspeed_pin_desc *pdesc)
199 {
200 	return get_defined_attribute(pdesc, aspeed_sig_expr_function);
201 }
202 
aspeed_sig_expr_signal(const struct aspeed_sig_expr * expr)203 static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr)
204 {
205 	return expr->signal;
206 }
207 
get_defined_signals(const struct aspeed_pin_desc * pdesc)208 static char *get_defined_signals(const struct aspeed_pin_desc *pdesc)
209 {
210 	return get_defined_attribute(pdesc, aspeed_sig_expr_signal);
211 }
212 
aspeed_pinmux_set_mux(struct pinctrl_dev * pctldev,unsigned int function,unsigned int group)213 int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
214 			  unsigned int group)
215 {
216 	int i;
217 	int ret;
218 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
219 	const struct aspeed_pin_group *pgroup = &pdata->pinmux.groups[group];
220 	const struct aspeed_pin_function *pfunc =
221 		&pdata->pinmux.functions[function];
222 
223 	for (i = 0; i < pgroup->npins; i++) {
224 		int pin = pgroup->pins[i];
225 		const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data;
226 		const struct aspeed_sig_expr *expr = NULL;
227 		const struct aspeed_sig_expr **funcs;
228 		const struct aspeed_sig_expr ***prios;
229 
230 		if (!pdesc)
231 			return -EINVAL;
232 
233 		pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name);
234 
235 		prios = pdesc->prios;
236 
237 		if (!prios)
238 			continue;
239 
240 		/* Disable functions at a higher priority than that requested */
241 		while ((funcs = *prios)) {
242 			expr = aspeed_find_expr_by_name(funcs, pfunc->name);
243 
244 			if (expr)
245 				break;
246 
247 			ret = aspeed_disable_sig(&pdata->pinmux, funcs);
248 			if (ret)
249 				return ret;
250 
251 			prios++;
252 		}
253 
254 		if (!expr) {
255 			char *functions = get_defined_functions(pdesc);
256 			char *signals = get_defined_signals(pdesc);
257 
258 			pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n",
259 				pfunc->name, pdesc->name, pin, signals,
260 				functions);
261 			kfree(signals);
262 			kfree(functions);
263 
264 			return -ENXIO;
265 		}
266 
267 		ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
268 		if (ret)
269 			return ret;
270 
271 		pr_debug("Muxed pin %s as %s for %s\n", pdesc->name, expr->signal,
272 			 expr->function);
273 	}
274 
275 	return 0;
276 }
277 
aspeed_expr_is_gpio(const struct aspeed_sig_expr * expr)278 static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
279 {
280 	/*
281 	 * We need to differentiate between GPIO and non-GPIO signals to
282 	 * implement the gpio_request_enable() interface. For better or worse
283 	 * the ASPEED pinctrl driver uses the expression names to determine
284 	 * whether an expression will mux a pin for GPIO.
285 	 *
286 	 * Generally we have the following - A GPIO such as B1 has:
287 	 *
288 	 *    - expr->signal set to "GPIOB1"
289 	 *    - expr->function set to "GPIOB1"
290 	 *
291 	 * Using this fact we can determine whether the provided expression is
292 	 * a GPIO expression by testing the signal name for the string prefix
293 	 * "GPIO".
294 	 *
295 	 * However, some GPIOs are input-only, and the ASPEED datasheets name
296 	 * them differently. An input-only GPIO such as T0 has:
297 	 *
298 	 *    - expr->signal set to "GPIT0"
299 	 *    - expr->function set to "GPIT0"
300 	 *
301 	 * It's tempting to generalise the prefix test from "GPIO" to "GPI" to
302 	 * account for both GPIOs and GPIs, but in doing so we run aground on
303 	 * another feature:
304 	 *
305 	 * Some pins in the ASPEED BMC SoCs have a "pass-through" GPIO
306 	 * function where the input state of one pin is replicated as the
307 	 * output state of another (as if they were shorted together - a mux
308 	 * configuration that is typically enabled by hardware strapping).
309 	 * This feature allows the BMC to pass e.g. power button state through
310 	 * to the host while the BMC is yet to boot, but take control of the
311 	 * button state once the BMC has booted by muxing each pin as a
312 	 * separate, pin-specific GPIO.
313 	 *
314 	 * Conceptually this pass-through mode is a form of GPIO and is named
315 	 * as such in the datasheets, e.g. "GPID0". This naming similarity
316 	 * trips us up with the simple GPI-prefixed-signal-name scheme
317 	 * discussed above, as the pass-through configuration is not what we
318 	 * want when muxing a pin as GPIO for the GPIO subsystem.
319 	 *
320 	 * On e.g. the AST2400, a pass-through function "GPID0" is grouped on
321 	 * balls A18 and D16, where we have:
322 	 *
323 	 *    For ball A18:
324 	 *    - expr->signal set to "GPID0IN"
325 	 *    - expr->function set to "GPID0"
326 	 *
327 	 *    For ball D16:
328 	 *    - expr->signal set to "GPID0OUT"
329 	 *    - expr->function set to "GPID0"
330 	 *
331 	 * By contrast, the pin-specific GPIO expressions for the same pins are
332 	 * as follows:
333 	 *
334 	 *    For ball A18:
335 	 *    - expr->signal looks like "GPIOD0"
336 	 *    - expr->function looks like "GPIOD0"
337 	 *
338 	 *    For ball D16:
339 	 *    - expr->signal looks like "GPIOD1"
340 	 *    - expr->function looks like "GPIOD1"
341 	 *
342 	 * Testing both the signal _and_ function names gives us the means
343 	 * differentiate the pass-through GPIO pinmux configuration from the
344 	 * pin-specific configuration that the GPIO subsystem is after: An
345 	 * expression is a pin-specific (non-pass-through) GPIO configuration
346 	 * if the signal prefix is "GPI" and the signal name matches the
347 	 * function name.
348 	 */
349 	return !strncmp(expr->signal, "GPI", 3) &&
350 			!strcmp(expr->signal, expr->function);
351 }
352 
aspeed_gpio_in_exprs(const struct aspeed_sig_expr ** exprs)353 static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)
354 {
355 	if (!exprs)
356 		return false;
357 
358 	while (*exprs) {
359 		if (aspeed_expr_is_gpio(*exprs))
360 			return true;
361 		exprs++;
362 	}
363 
364 	return false;
365 }
366 
aspeed_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int offset)367 int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev,
368 			       struct pinctrl_gpio_range *range,
369 			       unsigned int offset)
370 {
371 	int ret;
372 	struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
373 	const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data;
374 	const struct aspeed_sig_expr ***prios, **funcs, *expr;
375 
376 	if (!pdesc)
377 		return -EINVAL;
378 
379 	prios = pdesc->prios;
380 
381 	if (!prios)
382 		return -ENXIO;
383 
384 	pr_debug("Muxing pin %s for GPIO\n", pdesc->name);
385 
386 	/* Disable any functions of higher priority than GPIO */
387 	while ((funcs = *prios)) {
388 		if (aspeed_gpio_in_exprs(funcs))
389 			break;
390 
391 		ret = aspeed_disable_sig(&pdata->pinmux, funcs);
392 		if (ret)
393 			return ret;
394 
395 		prios++;
396 	}
397 
398 	if (!funcs) {
399 		char *signals = get_defined_signals(pdesc);
400 
401 		pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n",
402 			pdesc->name, offset, signals);
403 		kfree(signals);
404 
405 		return -ENXIO;
406 	}
407 
408 	expr = *funcs;
409 
410 	/*
411 	 * Disabling all higher-priority expressions is enough to enable the
412 	 * lowest-priority signal type. As such it has no associated
413 	 * expression.
414 	 */
415 	if (!expr) {
416 		pr_debug("Muxed pin %s as GPIO\n", pdesc->name);
417 		return 0;
418 	}
419 
420 	/*
421 	 * If GPIO is not the lowest priority signal type, assume there is only
422 	 * one expression defined to enable the GPIO function
423 	 */
424 	ret = aspeed_sig_expr_enable(&pdata->pinmux, expr);
425 	if (ret)
426 		return ret;
427 
428 	pr_debug("Muxed pin %s as %s\n", pdesc->name, expr->signal);
429 
430 	return 0;
431 }
432 
aspeed_pinctrl_probe(struct platform_device * pdev,struct pinctrl_desc * pdesc,struct aspeed_pinctrl_data * pdata)433 int aspeed_pinctrl_probe(struct platform_device *pdev,
434 			 struct pinctrl_desc *pdesc,
435 			 struct aspeed_pinctrl_data *pdata)
436 {
437 	struct device *parent;
438 	struct pinctrl_dev *pctl;
439 
440 	parent = pdev->dev.parent;
441 	if (!parent) {
442 		dev_err(&pdev->dev, "No parent for syscon pincontroller\n");
443 		return -ENODEV;
444 	}
445 
446 	pdata->scu = syscon_node_to_regmap(parent->of_node);
447 	if (IS_ERR(pdata->scu)) {
448 		dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n");
449 		return PTR_ERR(pdata->scu);
450 	}
451 
452 	pdata->pinmux.maps[ASPEED_IP_SCU] = pdata->scu;
453 
454 	pctl = pinctrl_register(pdesc, &pdev->dev, pdata);
455 
456 	if (IS_ERR(pctl)) {
457 		dev_err(&pdev->dev, "Failed to register pinctrl\n");
458 		return PTR_ERR(pctl);
459 	}
460 
461 	platform_set_drvdata(pdev, pdata);
462 
463 	return 0;
464 }
465 
pin_in_config_range(unsigned int offset,const struct aspeed_pin_config * config)466 static inline bool pin_in_config_range(unsigned int offset,
467 		const struct aspeed_pin_config *config)
468 {
469 	return offset >= config->pins[0] && offset <= config->pins[1];
470 }
471 
find_pinconf_config(const struct aspeed_pinctrl_data * pdata,unsigned int offset,enum pin_config_param param)472 static inline const struct aspeed_pin_config *find_pinconf_config(
473 		const struct aspeed_pinctrl_data *pdata,
474 		unsigned int offset,
475 		enum pin_config_param param)
476 {
477 	unsigned int i;
478 
479 	for (i = 0; i < pdata->nconfigs; i++) {
480 		if (param == pdata->configs[i].param &&
481 				pin_in_config_range(offset, &pdata->configs[i]))
482 			return &pdata->configs[i];
483 	}
484 
485 	return NULL;
486 }
487 
488 enum aspeed_pin_config_map_type { MAP_TYPE_ARG, MAP_TYPE_VAL };
489 
find_pinconf_map(const struct aspeed_pinctrl_data * pdata,enum pin_config_param param,enum aspeed_pin_config_map_type type,s64 value)490 static const struct aspeed_pin_config_map *find_pinconf_map(
491 		const struct aspeed_pinctrl_data *pdata,
492 		enum pin_config_param param,
493 		enum aspeed_pin_config_map_type type,
494 		s64 value)
495 {
496 	int i;
497 
498 	for (i = 0; i < pdata->nconfmaps; i++) {
499 		const struct aspeed_pin_config_map *elem;
500 		bool match;
501 
502 		elem = &pdata->confmaps[i];
503 
504 		switch (type) {
505 		case MAP_TYPE_ARG:
506 			match = (elem->arg == -1 || elem->arg == value);
507 			break;
508 		case MAP_TYPE_VAL:
509 			match = (elem->val == value);
510 			break;
511 		}
512 
513 		if (param == elem->param && match)
514 			return elem;
515 	}
516 
517 	return NULL;
518 }
519 
aspeed_pin_config_get(struct pinctrl_dev * pctldev,unsigned int offset,unsigned long * config)520 int aspeed_pin_config_get(struct pinctrl_dev *pctldev, unsigned int offset,
521 		unsigned long *config)
522 {
523 	const enum pin_config_param param = pinconf_to_config_param(*config);
524 	const struct aspeed_pin_config_map *pmap;
525 	const struct aspeed_pinctrl_data *pdata;
526 	const struct aspeed_pin_config *pconf;
527 	unsigned int val;
528 	int rc = 0;
529 	u32 arg;
530 
531 	pdata = pinctrl_dev_get_drvdata(pctldev);
532 	pconf = find_pinconf_config(pdata, offset, param);
533 	if (!pconf)
534 		return -ENOTSUPP;
535 
536 	rc = regmap_read(pdata->scu, pconf->reg, &val);
537 	if (rc < 0)
538 		return rc;
539 
540 	pmap = find_pinconf_map(pdata, param, MAP_TYPE_VAL,
541 			(val & pconf->mask) >> __ffs(pconf->mask));
542 
543 	if (!pmap)
544 		return -EINVAL;
545 
546 	if (param == PIN_CONFIG_DRIVE_STRENGTH)
547 		arg = (u32) pmap->arg;
548 	else if (param == PIN_CONFIG_BIAS_PULL_DOWN)
549 		arg = !!pmap->arg;
550 	else
551 		arg = 1;
552 
553 	if (!arg)
554 		return -EINVAL;
555 
556 	*config = pinconf_to_config_packed(param, arg);
557 
558 	return 0;
559 }
560 
aspeed_pin_config_set(struct pinctrl_dev * pctldev,unsigned int offset,unsigned long * configs,unsigned int num_configs)561 int aspeed_pin_config_set(struct pinctrl_dev *pctldev, unsigned int offset,
562 		unsigned long *configs, unsigned int num_configs)
563 {
564 	const struct aspeed_pinctrl_data *pdata;
565 	unsigned int i;
566 	int rc = 0;
567 
568 	pdata = pinctrl_dev_get_drvdata(pctldev);
569 
570 	for (i = 0; i < num_configs; i++) {
571 		const struct aspeed_pin_config_map *pmap;
572 		const struct aspeed_pin_config *pconf;
573 		enum pin_config_param param;
574 		unsigned int val;
575 		u32 arg;
576 
577 		param = pinconf_to_config_param(configs[i]);
578 		arg = pinconf_to_config_argument(configs[i]);
579 
580 		pconf = find_pinconf_config(pdata, offset, param);
581 		if (!pconf)
582 			return -ENOTSUPP;
583 
584 		pmap = find_pinconf_map(pdata, param, MAP_TYPE_ARG, arg);
585 
586 		if (WARN_ON(!pmap))
587 			return -EINVAL;
588 
589 		val = pmap->val << __ffs(pconf->mask);
590 
591 		rc = regmap_update_bits(pdata->scu, pconf->reg,
592 					pconf->mask, val);
593 
594 		if (rc < 0)
595 			return rc;
596 
597 		pr_debug("%s: Set SCU%02X[0x%08X]=0x%X for param %d(=%d) on pin %d\n",
598 				__func__, pconf->reg, pconf->mask,
599 				val, param, arg, offset);
600 	}
601 
602 	return 0;
603 }
604 
aspeed_pin_config_group_get(struct pinctrl_dev * pctldev,unsigned int selector,unsigned long * config)605 int aspeed_pin_config_group_get(struct pinctrl_dev *pctldev,
606 		unsigned int selector,
607 		unsigned long *config)
608 {
609 	const unsigned int *pins;
610 	unsigned int npins;
611 	int rc;
612 
613 	rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
614 	if (rc < 0)
615 		return rc;
616 
617 	if (!npins)
618 		return -ENODEV;
619 
620 	rc = aspeed_pin_config_get(pctldev, pins[0], config);
621 
622 	return rc;
623 }
624 
aspeed_pin_config_group_set(struct pinctrl_dev * pctldev,unsigned int selector,unsigned long * configs,unsigned int num_configs)625 int aspeed_pin_config_group_set(struct pinctrl_dev *pctldev,
626 		unsigned int selector,
627 		unsigned long *configs,
628 		unsigned int num_configs)
629 {
630 	const unsigned int *pins;
631 	unsigned int npins;
632 	int rc;
633 	int i;
634 
635 	pr_debug("%s: Fetching pins for group selector %d\n",
636 			__func__, selector);
637 	rc = aspeed_pinctrl_get_group_pins(pctldev, selector, &pins, &npins);
638 	if (rc < 0)
639 		return rc;
640 
641 	for (i = 0; i < npins; i++) {
642 		rc = aspeed_pin_config_set(pctldev, pins[i], configs,
643 				num_configs);
644 		if (rc < 0)
645 			return rc;
646 	}
647 
648 	return 0;
649 }
650