xref: /linux/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 
15 #include <linux/export.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/pinctrl/pinconf.h>
18 #include <linux/pinctrl/pinconf-generic.h>
19 #include <linux/pinctrl/pinctrl.h>
20 #include <linux/pinctrl/pinmux.h>
21 #include <linux/platform_device.h>
22 #include <linux/regmap.h>
23 
24 #include "../core.h"
25 #include "../pinctrl-utils.h"
26 #include "pinctrl-uniphier.h"
27 
28 struct uniphier_pinctrl_priv {
29 	struct pinctrl_dev *pctldev;
30 	struct regmap *regmap;
31 	struct uniphier_pinctrl_socdata *socdata;
32 };
33 
34 static int uniphier_pctl_get_groups_count(struct pinctrl_dev *pctldev)
35 {
36 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
37 
38 	return priv->socdata->groups_count;
39 }
40 
41 static const char *uniphier_pctl_get_group_name(struct pinctrl_dev *pctldev,
42 						unsigned selector)
43 {
44 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
45 
46 	return priv->socdata->groups[selector].name;
47 }
48 
49 static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev,
50 					unsigned selector,
51 					const unsigned **pins,
52 					unsigned *num_pins)
53 {
54 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
55 
56 	*pins = priv->socdata->groups[selector].pins;
57 	*num_pins = priv->socdata->groups[selector].num_pins;
58 
59 	return 0;
60 }
61 
62 #ifdef CONFIG_DEBUG_FS
63 static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev,
64 				       struct seq_file *s, unsigned offset)
65 {
66 	const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset];
67 	const char *pull_dir, *drv_str;
68 
69 	switch (uniphier_pin_get_pull_dir(pin->drv_data)) {
70 	case UNIPHIER_PIN_PULL_UP:
71 		pull_dir = "UP";
72 		break;
73 	case UNIPHIER_PIN_PULL_DOWN:
74 		pull_dir = "DOWN";
75 		break;
76 	case UNIPHIER_PIN_PULL_NONE:
77 		pull_dir = "NONE";
78 		break;
79 	default:
80 		BUG();
81 	}
82 
83 	switch (uniphier_pin_get_drv_str(pin->drv_data)) {
84 	case UNIPHIER_PIN_DRV_4_8:
85 		drv_str = "4/8(mA)";
86 		break;
87 	case UNIPHIER_PIN_DRV_8_12_16_20:
88 		drv_str = "8/12/16/20(mA)";
89 		break;
90 	case UNIPHIER_PIN_DRV_FIXED_4:
91 		drv_str = "4(mA)";
92 		break;
93 	case UNIPHIER_PIN_DRV_FIXED_5:
94 		drv_str = "5(mA)";
95 		break;
96 	case UNIPHIER_PIN_DRV_FIXED_8:
97 		drv_str = "8(mA)";
98 		break;
99 	case UNIPHIER_PIN_DRV_NONE:
100 		drv_str = "NONE";
101 		break;
102 	default:
103 		BUG();
104 	}
105 
106 	seq_printf(s, " PULL_DIR=%s  DRV_STR=%s", pull_dir, drv_str);
107 }
108 #endif
109 
110 static const struct pinctrl_ops uniphier_pctlops = {
111 	.get_groups_count = uniphier_pctl_get_groups_count,
112 	.get_group_name = uniphier_pctl_get_group_name,
113 	.get_group_pins = uniphier_pctl_get_group_pins,
114 #ifdef CONFIG_DEBUG_FS
115 	.pin_dbg_show = uniphier_pctl_pin_dbg_show,
116 #endif
117 	.dt_node_to_map = pinconf_generic_dt_node_to_map_all,
118 	.dt_free_map = pinctrl_utils_dt_free_map,
119 };
120 
121 static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev,
122 				      const struct pinctrl_pin_desc *pin,
123 				      enum pin_config_param param)
124 {
125 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
126 	enum uniphier_pin_pull_dir pull_dir =
127 				uniphier_pin_get_pull_dir(pin->drv_data);
128 	unsigned int pupdctrl, reg, shift, val;
129 	unsigned int expected = 1;
130 	int ret;
131 
132 	switch (param) {
133 	case PIN_CONFIG_BIAS_DISABLE:
134 		if (pull_dir == UNIPHIER_PIN_PULL_NONE)
135 			return 0;
136 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
137 		    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
138 			return -EINVAL;
139 		expected = 0;
140 		break;
141 	case PIN_CONFIG_BIAS_PULL_UP:
142 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED)
143 			return 0;
144 		if (pull_dir != UNIPHIER_PIN_PULL_UP)
145 			return -EINVAL;
146 		break;
147 	case PIN_CONFIG_BIAS_PULL_DOWN:
148 		if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED)
149 			return 0;
150 		if (pull_dir != UNIPHIER_PIN_PULL_DOWN)
151 			return -EINVAL;
152 		break;
153 	default:
154 		BUG();
155 	}
156 
157 	pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
158 
159 	reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
160 	shift = pupdctrl % 32;
161 
162 	ret = regmap_read(priv->regmap, reg, &val);
163 	if (ret)
164 		return ret;
165 
166 	val = (val >> shift) & 1;
167 
168 	return (val == expected) ? 0 : -EINVAL;
169 }
170 
171 static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev,
172 				       const struct pinctrl_pin_desc *pin,
173 				       u16 *strength)
174 {
175 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
176 	enum uniphier_pin_drv_str drv_str =
177 				uniphier_pin_get_drv_str(pin->drv_data);
178 	const unsigned int strength_4_8[] = {4, 8};
179 	const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20};
180 	const unsigned int *supported_strength;
181 	unsigned int drvctrl, reg, shift, mask, width, val;
182 	int ret;
183 
184 	switch (drv_str) {
185 	case UNIPHIER_PIN_DRV_4_8:
186 		supported_strength = strength_4_8;
187 		width = 1;
188 		break;
189 	case UNIPHIER_PIN_DRV_8_12_16_20:
190 		supported_strength = strength_8_12_16_20;
191 		width = 2;
192 		break;
193 	case UNIPHIER_PIN_DRV_FIXED_4:
194 		*strength = 4;
195 		return 0;
196 	case UNIPHIER_PIN_DRV_FIXED_5:
197 		*strength = 5;
198 		return 0;
199 	case UNIPHIER_PIN_DRV_FIXED_8:
200 		*strength = 8;
201 		return 0;
202 	default:
203 		/* drive strength control is not supported for this pin */
204 		return -EINVAL;
205 	}
206 
207 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
208 	drvctrl *= width;
209 
210 	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
211 			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
212 
213 	reg += drvctrl / 32 * 4;
214 	shift = drvctrl % 32;
215 	mask = (1U << width) - 1;
216 
217 	ret = regmap_read(priv->regmap, reg, &val);
218 	if (ret)
219 		return ret;
220 
221 	*strength = supported_strength[(val >> shift) & mask];
222 
223 	return 0;
224 }
225 
226 static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev,
227 					const struct pinctrl_pin_desc *pin)
228 {
229 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
230 	unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
231 	unsigned int val;
232 	int ret;
233 
234 	if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
235 		/* This pin is always input-enabled. */
236 		return 0;
237 
238 	ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val);
239 	if (ret)
240 		return ret;
241 
242 	return val & BIT(iectrl) ? 0 : -EINVAL;
243 }
244 
245 static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev,
246 					unsigned pin,
247 					unsigned long *configs)
248 {
249 	const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
250 	enum pin_config_param param = pinconf_to_config_param(*configs);
251 	bool has_arg = false;
252 	u16 arg;
253 	int ret;
254 
255 	switch (param) {
256 	case PIN_CONFIG_BIAS_DISABLE:
257 	case PIN_CONFIG_BIAS_PULL_UP:
258 	case PIN_CONFIG_BIAS_PULL_DOWN:
259 		ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param);
260 		break;
261 	case PIN_CONFIG_DRIVE_STRENGTH:
262 		ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg);
263 		has_arg = true;
264 		break;
265 	case PIN_CONFIG_INPUT_ENABLE:
266 		ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc);
267 		break;
268 	default:
269 		/* unsupported parameter */
270 		ret = -EINVAL;
271 		break;
272 	}
273 
274 	if (ret == 0 && has_arg)
275 		*configs = pinconf_to_config_packed(param, arg);
276 
277 	return ret;
278 }
279 
280 static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev,
281 				      const struct pinctrl_pin_desc *pin,
282 				      enum pin_config_param param,
283 				      u16 arg)
284 {
285 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
286 	enum uniphier_pin_pull_dir pull_dir =
287 				uniphier_pin_get_pull_dir(pin->drv_data);
288 	unsigned int pupdctrl, reg, shift;
289 	unsigned int val = 1;
290 
291 	switch (param) {
292 	case PIN_CONFIG_BIAS_DISABLE:
293 		if (pull_dir == UNIPHIER_PIN_PULL_NONE)
294 			return 0;
295 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED ||
296 		    pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) {
297 			dev_err(pctldev->dev,
298 				"can not disable pull register for pin %u (%s)\n",
299 				pin->number, pin->name);
300 			return -EINVAL;
301 		}
302 		val = 0;
303 		break;
304 	case PIN_CONFIG_BIAS_PULL_UP:
305 		if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED && arg != 0)
306 			return 0;
307 		if (pull_dir != UNIPHIER_PIN_PULL_UP) {
308 			dev_err(pctldev->dev,
309 				"pull-up is unsupported for pin %u (%s)\n",
310 				pin->number, pin->name);
311 			return -EINVAL;
312 		}
313 		if (arg == 0) {
314 			dev_err(pctldev->dev, "pull-up can not be total\n");
315 			return -EINVAL;
316 		}
317 		break;
318 	case PIN_CONFIG_BIAS_PULL_DOWN:
319 		if (pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED && arg != 0)
320 			return 0;
321 		if (pull_dir != UNIPHIER_PIN_PULL_DOWN) {
322 			dev_err(pctldev->dev,
323 				"pull-down is unsupported for pin %u (%s)\n",
324 				pin->number, pin->name);
325 			return -EINVAL;
326 		}
327 		if (arg == 0) {
328 			dev_err(pctldev->dev, "pull-down can not be total\n");
329 			return -EINVAL;
330 		}
331 		break;
332 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
333 		if (pull_dir == UNIPHIER_PIN_PULL_NONE) {
334 			dev_err(pctldev->dev,
335 				"pull-up/down is unsupported for pin %u (%s)\n",
336 				pin->number, pin->name);
337 			return -EINVAL;
338 		}
339 
340 		if (arg == 0)
341 			return 0; /* configuration ingored */
342 		break;
343 	default:
344 		BUG();
345 	}
346 
347 	pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data);
348 
349 	reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4;
350 	shift = pupdctrl % 32;
351 
352 	return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift);
353 }
354 
355 static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev,
356 				       const struct pinctrl_pin_desc *pin,
357 				       u16 strength)
358 {
359 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
360 	enum uniphier_pin_drv_str drv_str =
361 				uniphier_pin_get_drv_str(pin->drv_data);
362 	const unsigned int strength_4_8[] = {4, 8, -1};
363 	const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1};
364 	const unsigned int *supported_strength;
365 	unsigned int drvctrl, reg, shift, mask, width, val;
366 
367 	switch (drv_str) {
368 	case UNIPHIER_PIN_DRV_4_8:
369 		supported_strength = strength_4_8;
370 		width = 1;
371 		break;
372 	case UNIPHIER_PIN_DRV_8_12_16_20:
373 		supported_strength = strength_8_12_16_20;
374 		width = 2;
375 		break;
376 	default:
377 		dev_err(pctldev->dev,
378 			"cannot change drive strength for pin %u (%s)\n",
379 			pin->number, pin->name);
380 		return -EINVAL;
381 	}
382 
383 	for (val = 0; supported_strength[val] > 0; val++) {
384 		if (supported_strength[val] > strength)
385 			break;
386 	}
387 
388 	if (val == 0) {
389 		dev_err(pctldev->dev,
390 			"unsupported drive strength %u mA for pin %u (%s)\n",
391 			strength, pin->number, pin->name);
392 		return -EINVAL;
393 	}
394 
395 	val--;
396 
397 	drvctrl = uniphier_pin_get_drvctrl(pin->drv_data);
398 	drvctrl *= width;
399 
400 	reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE :
401 			     UNIPHIER_PINCTRL_DRVCTRL_BASE;
402 
403 	reg += drvctrl / 32 * 4;
404 	shift = drvctrl % 32;
405 	mask = (1U << width) - 1;
406 
407 	return regmap_update_bits(priv->regmap, reg,
408 				  mask << shift, val << shift);
409 }
410 
411 static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev,
412 					  const struct pinctrl_pin_desc *pin,
413 					  u16 enable)
414 {
415 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
416 	unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data);
417 
418 	if (enable == 0) {
419 		/*
420 		 * Multiple pins share one input enable, so per-pin disabling
421 		 * is impossible.
422 		 */
423 		dev_err(pctldev->dev, "unable to disable input\n");
424 		return -EINVAL;
425 	}
426 
427 	if (iectrl == UNIPHIER_PIN_IECTRL_NONE)
428 		/* This pin is always input-enabled. nothing to do. */
429 		return 0;
430 
431 	return regmap_update_bits(priv->regmap, UNIPHIER_PINCTRL_IECTRL,
432 				  BIT(iectrl), BIT(iectrl));
433 }
434 
435 static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev,
436 					unsigned pin,
437 					unsigned long *configs,
438 					unsigned num_configs)
439 {
440 	const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin];
441 	int i, ret;
442 
443 	for (i = 0; i < num_configs; i++) {
444 		enum pin_config_param param =
445 					pinconf_to_config_param(configs[i]);
446 		u16 arg = pinconf_to_config_argument(configs[i]);
447 
448 		switch (param) {
449 		case PIN_CONFIG_BIAS_DISABLE:
450 		case PIN_CONFIG_BIAS_PULL_UP:
451 		case PIN_CONFIG_BIAS_PULL_DOWN:
452 		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
453 			ret = uniphier_conf_pin_bias_set(pctldev, pin_desc,
454 							 param, arg);
455 			break;
456 		case PIN_CONFIG_DRIVE_STRENGTH:
457 			ret = uniphier_conf_pin_drive_set(pctldev, pin_desc,
458 							  arg);
459 			break;
460 		case PIN_CONFIG_INPUT_ENABLE:
461 			ret = uniphier_conf_pin_input_enable(pctldev,
462 							     pin_desc, arg);
463 			break;
464 		default:
465 			dev_err(pctldev->dev,
466 				"unsupported configuration parameter %u\n",
467 				param);
468 			return -EINVAL;
469 		}
470 
471 		if (ret)
472 			return ret;
473 	}
474 
475 	return 0;
476 }
477 
478 static int uniphier_conf_pin_config_group_set(struct pinctrl_dev *pctldev,
479 					      unsigned selector,
480 					      unsigned long *configs,
481 					      unsigned num_configs)
482 {
483 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
484 	const unsigned *pins = priv->socdata->groups[selector].pins;
485 	unsigned num_pins = priv->socdata->groups[selector].num_pins;
486 	int i, ret;
487 
488 	for (i = 0; i < num_pins; i++) {
489 		ret = uniphier_conf_pin_config_set(pctldev, pins[i],
490 						   configs, num_configs);
491 		if (ret)
492 			return ret;
493 	}
494 
495 	return 0;
496 }
497 
498 static const struct pinconf_ops uniphier_confops = {
499 	.is_generic = true,
500 	.pin_config_get = uniphier_conf_pin_config_get,
501 	.pin_config_set = uniphier_conf_pin_config_set,
502 	.pin_config_group_set = uniphier_conf_pin_config_group_set,
503 };
504 
505 static int uniphier_pmx_get_functions_count(struct pinctrl_dev *pctldev)
506 {
507 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
508 
509 	return priv->socdata->functions_count;
510 }
511 
512 static const char *uniphier_pmx_get_function_name(struct pinctrl_dev *pctldev,
513 						  unsigned selector)
514 {
515 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
516 
517 	return priv->socdata->functions[selector].name;
518 }
519 
520 static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev,
521 					    unsigned selector,
522 					    const char * const **groups,
523 					    unsigned *num_groups)
524 {
525 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
526 
527 	*groups = priv->socdata->functions[selector].groups;
528 	*num_groups = priv->socdata->functions[selector].num_groups;
529 
530 	return 0;
531 }
532 
533 static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin,
534 				    unsigned muxval)
535 {
536 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
537 	unsigned mux_bits = priv->socdata->mux_bits;
538 	unsigned reg_stride = priv->socdata->reg_stride;
539 	unsigned reg, reg_end, shift, mask;
540 	int ret;
541 
542 	reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
543 	reg_end = reg + reg_stride;
544 	shift = pin * mux_bits % 32;
545 	mask = (1U << mux_bits) - 1;
546 
547 	/*
548 	 * If reg_stride is greater than 4, the MSB of each pinsel shall be
549 	 * stored in the offset+4.
550 	 */
551 	for (; reg < reg_end; reg += 4) {
552 		ret = regmap_update_bits(priv->regmap, reg,
553 					 mask << shift, muxval << shift);
554 		if (ret)
555 			return ret;
556 		muxval >>= mux_bits;
557 	}
558 
559 	if (priv->socdata->load_pinctrl) {
560 		ret = regmap_write(priv->regmap,
561 				   UNIPHIER_PINCTRL_LOAD_PINMUX, 1);
562 		if (ret)
563 			return ret;
564 	}
565 
566 	/* some pins need input-enabling */
567 	return uniphier_conf_pin_input_enable(pctldev,
568 					      &pctldev->desc->pins[pin], 1);
569 }
570 
571 static int uniphier_pmx_set_mux(struct pinctrl_dev *pctldev,
572 				unsigned func_selector,
573 				unsigned group_selector)
574 {
575 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
576 	const struct uniphier_pinctrl_group *grp =
577 					&priv->socdata->groups[group_selector];
578 	int i;
579 	int ret;
580 
581 	for (i = 0; i < grp->num_pins; i++) {
582 		ret = uniphier_pmx_set_one_mux(pctldev, grp->pins[i],
583 					       grp->muxvals[i]);
584 		if (ret)
585 			return ret;
586 	}
587 
588 	return 0;
589 }
590 
591 static int uniphier_pmx_gpio_request_enable(struct pinctrl_dev *pctldev,
592 					    struct pinctrl_gpio_range *range,
593 					    unsigned offset)
594 {
595 	struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev);
596 	const struct uniphier_pinctrl_group *groups = priv->socdata->groups;
597 	int groups_count = priv->socdata->groups_count;
598 	enum uniphier_pinmux_gpio_range_type range_type;
599 	int i, j;
600 
601 	if (strstr(range->name, "irq"))
602 		range_type = UNIPHIER_PINMUX_GPIO_RANGE_IRQ;
603 	else
604 		range_type = UNIPHIER_PINMUX_GPIO_RANGE_PORT;
605 
606 	for (i = 0; i < groups_count; i++) {
607 		if (groups[i].range_type != range_type)
608 			continue;
609 
610 		for (j = 0; j < groups[i].num_pins; j++)
611 			if (groups[i].pins[j] == offset)
612 				goto found;
613 	}
614 
615 	dev_err(pctldev->dev, "pin %u does not support GPIO\n", offset);
616 	return -EINVAL;
617 
618 found:
619 	return uniphier_pmx_set_one_mux(pctldev, offset, groups[i].muxvals[j]);
620 }
621 
622 static const struct pinmux_ops uniphier_pmxops = {
623 	.get_functions_count = uniphier_pmx_get_functions_count,
624 	.get_function_name = uniphier_pmx_get_function_name,
625 	.get_function_groups = uniphier_pmx_get_function_groups,
626 	.set_mux = uniphier_pmx_set_mux,
627 	.gpio_request_enable = uniphier_pmx_gpio_request_enable,
628 	.strict = true,
629 };
630 
631 int uniphier_pinctrl_probe(struct platform_device *pdev,
632 			   struct pinctrl_desc *desc,
633 			   struct uniphier_pinctrl_socdata *socdata)
634 {
635 	struct device *dev = &pdev->dev;
636 	struct uniphier_pinctrl_priv *priv;
637 
638 	if (!socdata ||
639 	    !socdata->groups ||
640 	    !socdata->groups_count ||
641 	    !socdata->functions ||
642 	    !socdata->functions_count ||
643 	    !socdata->mux_bits ||
644 	    !socdata->reg_stride) {
645 		dev_err(dev, "pinctrl socdata lacks necessary members\n");
646 		return -EINVAL;
647 	}
648 
649 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
650 	if (!priv)
651 		return -ENOMEM;
652 
653 	priv->regmap = syscon_node_to_regmap(dev->of_node);
654 	if (IS_ERR(priv->regmap)) {
655 		dev_err(dev, "failed to get regmap\n");
656 		return PTR_ERR(priv->regmap);
657 	}
658 
659 	priv->socdata = socdata;
660 	desc->pctlops = &uniphier_pctlops;
661 	desc->pmxops = &uniphier_pmxops;
662 	desc->confops = &uniphier_confops;
663 
664 	priv->pctldev = pinctrl_register(desc, dev, priv);
665 	if (IS_ERR(priv->pctldev)) {
666 		dev_err(dev, "failed to register UniPhier pinctrl driver\n");
667 		return PTR_ERR(priv->pctldev);
668 	}
669 
670 	platform_set_drvdata(pdev, priv);
671 
672 	return 0;
673 }
674 EXPORT_SYMBOL_GPL(uniphier_pinctrl_probe);
675 
676 int uniphier_pinctrl_remove(struct platform_device *pdev)
677 {
678 	struct uniphier_pinctrl_priv *priv = platform_get_drvdata(pdev);
679 
680 	pinctrl_unregister(priv->pctldev);
681 
682 	return 0;
683 }
684 EXPORT_SYMBOL_GPL(uniphier_pinctrl_remove);
685