]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/gpio/gpio-uclass.c
karo: fdt: fix panel-dpi support
[karo-tx-uboot.git] / drivers / gpio / gpio-uclass.c
1 /*
2  * Copyright (c) 2013 Google, Inc
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <fdtdec.h>
11 #include <malloc.h>
12 #include <asm/gpio.h>
13 #include <linux/ctype.h>
14
15 DECLARE_GLOBAL_DATA_PTR;
16
17 /**
18  * gpio_to_device() - Convert global GPIO number to device, number
19  *
20  * Convert the GPIO number to an entry in the list of GPIOs
21  * or GPIO blocks registered with the GPIO controller. Returns
22  * entry on success, NULL on error.
23  *
24  * @gpio:       The numeric representation of the GPIO
25  * @desc:       Returns description (desc->flags will always be 0)
26  * @return 0 if found, -ENOENT if not found
27  */
28 static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
29 {
30         struct gpio_dev_priv *uc_priv;
31         struct udevice *dev;
32         int ret;
33
34         for (ret = uclass_first_device(UCLASS_GPIO, &dev);
35              dev;
36              ret = uclass_next_device(&dev)) {
37                 uc_priv = dev_get_uclass_priv(dev);
38                 if (gpio >= uc_priv->gpio_base &&
39                     gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
40                         desc->dev = dev;
41                         desc->offset = gpio - uc_priv->gpio_base;
42                         desc->flags = 0;
43                         return 0;
44                 }
45         }
46
47         /* No such GPIO */
48         return ret ? ret : -ENOENT;
49 }
50
51 int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
52 {
53         struct gpio_dev_priv *uc_priv = NULL;
54         struct udevice *dev;
55         ulong offset;
56         int numeric;
57         int ret;
58
59         numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
60         for (ret = uclass_first_device(UCLASS_GPIO, &dev);
61              dev;
62              ret = uclass_next_device(&dev)) {
63                 int len;
64
65                 uc_priv = dev_get_uclass_priv(dev);
66                 if (numeric != -1) {
67                         offset = numeric - uc_priv->gpio_base;
68                         /* Allow GPIOs to be numbered from 0 */
69                         if (offset >= 0 && offset < uc_priv->gpio_count)
70                                 break;
71                 }
72
73                 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
74
75                 if (!strncasecmp(name, uc_priv->bank_name, len)) {
76                         if (!strict_strtoul(name + len, 10, &offset))
77                                 break;
78                 }
79         }
80
81         if (!dev)
82                 return ret ? ret : -EINVAL;
83
84         desc->dev = dev;
85         desc->offset = offset;
86
87         return 0;
88 }
89
90 int gpio_lookup_name(const char *name, struct udevice **devp,
91                      unsigned int *offsetp, unsigned int *gpiop)
92 {
93         struct gpio_desc desc;
94         int ret;
95
96         if (devp)
97                 *devp = NULL;
98         ret = dm_gpio_lookup_name(name, &desc);
99         if (ret)
100                 return ret;
101
102         if (devp)
103                 *devp = desc.dev;
104         if (offsetp)
105                 *offsetp = desc.offset;
106         if (gpiop) {
107                 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
108
109                 *gpiop = uc_priv->gpio_base + desc.offset;
110         }
111
112         return 0;
113 }
114
115 static int gpio_find_and_xlate(struct gpio_desc *desc,
116                                struct fdtdec_phandle_args *args)
117 {
118         struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
119
120         /* Use the first argument as the offset by default */
121         if (args->args_count > 0)
122                 desc->offset = args->args[0];
123         else
124                 desc->offset = -1;
125         desc->flags = 0;
126
127         return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
128 }
129
130 int dm_gpio_request(struct gpio_desc *desc, const char *label)
131 {
132         struct udevice *dev = desc->dev;
133         struct gpio_dev_priv *uc_priv;
134         char *str;
135         int ret;
136
137         uc_priv = dev_get_uclass_priv(dev);
138         if (uc_priv->name[desc->offset])
139                 return -EBUSY;
140         str = strdup(label);
141         if (!str)
142                 return -ENOMEM;
143         if (gpio_get_ops(dev)->request) {
144                 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
145                 if (ret) {
146                         free(str);
147                         return ret;
148                 }
149         }
150         uc_priv->name[desc->offset] = str;
151
152         return 0;
153 }
154
155 static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
156 {
157         va_list args;
158         char buf[40];
159
160         va_start(args, fmt);
161         vscnprintf(buf, sizeof(buf), fmt, args);
162         va_end(args);
163         return dm_gpio_request(desc, buf);
164 }
165
166 /**
167  * gpio_request() - [COMPAT] Request GPIO
168  * gpio:        GPIO number
169  * label:       Name for the requested GPIO
170  *
171  * The label is copied and allocated so the caller does not need to keep
172  * the pointer around.
173  *
174  * This function implements the API that's compatible with current
175  * GPIO API used in U-Boot. The request is forwarded to particular
176  * GPIO driver. Returns 0 on success, negative value on error.
177  */
178 int gpio_request(unsigned gpio, const char *label)
179 {
180         struct gpio_desc desc;
181         int ret;
182
183         ret = gpio_to_device(gpio, &desc);
184         if (ret)
185                 return ret;
186
187         return dm_gpio_request(&desc, label);
188 }
189
190 /**
191  * gpio_requestf() - [COMPAT] Request GPIO
192  * @gpio:       GPIO number
193  * @fmt:        Format string for the requested GPIO
194  * @...:        Arguments for the printf() format string
195  *
196  * This function implements the API that's compatible with current
197  * GPIO API used in U-Boot. The request is forwarded to particular
198  * GPIO driver. Returns 0 on success, negative value on error.
199  */
200 int gpio_requestf(unsigned gpio, const char *fmt, ...)
201 {
202         va_list args;
203         char buf[40];
204
205         va_start(args, fmt);
206         vscnprintf(buf, sizeof(buf), fmt, args);
207         va_end(args);
208         return gpio_request(gpio, buf);
209 }
210
211 int _dm_gpio_free(struct udevice *dev, uint offset)
212 {
213         struct gpio_dev_priv *uc_priv;
214         int ret;
215
216         uc_priv = dev_get_uclass_priv(dev);
217         if (!uc_priv->name[offset])
218                 return -ENXIO;
219         if (gpio_get_ops(dev)->free) {
220                 ret = gpio_get_ops(dev)->free(dev, offset);
221                 if (ret)
222                         return ret;
223         }
224
225         free(uc_priv->name[offset]);
226         uc_priv->name[offset] = NULL;
227
228         return 0;
229 }
230
231 /**
232  * gpio_free() - [COMPAT] Relinquish GPIO
233  * gpio:        GPIO number
234  *
235  * This function implements the API that's compatible with current
236  * GPIO API used in U-Boot. The request is forwarded to particular
237  * GPIO driver. Returns 0 on success, negative value on error.
238  */
239 int gpio_free(unsigned gpio)
240 {
241         struct gpio_desc desc;
242         int ret;
243
244         ret = gpio_to_device(gpio, &desc);
245         if (ret)
246                 return ret;
247
248         return _dm_gpio_free(desc.dev, desc.offset);
249 }
250
251 static int check_reserved(struct gpio_desc *desc, const char *func)
252 {
253         struct gpio_dev_priv *uc_priv;
254
255         if (!dm_gpio_is_valid(desc))
256                 return -ENOENT;
257
258         uc_priv = dev_get_uclass_priv(desc->dev);
259         if (!uc_priv->name[desc->offset]) {
260                 printf("%s: %s: error: gpio %s%d not reserved\n",
261                        desc->dev->name, func,
262                        uc_priv->bank_name ? uc_priv->bank_name : "",
263                        desc->offset);
264                 return -EBUSY;
265         }
266
267         return 0;
268 }
269
270 /**
271  * gpio_direction_input() - [COMPAT] Set GPIO direction to input
272  * gpio:        GPIO number
273  *
274  * This function implements the API that's compatible with current
275  * GPIO API used in U-Boot. The request is forwarded to particular
276  * GPIO driver. Returns 0 on success, negative value on error.
277  */
278 int gpio_direction_input(unsigned gpio)
279 {
280         struct gpio_desc desc;
281         int ret;
282
283         ret = gpio_to_device(gpio, &desc);
284         if (ret)
285                 return ret;
286         ret = check_reserved(&desc, "dir_input");
287         if (ret)
288                 return ret;
289
290         return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
291 }
292
293 /**
294  * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
295  * gpio:        GPIO number
296  * value:       Logical value to be set on the GPIO pin
297  *
298  * This function implements the API that's compatible with current
299  * GPIO API used in U-Boot. The request is forwarded to particular
300  * GPIO driver. Returns 0 on success, negative value on error.
301  */
302 int gpio_direction_output(unsigned gpio, int value)
303 {
304         struct gpio_desc desc;
305         int ret;
306
307         ret = gpio_to_device(gpio, &desc);
308         if (ret)
309                 return ret;
310         ret = check_reserved(&desc, "dir_output");
311         if (ret)
312                 return ret;
313
314         return gpio_get_ops(desc.dev)->direction_output(desc.dev,
315                                                         desc.offset, value);
316 }
317
318 int dm_gpio_get_value(struct gpio_desc *desc)
319 {
320         int value;
321         int ret;
322
323         ret = check_reserved(desc, "get_value");
324         if (ret)
325                 return ret;
326
327         value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
328
329         return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
330 }
331
332 int dm_gpio_set_value(struct gpio_desc *desc, int value)
333 {
334         int ret;
335
336         ret = check_reserved(desc, "set_value");
337         if (ret)
338                 return ret;
339
340         if (desc->flags & GPIOD_ACTIVE_LOW)
341                 value = !value;
342         gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
343         return 0;
344 }
345
346 int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
347 {
348         struct udevice *dev = desc->dev;
349         struct dm_gpio_ops *ops = gpio_get_ops(dev);
350         int ret;
351
352         ret = check_reserved(desc, "set_dir");
353         if (ret)
354                 return ret;
355
356         if (flags & GPIOD_IS_OUT) {
357                 int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
358
359                 if (flags & GPIOD_ACTIVE_LOW)
360                         value = !value;
361                 ret = ops->direction_output(dev, desc->offset, value);
362         } else  if (flags & GPIOD_IS_IN) {
363                 ret = ops->direction_input(dev, desc->offset);
364         }
365         if (ret)
366                 return ret;
367         /*
368          * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
369          * futures
370          */
371         desc->flags = flags;
372
373         return 0;
374 }
375
376 int dm_gpio_set_dir(struct gpio_desc *desc)
377 {
378         return dm_gpio_set_dir_flags(desc, desc->flags);
379 }
380
381 /**
382  * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
383  * gpio:        GPIO number
384  *
385  * This function implements the API that's compatible with current
386  * GPIO API used in U-Boot. The request is forwarded to particular
387  * GPIO driver. Returns the value of the GPIO pin, or negative value
388  * on error.
389  */
390 int gpio_get_value(unsigned gpio)
391 {
392         int ret;
393
394         struct gpio_desc desc;
395
396         ret = gpio_to_device(gpio, &desc);
397         if (ret)
398                 return ret;
399         return dm_gpio_get_value(&desc);
400 }
401
402 /**
403  * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
404  * gpio:        GPIO number
405  * value:       Logical value to be set on the GPIO pin.
406  *
407  * This function implements the API that's compatible with current
408  * GPIO API used in U-Boot. The request is forwarded to particular
409  * GPIO driver. Returns 0 on success, negative value on error.
410  */
411 int gpio_set_value(unsigned gpio, int value)
412 {
413         struct gpio_desc desc;
414         int ret;
415
416         ret = gpio_to_device(gpio, &desc);
417         if (ret)
418                 return ret;
419         return dm_gpio_set_value(&desc, value);
420 }
421
422 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
423 {
424         struct gpio_dev_priv *priv;
425
426         /* Must be called on an active device */
427         priv = dev_get_uclass_priv(dev);
428         assert(priv);
429
430         *bit_count = priv->gpio_count;
431         return priv->bank_name;
432 }
433
434 static const char * const gpio_function[GPIOF_COUNT] = {
435         "input",
436         "output",
437         "unused",
438         "unknown",
439         "func",
440 };
441
442 int get_function(struct udevice *dev, int offset, bool skip_unused,
443                  const char **namep)
444 {
445         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
446         struct dm_gpio_ops *ops = gpio_get_ops(dev);
447
448         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
449         if (!device_active(dev))
450                 return -ENODEV;
451         if (offset < 0 || offset >= uc_priv->gpio_count)
452                 return -EINVAL;
453         if (namep)
454                 *namep = uc_priv->name[offset];
455         if (skip_unused && !uc_priv->name[offset])
456                 return GPIOF_UNUSED;
457         if (ops->get_function) {
458                 int ret;
459
460                 ret = ops->get_function(dev, offset);
461                 if (ret < 0)
462                         return ret;
463                 if (ret >= ARRAY_SIZE(gpio_function))
464                         return -ENODATA;
465                 return ret;
466         }
467
468         return GPIOF_UNKNOWN;
469 }
470
471 int gpio_get_function(struct udevice *dev, int offset, const char **namep)
472 {
473         return get_function(dev, offset, true, namep);
474 }
475
476 int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
477 {
478         return get_function(dev, offset, false, namep);
479 }
480
481 int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
482 {
483         struct dm_gpio_ops *ops = gpio_get_ops(dev);
484         struct gpio_dev_priv *priv;
485         char *str = buf;
486         int func;
487         int ret;
488         int len;
489
490         BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
491
492         *buf = 0;
493         priv = dev_get_uclass_priv(dev);
494         ret = gpio_get_raw_function(dev, offset, NULL);
495         if (ret < 0)
496                 return ret;
497         func = ret;
498         len = snprintf(str, buffsize, "%s%d: %s",
499                        priv->bank_name ? priv->bank_name : "",
500                        offset, gpio_function[func]);
501         if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
502             func == GPIOF_UNUSED) {
503                 const char *label;
504                 bool used;
505
506                 ret = ops->get_value(dev, offset);
507                 if (ret < 0)
508                         return ret;
509                 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
510                 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
511                          ret,
512                          used ? 'x' : ' ',
513                          used ? " " : "",
514                          label ? label : "");
515         }
516
517         return 0;
518 }
519
520 int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
521 {
522         int i, ret;
523         int gpio;
524
525         for (i = 0; i < 32; i++) {
526                 gpio = gpio_num_array[i];
527                 if (gpio == -1)
528                         break;
529                 ret = gpio_requestf(gpio, fmt, i);
530                 if (ret)
531                         goto err;
532                 ret = gpio_direction_input(gpio);
533                 if (ret) {
534                         gpio_free(gpio);
535                         goto err;
536                 }
537         }
538
539         return 0;
540 err:
541         for (i--; i >= 0; i--)
542                 gpio_free(gpio_num_array[i]);
543
544         return ret;
545 }
546
547 /*
548  * get a number comprised of multiple GPIO values. gpio_num_array points to
549  * the array of gpio pin numbers to scan, terminated by -1.
550  */
551 int gpio_get_values_as_int(const int *gpio_list)
552 {
553         int gpio;
554         unsigned bitmask = 1;
555         unsigned vector = 0;
556         int ret;
557
558         while (bitmask &&
559                ((gpio = *gpio_list++) != -1)) {
560                 ret = gpio_get_value(gpio);
561                 if (ret < 0)
562                         return ret;
563                 else if (ret)
564                         vector |= bitmask;
565                 bitmask <<= 1;
566         }
567
568         return vector;
569 }
570
571 static int _gpio_request_by_name_nodev(const void *blob, int node,
572                                        const char *list_name, int index,
573                                        struct gpio_desc *desc, int flags,
574                                        bool add_index)
575 {
576         struct fdtdec_phandle_args args;
577         int ret;
578
579         desc->dev = NULL;
580         desc->offset = 0;
581         ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
582                                              "#gpio-cells", 0, index, &args);
583         if (ret) {
584                 debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
585                 goto err;
586         }
587
588         ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
589                                              &desc->dev);
590         if (ret) {
591                 debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
592                 goto err;
593         }
594         ret = gpio_find_and_xlate(desc, &args);
595         if (ret) {
596                 debug("%s: gpio_find_and_xlate failed\n", __func__);
597                 goto err;
598         }
599         ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
600                                fdt_get_name(blob, node, NULL),
601                                list_name, index);
602         if (ret) {
603                 debug("%s: dm_gpio_requestf failed\n", __func__);
604                 goto err;
605         }
606         ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
607         if (ret) {
608                 debug("%s: dm_gpio_set_dir failed\n", __func__);
609                 goto err;
610         }
611
612         return 0;
613 err:
614         debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
615               __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
616         return ret;
617 }
618
619 int gpio_request_by_name_nodev(const void *blob, int node,
620                                const char *list_name, int index,
621                                struct gpio_desc *desc, int flags)
622 {
623         return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
624                                            flags, index > 0);
625 }
626
627 int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
628                          struct gpio_desc *desc, int flags)
629 {
630         /*
631          * This isn't ideal since we don't use dev->name in the debug()
632          * calls in gpio_request_by_name(), but we can do this until
633          * gpio_request_by_name_nodev() can be dropped.
634          */
635         return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
636                                           list_name, index, desc, flags);
637 }
638
639 int gpio_request_list_by_name_nodev(const void *blob, int node,
640                                     const char *list_name,
641                                     struct gpio_desc *desc, int max_count,
642                                     int flags)
643 {
644         int count;
645         int ret;
646
647         for (count = 0; count < max_count; count++) {
648                 ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
649                                                   &desc[count], flags, true);
650                 if (ret == -ENOENT)
651                         break;
652                 else if (ret)
653                         goto err;
654         }
655
656         /* We ran out of GPIOs in the list */
657         return count;
658
659 err:
660         gpio_free_list_nodev(desc, count - 1);
661
662         return ret;
663 }
664
665 int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
666                               struct gpio_desc *desc, int max_count,
667                               int flags)
668 {
669         /*
670          * This isn't ideal since we don't use dev->name in the debug()
671          * calls in gpio_request_by_name(), but we can do this until
672          * gpio_request_list_by_name_nodev() can be dropped.
673          */
674         return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
675                                                list_name, desc, max_count,
676                                                flags);
677 }
678
679 int gpio_get_list_count(struct udevice *dev, const char *list_name)
680 {
681         int ret;
682
683         ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
684                                              list_name, "#gpio-cells", 0, -1,
685                                              NULL);
686         if (ret) {
687                 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
688                       __func__, dev->name, list_name, ret);
689         }
690
691         return ret;
692 }
693
694 int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
695 {
696         /* For now, we don't do any checking of dev */
697         return _dm_gpio_free(desc->dev, desc->offset);
698 }
699
700 int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
701 {
702         int i;
703
704         /* For now, we don't do any checking of dev */
705         for (i = 0; i < count; i++)
706                 dm_gpio_free(dev, &desc[i]);
707
708         return 0;
709 }
710
711 int gpio_free_list_nodev(struct gpio_desc *desc, int count)
712 {
713         return gpio_free_list(NULL, desc, count);
714 }
715
716 /* We need to renumber the GPIOs when any driver is probed/removed */
717 static int gpio_renumber(struct udevice *removed_dev)
718 {
719         struct gpio_dev_priv *uc_priv;
720         struct udevice *dev;
721         struct uclass *uc;
722         unsigned base;
723         int ret;
724
725         ret = uclass_get(UCLASS_GPIO, &uc);
726         if (ret)
727                 return ret;
728
729         /* Ensure that we have a base for each bank */
730         base = 0;
731         uclass_foreach_dev(dev, uc) {
732                 if (device_active(dev) && dev != removed_dev) {
733                         uc_priv = dev_get_uclass_priv(dev);
734                         uc_priv->gpio_base = base;
735                         base += uc_priv->gpio_count;
736                 }
737         }
738
739         return 0;
740 }
741
742 int gpio_get_number(struct gpio_desc *desc)
743 {
744         struct udevice *dev = desc->dev;
745         struct gpio_dev_priv *uc_priv;
746
747         if (!dev)
748                 return -1;
749         uc_priv = dev->uclass_priv;
750
751         return uc_priv->gpio_base + desc->offset;
752 }
753
754 static int gpio_post_probe(struct udevice *dev)
755 {
756         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
757
758         uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
759         if (!uc_priv->name)
760                 return -ENOMEM;
761
762         return gpio_renumber(NULL);
763 }
764
765 static int gpio_pre_remove(struct udevice *dev)
766 {
767         struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
768         int i;
769
770         for (i = 0; i < uc_priv->gpio_count; i++) {
771                 if (uc_priv->name[i])
772                         free(uc_priv->name[i]);
773         }
774         free(uc_priv->name);
775
776         return gpio_renumber(dev);
777 }
778
779 UCLASS_DRIVER(gpio) = {
780         .id             = UCLASS_GPIO,
781         .name           = "gpio",
782         .flags          = DM_UC_FLAG_SEQ_ALIAS,
783         .post_probe     = gpio_post_probe,
784         .pre_remove     = gpio_pre_remove,
785         .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv),
786 };