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