xref: /openbmc/linux/drivers/pinctrl/pinconf.c (revision f35e839a)
1 /*
2  * Core driver for the pin config portions of the pin control subsystem
3  *
4  * Copyright (C) 2011 ST-Ericsson SA
5  * Written on behalf of Linaro for ST-Ericsson
6  *
7  * Author: Linus Walleij <linus.walleij@linaro.org>
8  *
9  * License terms: GNU General Public License (GPL) version 2
10  */
11 #define pr_fmt(fmt) "pinconfig core: " fmt
12 
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/device.h>
17 #include <linux/slab.h>
18 #include <linux/debugfs.h>
19 #include <linux/seq_file.h>
20 #include <linux/uaccess.h>
21 #include <linux/pinctrl/machine.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinconf.h>
24 #include "core.h"
25 #include "pinconf.h"
26 
27 int pinconf_check_ops(struct pinctrl_dev *pctldev)
28 {
29 	const struct pinconf_ops *ops = pctldev->desc->confops;
30 
31 	/* We must be able to read out pin status */
32 	if (!ops->pin_config_get && !ops->pin_config_group_get) {
33 		dev_err(pctldev->dev,
34 			"pinconf must be able to read out pin status\n");
35 		return -EINVAL;
36 	}
37 	/* We have to be able to config the pins in SOME way */
38 	if (!ops->pin_config_set && !ops->pin_config_group_set) {
39 		dev_err(pctldev->dev,
40 			"pinconf has to be able to set a pins config\n");
41 		return -EINVAL;
42 	}
43 	return 0;
44 }
45 
46 int pinconf_validate_map(struct pinctrl_map const *map, int i)
47 {
48 	if (!map->data.configs.group_or_pin) {
49 		pr_err("failed to register map %s (%d): no group/pin given\n",
50 		       map->name, i);
51 		return -EINVAL;
52 	}
53 
54 	if (!map->data.configs.num_configs ||
55 			!map->data.configs.configs) {
56 		pr_err("failed to register map %s (%d): no configs given\n",
57 		       map->name, i);
58 		return -EINVAL;
59 	}
60 
61 	return 0;
62 }
63 
64 int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
65 			   unsigned long *config)
66 {
67 	const struct pinconf_ops *ops = pctldev->desc->confops;
68 
69 	if (!ops || !ops->pin_config_get) {
70 		dev_err(pctldev->dev, "cannot get pin configuration, missing "
71 			"pin_config_get() function in driver\n");
72 		return -EINVAL;
73 	}
74 
75 	return ops->pin_config_get(pctldev, pin, config);
76 }
77 
78 /**
79  * pin_config_get() - get the configuration of a single pin parameter
80  * @dev_name: name of the pin controller device for this pin
81  * @name: name of the pin to get the config for
82  * @config: the config pointed to by this argument will be filled in with the
83  *	current pin state, it can be used directly by drivers as a numeral, or
84  *	it can be dereferenced to any struct.
85  */
86 int pin_config_get(const char *dev_name, const char *name,
87 			  unsigned long *config)
88 {
89 	struct pinctrl_dev *pctldev;
90 	int pin;
91 
92 	pctldev = get_pinctrl_dev_from_devname(dev_name);
93 	if (!pctldev) {
94 		pin = -EINVAL;
95 		return pin;
96 	}
97 
98 	mutex_lock(&pctldev->mutex);
99 
100 	pin = pin_get_from_name(pctldev, name);
101 	if (pin < 0)
102 		goto unlock;
103 
104 	pin = pin_config_get_for_pin(pctldev, pin, config);
105 
106 unlock:
107 	mutex_unlock(&pctldev->mutex);
108 	return pin;
109 }
110 EXPORT_SYMBOL(pin_config_get);
111 
112 static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
113 			   unsigned long config)
114 {
115 	const struct pinconf_ops *ops = pctldev->desc->confops;
116 	int ret;
117 
118 	if (!ops || !ops->pin_config_set) {
119 		dev_err(pctldev->dev, "cannot configure pin, missing "
120 			"config function in driver\n");
121 		return -EINVAL;
122 	}
123 
124 	ret = ops->pin_config_set(pctldev, pin, config);
125 	if (ret) {
126 		dev_err(pctldev->dev,
127 			"unable to set pin configuration on pin %d\n", pin);
128 		return ret;
129 	}
130 
131 	return 0;
132 }
133 
134 /**
135  * pin_config_set() - set the configuration of a single pin parameter
136  * @dev_name: name of pin controller device for this pin
137  * @name: name of the pin to set the config for
138  * @config: the config in this argument will contain the desired pin state, it
139  *	can be used directly by drivers as a numeral, or it can be dereferenced
140  *	to any struct.
141  */
142 int pin_config_set(const char *dev_name, const char *name,
143 		   unsigned long config)
144 {
145 	struct pinctrl_dev *pctldev;
146 	int pin, ret;
147 
148 	pctldev = get_pinctrl_dev_from_devname(dev_name);
149 	if (!pctldev) {
150 		ret = -EINVAL;
151 		return ret;
152 	}
153 
154 	mutex_lock(&pctldev->mutex);
155 
156 	pin = pin_get_from_name(pctldev, name);
157 	if (pin < 0) {
158 		ret = pin;
159 		goto unlock;
160 	}
161 
162 	ret = pin_config_set_for_pin(pctldev, pin, config);
163 
164 unlock:
165 	mutex_unlock(&pctldev->mutex);
166 	return ret;
167 }
168 EXPORT_SYMBOL(pin_config_set);
169 
170 int pin_config_group_get(const char *dev_name, const char *pin_group,
171 			 unsigned long *config)
172 {
173 	struct pinctrl_dev *pctldev;
174 	const struct pinconf_ops *ops;
175 	int selector, ret;
176 
177 	pctldev = get_pinctrl_dev_from_devname(dev_name);
178 	if (!pctldev) {
179 		ret = -EINVAL;
180 		return ret;
181 	}
182 
183 	mutex_lock(&pctldev->mutex);
184 
185 	ops = pctldev->desc->confops;
186 
187 	if (!ops || !ops->pin_config_group_get) {
188 		dev_err(pctldev->dev, "cannot get configuration for pin "
189 			"group, missing group config get function in "
190 			"driver\n");
191 		ret = -EINVAL;
192 		goto unlock;
193 	}
194 
195 	selector = pinctrl_get_group_selector(pctldev, pin_group);
196 	if (selector < 0) {
197 		ret = selector;
198 		goto unlock;
199 	}
200 
201 	ret = ops->pin_config_group_get(pctldev, selector, config);
202 
203 unlock:
204 	mutex_unlock(&pctldev->mutex);
205 	return ret;
206 }
207 EXPORT_SYMBOL(pin_config_group_get);
208 
209 int pin_config_group_set(const char *dev_name, const char *pin_group,
210 			 unsigned long config)
211 {
212 	struct pinctrl_dev *pctldev;
213 	const struct pinconf_ops *ops;
214 	const struct pinctrl_ops *pctlops;
215 	int selector;
216 	const unsigned *pins;
217 	unsigned num_pins;
218 	int ret;
219 	int i;
220 
221 	pctldev = get_pinctrl_dev_from_devname(dev_name);
222 	if (!pctldev) {
223 		ret = -EINVAL;
224 		return ret;
225 	}
226 
227 	mutex_lock(&pctldev->mutex);
228 
229 	ops = pctldev->desc->confops;
230 	pctlops = pctldev->desc->pctlops;
231 
232 	if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
233 		dev_err(pctldev->dev, "cannot configure pin group, missing "
234 			"config function in driver\n");
235 		ret = -EINVAL;
236 		goto unlock;
237 	}
238 
239 	selector = pinctrl_get_group_selector(pctldev, pin_group);
240 	if (selector < 0) {
241 		ret = selector;
242 		goto unlock;
243 	}
244 
245 	ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
246 	if (ret) {
247 		dev_err(pctldev->dev, "cannot configure pin group, error "
248 			"getting pins\n");
249 		goto unlock;
250 	}
251 
252 	/*
253 	 * If the pin controller supports handling entire groups we use that
254 	 * capability.
255 	 */
256 	if (ops->pin_config_group_set) {
257 		ret = ops->pin_config_group_set(pctldev, selector, config);
258 		/*
259 		 * If the pin controller prefer that a certain group be handled
260 		 * pin-by-pin as well, it returns -EAGAIN.
261 		 */
262 		if (ret != -EAGAIN)
263 			goto unlock;
264 	}
265 
266 	/*
267 	 * If the controller cannot handle entire groups, we configure each pin
268 	 * individually.
269 	 */
270 	if (!ops->pin_config_set) {
271 		ret = 0;
272 		goto unlock;
273 	}
274 
275 	for (i = 0; i < num_pins; i++) {
276 		ret = ops->pin_config_set(pctldev, pins[i], config);
277 		if (ret < 0)
278 			goto unlock;
279 	}
280 
281 	ret = 0;
282 
283 unlock:
284 	mutex_unlock(&pctldev->mutex);
285 
286 	return ret;
287 }
288 EXPORT_SYMBOL(pin_config_group_set);
289 
290 int pinconf_map_to_setting(struct pinctrl_map const *map,
291 			  struct pinctrl_setting *setting)
292 {
293 	struct pinctrl_dev *pctldev = setting->pctldev;
294 	int pin;
295 
296 	switch (setting->type) {
297 	case PIN_MAP_TYPE_CONFIGS_PIN:
298 		pin = pin_get_from_name(pctldev,
299 					map->data.configs.group_or_pin);
300 		if (pin < 0) {
301 			dev_err(pctldev->dev, "could not map pin config for \"%s\"",
302 				map->data.configs.group_or_pin);
303 			return pin;
304 		}
305 		setting->data.configs.group_or_pin = pin;
306 		break;
307 	case PIN_MAP_TYPE_CONFIGS_GROUP:
308 		pin = pinctrl_get_group_selector(pctldev,
309 					 map->data.configs.group_or_pin);
310 		if (pin < 0) {
311 			dev_err(pctldev->dev, "could not map group config for \"%s\"",
312 				map->data.configs.group_or_pin);
313 			return pin;
314 		}
315 		setting->data.configs.group_or_pin = pin;
316 		break;
317 	default:
318 		return -EINVAL;
319 	}
320 
321 	setting->data.configs.num_configs = map->data.configs.num_configs;
322 	setting->data.configs.configs = map->data.configs.configs;
323 
324 	return 0;
325 }
326 
327 void pinconf_free_setting(struct pinctrl_setting const *setting)
328 {
329 }
330 
331 int pinconf_apply_setting(struct pinctrl_setting const *setting)
332 {
333 	struct pinctrl_dev *pctldev = setting->pctldev;
334 	const struct pinconf_ops *ops = pctldev->desc->confops;
335 	int i, ret;
336 
337 	if (!ops) {
338 		dev_err(pctldev->dev, "missing confops\n");
339 		return -EINVAL;
340 	}
341 
342 	switch (setting->type) {
343 	case PIN_MAP_TYPE_CONFIGS_PIN:
344 		if (!ops->pin_config_set) {
345 			dev_err(pctldev->dev, "missing pin_config_set op\n");
346 			return -EINVAL;
347 		}
348 		for (i = 0; i < setting->data.configs.num_configs; i++) {
349 			ret = ops->pin_config_set(pctldev,
350 					setting->data.configs.group_or_pin,
351 					setting->data.configs.configs[i]);
352 			if (ret < 0) {
353 				dev_err(pctldev->dev,
354 					"pin_config_set op failed for pin %d config %08lx\n",
355 					setting->data.configs.group_or_pin,
356 					setting->data.configs.configs[i]);
357 				return ret;
358 			}
359 		}
360 		break;
361 	case PIN_MAP_TYPE_CONFIGS_GROUP:
362 		if (!ops->pin_config_group_set) {
363 			dev_err(pctldev->dev,
364 				"missing pin_config_group_set op\n");
365 			return -EINVAL;
366 		}
367 		for (i = 0; i < setting->data.configs.num_configs; i++) {
368 			ret = ops->pin_config_group_set(pctldev,
369 					setting->data.configs.group_or_pin,
370 					setting->data.configs.configs[i]);
371 			if (ret < 0) {
372 				dev_err(pctldev->dev,
373 					"pin_config_group_set op failed for group %d config %08lx\n",
374 					setting->data.configs.group_or_pin,
375 					setting->data.configs.configs[i]);
376 				return ret;
377 			}
378 		}
379 		break;
380 	default:
381 		return -EINVAL;
382 	}
383 
384 	return 0;
385 }
386 
387 #ifdef CONFIG_DEBUG_FS
388 
389 void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
390 {
391 	struct pinctrl_dev *pctldev;
392 	const struct pinconf_ops *confops;
393 	int i;
394 
395 	pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
396 	if (pctldev)
397 		confops = pctldev->desc->confops;
398 	else
399 		confops = NULL;
400 
401 	switch (map->type) {
402 	case PIN_MAP_TYPE_CONFIGS_PIN:
403 		seq_printf(s, "pin ");
404 		break;
405 	case PIN_MAP_TYPE_CONFIGS_GROUP:
406 		seq_printf(s, "group ");
407 		break;
408 	default:
409 		break;
410 	}
411 
412 	seq_printf(s, "%s\n", map->data.configs.group_or_pin);
413 
414 	for (i = 0; i < map->data.configs.num_configs; i++) {
415 		seq_printf(s, "config ");
416 		if (confops && confops->pin_config_config_dbg_show)
417 			confops->pin_config_config_dbg_show(pctldev, s,
418 						map->data.configs.configs[i]);
419 		else
420 			seq_printf(s, "%08lx", map->data.configs.configs[i]);
421 		seq_printf(s, "\n");
422 	}
423 }
424 
425 void pinconf_show_setting(struct seq_file *s,
426 			  struct pinctrl_setting const *setting)
427 {
428 	struct pinctrl_dev *pctldev = setting->pctldev;
429 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
430 	const struct pinconf_ops *confops = pctldev->desc->confops;
431 	struct pin_desc *desc;
432 	int i;
433 
434 	switch (setting->type) {
435 	case PIN_MAP_TYPE_CONFIGS_PIN:
436 		desc = pin_desc_get(setting->pctldev,
437 				    setting->data.configs.group_or_pin);
438 		seq_printf(s, "pin %s (%d)",
439 			   desc->name ? desc->name : "unnamed",
440 			   setting->data.configs.group_or_pin);
441 		break;
442 	case PIN_MAP_TYPE_CONFIGS_GROUP:
443 		seq_printf(s, "group %s (%d)",
444 			   pctlops->get_group_name(pctldev,
445 					setting->data.configs.group_or_pin),
446 			   setting->data.configs.group_or_pin);
447 		break;
448 	default:
449 		break;
450 	}
451 
452 	/*
453 	 * FIXME: We should really get the pin controler to dump the config
454 	 * values, so they can be decoded to something meaningful.
455 	 */
456 	for (i = 0; i < setting->data.configs.num_configs; i++) {
457 		seq_printf(s, " ");
458 		if (confops && confops->pin_config_config_dbg_show)
459 			confops->pin_config_config_dbg_show(pctldev, s,
460 				setting->data.configs.configs[i]);
461 		else
462 			seq_printf(s, "%08lx",
463 				   setting->data.configs.configs[i]);
464 	}
465 
466 	seq_printf(s, "\n");
467 }
468 
469 static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
470 			     struct seq_file *s, int pin)
471 {
472 	const struct pinconf_ops *ops = pctldev->desc->confops;
473 
474 	/* no-op when not using generic pin config */
475 	pinconf_generic_dump_pin(pctldev, s, pin);
476 	if (ops && ops->pin_config_dbg_show)
477 		ops->pin_config_dbg_show(pctldev, s, pin);
478 }
479 
480 static int pinconf_pins_show(struct seq_file *s, void *what)
481 {
482 	struct pinctrl_dev *pctldev = s->private;
483 	const struct pinconf_ops *ops = pctldev->desc->confops;
484 	unsigned i, pin;
485 
486 	if (!ops || !ops->pin_config_get)
487 		return 0;
488 
489 	seq_puts(s, "Pin config settings per pin\n");
490 	seq_puts(s, "Format: pin (name): configs\n");
491 
492 	mutex_lock(&pctldev->mutex);
493 
494 	/* The pin number can be retrived from the pin controller descriptor */
495 	for (i = 0; i < pctldev->desc->npins; i++) {
496 		struct pin_desc *desc;
497 
498 		pin = pctldev->desc->pins[i].number;
499 		desc = pin_desc_get(pctldev, pin);
500 		/* Skip if we cannot search the pin */
501 		if (desc == NULL)
502 			continue;
503 
504 		seq_printf(s, "pin %d (%s):", pin,
505 			   desc->name ? desc->name : "unnamed");
506 
507 		pinconf_dump_pin(pctldev, s, pin);
508 
509 		seq_printf(s, "\n");
510 	}
511 
512 	mutex_unlock(&pctldev->mutex);
513 
514 	return 0;
515 }
516 
517 static void pinconf_dump_group(struct pinctrl_dev *pctldev,
518 			       struct seq_file *s, unsigned selector,
519 			       const char *gname)
520 {
521 	const struct pinconf_ops *ops = pctldev->desc->confops;
522 
523 	/* no-op when not using generic pin config */
524 	pinconf_generic_dump_group(pctldev, s, gname);
525 	if (ops && ops->pin_config_group_dbg_show)
526 		ops->pin_config_group_dbg_show(pctldev, s, selector);
527 }
528 
529 static int pinconf_groups_show(struct seq_file *s, void *what)
530 {
531 	struct pinctrl_dev *pctldev = s->private;
532 	const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
533 	const struct pinconf_ops *ops = pctldev->desc->confops;
534 	unsigned ngroups = pctlops->get_groups_count(pctldev);
535 	unsigned selector = 0;
536 
537 	if (!ops || !ops->pin_config_group_get)
538 		return 0;
539 
540 	seq_puts(s, "Pin config settings per pin group\n");
541 	seq_puts(s, "Format: group (name): configs\n");
542 
543 	while (selector < ngroups) {
544 		const char *gname = pctlops->get_group_name(pctldev, selector);
545 
546 		seq_printf(s, "%u (%s):", selector, gname);
547 		pinconf_dump_group(pctldev, s, selector, gname);
548 		seq_printf(s, "\n");
549 
550 		selector++;
551 	}
552 
553 	return 0;
554 }
555 
556 static int pinconf_pins_open(struct inode *inode, struct file *file)
557 {
558 	return single_open(file, pinconf_pins_show, inode->i_private);
559 }
560 
561 static int pinconf_groups_open(struct inode *inode, struct file *file)
562 {
563 	return single_open(file, pinconf_groups_show, inode->i_private);
564 }
565 
566 static const struct file_operations pinconf_pins_ops = {
567 	.open		= pinconf_pins_open,
568 	.read		= seq_read,
569 	.llseek		= seq_lseek,
570 	.release	= single_release,
571 };
572 
573 static const struct file_operations pinconf_groups_ops = {
574 	.open		= pinconf_groups_open,
575 	.read		= seq_read,
576 	.llseek		= seq_lseek,
577 	.release	= single_release,
578 };
579 
580 #define MAX_NAME_LEN 15
581 
582 struct dbg_cfg {
583 	enum pinctrl_map_type map_type;
584 	char dev_name[MAX_NAME_LEN+1];
585 	char state_name[MAX_NAME_LEN+1];
586 	char pin_name[MAX_NAME_LEN+1];
587 };
588 
589 /*
590  * Goal is to keep this structure as global in order to simply read the
591  * pinconf-config file after a write to check config is as expected
592  */
593 static struct dbg_cfg pinconf_dbg_conf;
594 
595 /**
596  * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
597  * map, of the dev/pin/state that was last written to pinconf-config file.
598  * @s: string filled in  with config description
599  * @d: not used
600  */
601 static int pinconf_dbg_config_print(struct seq_file *s, void *d)
602 {
603 	struct pinctrl_maps *maps_node;
604 	const struct pinctrl_map *map;
605 	struct pinctrl_dev *pctldev = NULL;
606 	const struct pinconf_ops *confops = NULL;
607 	const struct pinctrl_map_configs *configs;
608 	struct dbg_cfg *dbg = &pinconf_dbg_conf;
609 	int i, j;
610 	bool found = false;
611 	unsigned long config;
612 
613 	mutex_lock(&pctldev->mutex);
614 
615 	/* Parse the pinctrl map and look for the elected pin/state */
616 	for_each_maps(maps_node, i, map) {
617 		if (map->type != dbg->map_type)
618 			continue;
619 		if (strcmp(map->dev_name, dbg->dev_name))
620 			continue;
621 		if (strcmp(map->name, dbg->state_name))
622 			continue;
623 
624 		for (j = 0; j < map->data.configs.num_configs; j++) {
625 			if (!strcmp(map->data.configs.group_or_pin,
626 					dbg->pin_name)) {
627 				/*
628 				 * We found the right pin / state, read the
629 				 * config and he pctldev for later use
630 				 */
631 				configs = &map->data.configs;
632 				pctldev = get_pinctrl_dev_from_devname
633 					(map->ctrl_dev_name);
634 				found = true;
635 				break;
636 			}
637 		}
638 	}
639 
640 	if (!found) {
641 		seq_printf(s, "No config found for dev/state/pin, expected:\n");
642 		seq_printf(s, "Searched dev:%s\n", dbg->dev_name);
643 		seq_printf(s, "Searched state:%s\n", dbg->state_name);
644 		seq_printf(s, "Searched pin:%s\n", dbg->pin_name);
645 		seq_printf(s, "Use: modify config_pin <devname> "\
646 				"<state> <pinname> <value>\n");
647 		goto exit;
648 	}
649 
650 	config = *(configs->configs);
651 	seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n",
652 			dbg->dev_name, dbg->pin_name,
653 			dbg->state_name, config);
654 
655 	if (pctldev)
656 		confops = pctldev->desc->confops;
657 
658 	if (confops && confops->pin_config_config_dbg_show)
659 		confops->pin_config_config_dbg_show(pctldev, s, config);
660 
661 exit:
662 	mutex_unlock(&pctldev->mutex);
663 
664 	return 0;
665 }
666 
667 /**
668  * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl
669  * map, of a dev/pin/state entry based on user entries to pinconf-config
670  * @user_buf: contains the modification request with expected format:
671  *     modify config_pin <devicename> <state> <pinname> <newvalue>
672  * modify is literal string, alternatives like add/delete not supported yet
673  * config_pin is literal, alternatives like config_mux not supported yet
674  * <devicename> <state> <pinname> are values that should match the pinctrl-maps
675  * <newvalue> reflects the new config and is driver dependant
676  */
677 static int pinconf_dbg_config_write(struct file *file,
678 	const char __user *user_buf, size_t count, loff_t *ppos)
679 {
680 	struct pinctrl_maps *maps_node;
681 	const struct pinctrl_map *map;
682 	struct pinctrl_dev *pctldev = NULL;
683 	const struct pinconf_ops *confops = NULL;
684 	struct dbg_cfg *dbg = &pinconf_dbg_conf;
685 	const struct pinctrl_map_configs *configs;
686 	char config[MAX_NAME_LEN+1];
687 	bool found = false;
688 	char buf[128];
689 	char *b = &buf[0];
690 	int buf_size;
691 	char *token;
692 	int i;
693 
694 	/* Get userspace string and assure termination */
695 	buf_size = min(count, (sizeof(buf)-1));
696 	if (copy_from_user(buf, user_buf, buf_size))
697 		return -EFAULT;
698 	buf[buf_size] = 0;
699 
700 	/*
701 	 * need to parse entry and extract parameters:
702 	 * modify configs_pin devicename state pinname newvalue
703 	 */
704 
705 	/* Get arg: 'modify' */
706 	token = strsep(&b, " ");
707 	if (!token)
708 		return -EINVAL;
709 	if (strcmp(token, "modify"))
710 		return -EINVAL;
711 
712 	/* Get arg type: "config_pin" type supported so far */
713 	token = strsep(&b, " ");
714 	if (!token)
715 		return -EINVAL;
716 	if (strcmp(token, "config_pin"))
717 		return -EINVAL;
718 	dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN;
719 
720 	/* get arg 'device_name' */
721 	token = strsep(&b, " ");
722 	if (token == NULL)
723 		return -EINVAL;
724 	if (strlen(token) >= MAX_NAME_LEN)
725 		return -EINVAL;
726 	strncpy(dbg->dev_name, token, MAX_NAME_LEN);
727 
728 	/* get arg 'state_name' */
729 	token = strsep(&b, " ");
730 	if (token == NULL)
731 		return -EINVAL;
732 	if (strlen(token) >= MAX_NAME_LEN)
733 		return -EINVAL;
734 	strncpy(dbg->state_name, token, MAX_NAME_LEN);
735 
736 	/* get arg 'pin_name' */
737 	token = strsep(&b, " ");
738 	if (token == NULL)
739 		return -EINVAL;
740 	if (strlen(token) >= MAX_NAME_LEN)
741 		return -EINVAL;
742 	strncpy(dbg->pin_name, token, MAX_NAME_LEN);
743 
744 	/* get new_value of config' */
745 	token = strsep(&b, " ");
746 	if (token == NULL)
747 		return -EINVAL;
748 	if (strlen(token) >= MAX_NAME_LEN)
749 		return -EINVAL;
750 	strncpy(config, token, MAX_NAME_LEN);
751 
752 	mutex_lock(&pinctrl_maps_mutex);
753 
754 	/* Parse the pinctrl map and look for the selected dev/state/pin */
755 	for_each_maps(maps_node, i, map) {
756 		if (strcmp(map->dev_name, dbg->dev_name))
757 			continue;
758 		if (map->type != dbg->map_type)
759 			continue;
760 		if (strcmp(map->name, dbg->state_name))
761 			continue;
762 
763 		/*  we found the right pin / state, so overwrite config */
764 		if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) {
765 			found = true;
766 			pctldev = get_pinctrl_dev_from_devname(
767 					map->ctrl_dev_name);
768 			configs = &map->data.configs;
769 			break;
770 		}
771 	}
772 
773 	if (!found) {
774 		count = -EINVAL;
775 		goto exit;
776 	}
777 
778 	if (pctldev)
779 		confops = pctldev->desc->confops;
780 
781 	if (confops && confops->pin_config_dbg_parse_modify) {
782 		for (i = 0; i < configs->num_configs; i++) {
783 			confops->pin_config_dbg_parse_modify(pctldev,
784 						     config,
785 						     &configs->configs[i]);
786 		}
787 	}
788 
789 exit:
790 	mutex_unlock(&pinctrl_maps_mutex);
791 
792 	return count;
793 }
794 
795 static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
796 {
797 	return single_open(file, pinconf_dbg_config_print, inode->i_private);
798 }
799 
800 static const struct file_operations pinconf_dbg_pinconfig_fops = {
801 	.open = pinconf_dbg_config_open,
802 	.write = pinconf_dbg_config_write,
803 	.read = seq_read,
804 	.llseek = seq_lseek,
805 	.release = single_release,
806 	.owner = THIS_MODULE,
807 };
808 
809 void pinconf_init_device_debugfs(struct dentry *devroot,
810 			 struct pinctrl_dev *pctldev)
811 {
812 	debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
813 			    devroot, pctldev, &pinconf_pins_ops);
814 	debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
815 			    devroot, pctldev, &pinconf_groups_ops);
816 	debugfs_create_file("pinconf-config",  (S_IRUGO | S_IWUSR | S_IWGRP),
817 			    devroot, pctldev, &pinconf_dbg_pinconfig_fops);
818 }
819 
820 #endif
821