]> Git Repo - u-boot.git/blame - drivers/gpio/gpio-uclass.c
Merge tag 'dm-pull-14dec20' of git://git.denx.de/u-boot-dm into next
[u-boot.git] / drivers / gpio / gpio-uclass.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
96495d90
SG
2/*
3 * Copyright (c) 2013 Google, Inc
96495d90
SG
4 */
5
6#include <common.h>
7#include <dm.h>
f7ae49fc 8#include <log.h>
d4b722e3
JJH
9#include <dm/devres.h>
10#include <dm/device_compat.h>
5fc7cf8c
HS
11#include <dm/device-internal.h>
12#include <dm/lists.h>
13#include <dm/uclass-internal.h>
6c880b77 14#include <dt-bindings/gpio/gpio.h>
96495d90 15#include <errno.h>
0dac4d51 16#include <fdtdec.h>
b892d127 17#include <malloc.h>
2912686c 18#include <acpi/acpi_device.h>
96495d90 19#include <asm/gpio.h>
f7ae49fc 20#include <dm/device_compat.h>
84b8bf6d 21#include <linux/bug.h>
fe1ef503 22#include <linux/ctype.h>
96495d90 23
3669e0e7
SG
24DECLARE_GLOBAL_DATA_PTR;
25
9f2b066c
PD
26/**
27 * gpio_desc_init() - Initialize the GPIO descriptor
28 *
29 * @desc: GPIO descriptor to initialize
30 * @dev: GPIO device
31 * @offset: Offset of device GPIO
32 */
33static void gpio_desc_init(struct gpio_desc *desc,
34 struct udevice *dev,
35 uint offset)
36{
37 desc->dev = dev;
38 desc->offset = offset;
39 desc->flags = 0;
40}
41
96495d90
SG
42/**
43 * gpio_to_device() - Convert global GPIO number to device, number
96495d90
SG
44 *
45 * Convert the GPIO number to an entry in the list of GPIOs
46 * or GPIO blocks registered with the GPIO controller. Returns
47 * entry on success, NULL on error.
ae7123f8
SG
48 *
49 * @gpio: The numeric representation of the GPIO
50 * @desc: Returns description (desc->flags will always be 0)
51 * @return 0 if found, -ENOENT if not found
96495d90 52 */
ae7123f8 53static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
96495d90
SG
54{
55 struct gpio_dev_priv *uc_priv;
54c5d08a 56 struct udevice *dev;
96495d90
SG
57 int ret;
58
59 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
60 dev;
61 ret = uclass_next_device(&dev)) {
e564f054 62 uc_priv = dev_get_uclass_priv(dev);
96495d90
SG
63 if (gpio >= uc_priv->gpio_base &&
64 gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
9f2b066c 65 gpio_desc_init(desc, dev, gpio - uc_priv->gpio_base);
96495d90
SG
66 return 0;
67 }
68 }
69
70 /* No such GPIO */
ae7123f8 71 return ret ? ret : -ENOENT;
96495d90
SG
72}
73
2bd261dd
HS
74#if CONFIG_IS_ENABLED(DM_GPIO_LOOKUP_LABEL)
75/**
76 * dm_gpio_lookup_label() - look for name in gpio device
77 *
78 * search in uc_priv, if there is a gpio with labelname same
79 * as name.
80 *
81 * @name: name which is searched
82 * @uc_priv: gpio_dev_priv pointer.
83 * @offset: gpio offset within the device
84 * @return: 0 if found, -ENOENT if not.
85 */
86static int dm_gpio_lookup_label(const char *name,
87 struct gpio_dev_priv *uc_priv, ulong *offset)
88{
89 int len;
90 int i;
91
92 *offset = -1;
93 len = strlen(name);
94 for (i = 0; i < uc_priv->gpio_count; i++) {
95 if (!uc_priv->name[i])
96 continue;
97 if (!strncmp(name, uc_priv->name[i], len)) {
98 *offset = i;
99 return 0;
100 }
101 }
102 return -ENOENT;
103}
104#else
105static int
106dm_gpio_lookup_label(const char *name, struct gpio_dev_priv *uc_priv,
107 ulong *offset)
108{
109 return -ENOENT;
110}
111#endif
112
32ec1598 113int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
96495d90 114{
fe1ef503 115 struct gpio_dev_priv *uc_priv = NULL;
54c5d08a 116 struct udevice *dev;
fe1ef503
SG
117 ulong offset;
118 int numeric;
96495d90
SG
119 int ret;
120
fe1ef503 121 numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
96495d90
SG
122 for (ret = uclass_first_device(UCLASS_GPIO, &dev);
123 dev;
124 ret = uclass_next_device(&dev)) {
96495d90
SG
125 int len;
126
e564f054 127 uc_priv = dev_get_uclass_priv(dev);
fe1ef503
SG
128 if (numeric != -1) {
129 offset = numeric - uc_priv->gpio_base;
130 /* Allow GPIOs to be numbered from 0 */
75897910 131 if (offset < uc_priv->gpio_count)
fe1ef503
SG
132 break;
133 }
134
96495d90
SG
135 len = uc_priv->bank_name ? strlen(uc_priv->bank_name) : 0;
136
939cda5b 137 if (!strncasecmp(name, uc_priv->bank_name, len)) {
fe1ef503
SG
138 if (!strict_strtoul(name + len, 10, &offset))
139 break;
96495d90 140 }
2bd261dd
HS
141
142 /*
143 * if we did not found a gpio through its bank
144 * name, we search for a valid gpio label.
145 */
146 if (!dm_gpio_lookup_label(name, uc_priv, &offset))
147 break;
96495d90
SG
148 }
149
fe1ef503
SG
150 if (!dev)
151 return ret ? ret : -EINVAL;
152
9f2b066c 153 gpio_desc_init(desc, dev, offset);
32ec1598
SG
154
155 return 0;
156}
157
158int gpio_lookup_name(const char *name, struct udevice **devp,
159 unsigned int *offsetp, unsigned int *gpiop)
160{
161 struct gpio_desc desc;
162 int ret;
163
fe1ef503 164 if (devp)
32ec1598
SG
165 *devp = NULL;
166 ret = dm_gpio_lookup_name(name, &desc);
167 if (ret)
168 return ret;
169
170 if (devp)
171 *devp = desc.dev;
fe1ef503 172 if (offsetp)
32ec1598
SG
173 *offsetp = desc.offset;
174 if (gpiop) {
175 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
176
177 *gpiop = uc_priv->gpio_base + desc.offset;
178 }
fe1ef503
SG
179
180 return 0;
96495d90
SG
181}
182
3a57123e
SG
183int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
184 struct ofnode_phandle_args *args)
6c880b77
EN
185{
186 if (args->args_count < 1)
187 return -EINVAL;
188
189 desc->offset = args->args[0];
190
191 if (args->args_count < 2)
192 return 0;
193
695e5fd5 194 desc->flags = 0;
6c880b77 195 if (args->args[1] & GPIO_ACTIVE_LOW)
695e5fd5 196 desc->flags |= GPIOD_ACTIVE_LOW;
6c880b77 197
477ca57b
PD
198 /*
199 * need to test 2 bits for gpio output binding:
200 * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4)
201 * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0)
202 */
203 if (args->args[1] & GPIO_SINGLE_ENDED) {
204 if (args->args[1] & GPIO_LINE_OPEN_DRAIN)
205 desc->flags |= GPIOD_OPEN_DRAIN;
206 else
207 desc->flags |= GPIOD_OPEN_SOURCE;
208 }
209
210 if (args->args[1] & GPIO_PULL_UP)
211 desc->flags |= GPIOD_PULL_UP;
212
213 if (args->args[1] & GPIO_PULL_DOWN)
214 desc->flags |= GPIOD_PULL_DOWN;
215
6c880b77
EN
216 return 0;
217}
218
3669e0e7 219static int gpio_find_and_xlate(struct gpio_desc *desc,
3a57123e 220 struct ofnode_phandle_args *args)
0dac4d51
SG
221{
222 struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
223
6c880b77
EN
224 if (ops->xlate)
225 return ops->xlate(desc->dev, desc, args);
0dac4d51 226 else
6c880b77 227 return gpio_xlate_offs_flags(desc->dev, desc, args);
0dac4d51
SG
228}
229
49b10cb4 230#if defined(CONFIG_GPIO_HOG)
5fc7cf8c
HS
231
232struct gpio_hog_priv {
233 struct gpio_desc gpiod;
234};
235
236struct gpio_hog_data {
237 int gpiod_flags;
238 int value;
239 u32 val[2];
240};
241
d1998a9f 242static int gpio_hog_of_to_plat(struct udevice *dev)
5fc7cf8c 243{
c69cda25 244 struct gpio_hog_data *plat = dev_get_plat(dev);
5fc7cf8c
HS
245 const char *nodename;
246 int ret;
247
248 plat->value = 0;
249 if (dev_read_bool(dev, "input")) {
250 plat->gpiod_flags = GPIOD_IS_IN;
251 } else if (dev_read_bool(dev, "output-high")) {
252 plat->value = 1;
253 plat->gpiod_flags = GPIOD_IS_OUT;
254 } else if (dev_read_bool(dev, "output-low")) {
255 plat->gpiod_flags = GPIOD_IS_OUT;
256 } else {
257 printf("%s: missing gpio-hog state.\n", __func__);
258 return -EINVAL;
259 }
260 ret = dev_read_u32_array(dev, "gpios", plat->val, 2);
261 if (ret) {
262 printf("%s: wrong gpios property, 2 values needed %d\n",
263 __func__, ret);
264 return ret;
265 }
266 nodename = dev_read_string(dev, "line-name");
49b10cb4
HS
267 if (nodename)
268 device_set_name(dev, nodename);
5fc7cf8c
HS
269
270 return 0;
271}
272
273static int gpio_hog_probe(struct udevice *dev)
274{
c69cda25 275 struct gpio_hog_data *plat = dev_get_plat(dev);
5fc7cf8c
HS
276 struct gpio_hog_priv *priv = dev_get_priv(dev);
277 int ret;
278
279 ret = gpio_dev_request_index(dev->parent, dev->name, "gpio-hog",
280 plat->val[0], plat->gpiod_flags,
281 plat->val[1], &priv->gpiod);
282 if (ret < 0) {
283 debug("%s: node %s could not get gpio.\n", __func__,
284 dev->name);
285 return ret;
286 }
49b10cb4
HS
287
288 if (plat->gpiod_flags == GPIOD_IS_OUT) {
289 ret = dm_gpio_set_value(&priv->gpiod, plat->value);
290 if (ret < 0) {
291 debug("%s: node %s could not set gpio.\n", __func__,
292 dev->name);
293 return ret;
294 }
295 }
5fc7cf8c
HS
296
297 return 0;
298}
299
300int gpio_hog_probe_all(void)
301{
302 struct udevice *dev;
303 int ret;
49b10cb4 304 int retval = 0;
5fc7cf8c
HS
305
306 for (uclass_first_device(UCLASS_NOP, &dev);
307 dev;
308 uclass_find_next_device(&dev)) {
309 if (dev->driver == DM_GET_DRIVER(gpio_hog)) {
310 ret = device_probe(dev);
49b10cb4
HS
311 if (ret) {
312 printf("Failed to probe device %s err: %d\n",
313 dev->name, ret);
314 retval = ret;
315 }
5fc7cf8c
HS
316 }
317 }
318
49b10cb4 319 return retval;
5fc7cf8c
HS
320}
321
49b10cb4 322int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
5fc7cf8c
HS
323{
324 struct udevice *dev;
325
49b10cb4 326 *desc = NULL;
5fc7cf8c
HS
327 gpio_hog_probe_all();
328 if (!uclass_get_device_by_name(UCLASS_NOP, name, &dev)) {
329 struct gpio_hog_priv *priv = dev_get_priv(dev);
330
49b10cb4
HS
331 *desc = &priv->gpiod;
332 return 0;
5fc7cf8c
HS
333 }
334
49b10cb4 335 return -ENODEV;
5fc7cf8c
HS
336}
337
338U_BOOT_DRIVER(gpio_hog) = {
339 .name = "gpio_hog",
340 .id = UCLASS_NOP,
d1998a9f 341 .of_to_plat = gpio_hog_of_to_plat,
5fc7cf8c 342 .probe = gpio_hog_probe,
41575d8e 343 .priv_auto = sizeof(struct gpio_hog_priv),
caa4daa2 344 .plat_auto = sizeof(struct gpio_hog_data),
5fc7cf8c
HS
345};
346#else
49b10cb4 347int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc)
5fc7cf8c 348{
49b10cb4 349 return 0;
5fc7cf8c
HS
350}
351#endif
352
efa677fb 353int dm_gpio_request(struct gpio_desc *desc, const char *label)
ae7123f8
SG
354{
355 struct udevice *dev = desc->dev;
356 struct gpio_dev_priv *uc_priv;
357 char *str;
358 int ret;
359
e564f054 360 uc_priv = dev_get_uclass_priv(dev);
ae7123f8
SG
361 if (uc_priv->name[desc->offset])
362 return -EBUSY;
363 str = strdup(label);
364 if (!str)
365 return -ENOMEM;
366 if (gpio_get_ops(dev)->request) {
367 ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
368 if (ret) {
369 free(str);
370 return ret;
371 }
372 }
373 uc_priv->name[desc->offset] = str;
374
375 return 0;
376}
377
3669e0e7
SG
378static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
379{
27084c03 380#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
3669e0e7
SG
381 va_list args;
382 char buf[40];
383
384 va_start(args, fmt);
385 vscnprintf(buf, sizeof(buf), fmt, args);
386 va_end(args);
387 return dm_gpio_request(desc, buf);
4dc5259a
SG
388#else
389 return dm_gpio_request(desc, fmt);
390#endif
3669e0e7
SG
391}
392
96495d90
SG
393/**
394 * gpio_request() - [COMPAT] Request GPIO
395 * gpio: GPIO number
396 * label: Name for the requested GPIO
397 *
b892d127
SG
398 * The label is copied and allocated so the caller does not need to keep
399 * the pointer around.
400 *
96495d90
SG
401 * This function implements the API that's compatible with current
402 * GPIO API used in U-Boot. The request is forwarded to particular
403 * GPIO driver. Returns 0 on success, negative value on error.
404 */
405int gpio_request(unsigned gpio, const char *label)
406{
ae7123f8 407 struct gpio_desc desc;
96495d90
SG
408 int ret;
409
ae7123f8 410 ret = gpio_to_device(gpio, &desc);
96495d90
SG
411 if (ret)
412 return ret;
413
ae7123f8 414 return dm_gpio_request(&desc, label);
96495d90
SG
415}
416
d44f597b
SG
417/**
418 * gpio_requestf() - [COMPAT] Request GPIO
419 * @gpio: GPIO number
420 * @fmt: Format string for the requested GPIO
421 * @...: Arguments for the printf() format string
422 *
423 * This function implements the API that's compatible with current
424 * GPIO API used in U-Boot. The request is forwarded to particular
425 * GPIO driver. Returns 0 on success, negative value on error.
426 */
427int gpio_requestf(unsigned gpio, const char *fmt, ...)
428{
27084c03 429#if !defined(CONFIG_SPL_BUILD) || !CONFIG_IS_ENABLED(USE_TINY_PRINTF)
d44f597b
SG
430 va_list args;
431 char buf[40];
432
433 va_start(args, fmt);
434 vscnprintf(buf, sizeof(buf), fmt, args);
435 va_end(args);
436 return gpio_request(gpio, buf);
4dc5259a
SG
437#else
438 return gpio_request(gpio, fmt);
439#endif
d44f597b
SG
440}
441
ae7123f8 442int _dm_gpio_free(struct udevice *dev, uint offset)
96495d90 443{
b892d127 444 struct gpio_dev_priv *uc_priv;
96495d90
SG
445 int ret;
446
e564f054 447 uc_priv = dev_get_uclass_priv(dev);
b892d127
SG
448 if (!uc_priv->name[offset])
449 return -ENXIO;
093152f2
SG
450 if (gpio_get_ops(dev)->rfree) {
451 ret = gpio_get_ops(dev)->rfree(dev, offset);
b892d127
SG
452 if (ret)
453 return ret;
454 }
455
456 free(uc_priv->name[offset]);
457 uc_priv->name[offset] = NULL;
458
459 return 0;
460}
461
ae7123f8
SG
462/**
463 * gpio_free() - [COMPAT] Relinquish GPIO
464 * gpio: GPIO number
465 *
466 * This function implements the API that's compatible with current
467 * GPIO API used in U-Boot. The request is forwarded to particular
468 * GPIO driver. Returns 0 on success, negative value on error.
469 */
470int gpio_free(unsigned gpio)
b892d127 471{
ae7123f8
SG
472 struct gpio_desc desc;
473 int ret;
474
475 ret = gpio_to_device(gpio, &desc);
476 if (ret)
477 return ret;
478
479 return _dm_gpio_free(desc.dev, desc.offset);
480}
b892d127 481
17c43f1a 482static int check_reserved(const struct gpio_desc *desc, const char *func)
ae7123f8 483{
eca48665
SG
484 struct gpio_dev_priv *uc_priv;
485
486 if (!dm_gpio_is_valid(desc))
487 return -ENOENT;
ae7123f8 488
eca48665 489 uc_priv = dev_get_uclass_priv(desc->dev);
ae7123f8 490 if (!uc_priv->name[desc->offset]) {
b892d127 491 printf("%s: %s: error: gpio %s%d not reserved\n",
ae7123f8
SG
492 desc->dev->name, func,
493 uc_priv->bank_name ? uc_priv->bank_name : "",
494 desc->offset);
b892d127
SG
495 return -EBUSY;
496 }
497
498 return 0;
96495d90
SG
499}
500
501/**
502 * gpio_direction_input() - [COMPAT] Set GPIO direction to input
503 * gpio: GPIO number
504 *
505 * This function implements the API that's compatible with current
506 * GPIO API used in U-Boot. The request is forwarded to particular
507 * GPIO driver. Returns 0 on success, negative value on error.
508 */
509int gpio_direction_input(unsigned gpio)
510{
ae7123f8 511 struct gpio_desc desc;
96495d90
SG
512 int ret;
513
ae7123f8
SG
514 ret = gpio_to_device(gpio, &desc);
515 if (ret)
516 return ret;
517 ret = check_reserved(&desc, "dir_input");
96495d90
SG
518 if (ret)
519 return ret;
520
ae7123f8 521 return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
96495d90
SG
522}
523
524/**
525 * gpio_direction_output() - [COMPAT] Set GPIO direction to output and set value
526 * gpio: GPIO number
527 * value: Logical value to be set on the GPIO pin
528 *
529 * This function implements the API that's compatible with current
530 * GPIO API used in U-Boot. The request is forwarded to particular
531 * GPIO driver. Returns 0 on success, negative value on error.
532 */
533int gpio_direction_output(unsigned gpio, int value)
534{
ae7123f8 535 struct gpio_desc desc;
96495d90
SG
536 int ret;
537
ae7123f8
SG
538 ret = gpio_to_device(gpio, &desc);
539 if (ret)
540 return ret;
541 ret = check_reserved(&desc, "dir_output");
542 if (ret)
543 return ret;
544
545 return gpio_get_ops(desc.dev)->direction_output(desc.dev,
546 desc.offset, value);
547}
548
8a9140cd 549static int _gpio_get_value(const struct gpio_desc *desc)
ae7123f8
SG
550{
551 int value;
8a9140cd
PD
552
553 value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
554
555 return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
556}
557
558int dm_gpio_get_value(const struct gpio_desc *desc)
559{
ae7123f8
SG
560 int ret;
561
562 ret = check_reserved(desc, "get_value");
96495d90
SG
563 if (ret)
564 return ret;
565
8a9140cd 566 return _gpio_get_value(desc);
ae7123f8
SG
567}
568
17c43f1a 569int dm_gpio_set_value(const struct gpio_desc *desc, int value)
ae7123f8
SG
570{
571 int ret;
572
573 ret = check_reserved(desc, "set_value");
574 if (ret)
575 return ret;
576
577 if (desc->flags & GPIOD_ACTIVE_LOW)
578 value = !value;
47bd533e
NA
579
580 /*
581 * Emulate open drain by not actively driving the line high or
582 * Emulate open source by not actively driving the line low
583 */
584 if ((desc->flags & GPIOD_OPEN_DRAIN && value) ||
585 (desc->flags & GPIOD_OPEN_SOURCE && !value))
586 return gpio_get_ops(desc->dev)->direction_input(desc->dev,
587 desc->offset);
588 else if (desc->flags & GPIOD_OPEN_DRAIN ||
589 desc->flags & GPIOD_OPEN_SOURCE)
590 return gpio_get_ops(desc->dev)->direction_output(desc->dev,
591 desc->offset,
592 value);
593
ae7123f8
SG
594 gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
595 return 0;
596}
597
4292fb16
PD
598/* check dir flags invalid configuration */
599static int check_dir_flags(ulong flags)
600{
601 if ((flags & GPIOD_IS_OUT) && (flags & GPIOD_IS_IN)) {
602 log_debug("%s: flags 0x%lx has GPIOD_IS_OUT and GPIOD_IS_IN\n",
603 __func__, flags);
477ca57b
PD
604 return -EINVAL;
605 }
606
607 if ((flags & GPIOD_PULL_UP) && (flags & GPIOD_PULL_DOWN)) {
608 log_debug("%s: flags 0x%lx has GPIOD_PULL_UP and GPIOD_PULL_DOWN\n",
609 __func__, flags);
610 return -EINVAL;
611 }
612
613 if ((flags & GPIOD_OPEN_DRAIN) && (flags & GPIOD_OPEN_SOURCE)) {
614 log_debug("%s: flags 0x%lx has GPIOD_OPEN_DRAIN and GPIOD_OPEN_SOURCE\n",
615 __func__, flags);
4292fb16
PD
616 return -EINVAL;
617 }
618
619 return 0;
620}
621
788ea834 622static int _dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
ae7123f8
SG
623{
624 struct udevice *dev = desc->dev;
625 struct dm_gpio_ops *ops = gpio_get_ops(dev);
4292fb16 626 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
788ea834 627 int ret = 0;
ae7123f8 628
4292fb16
PD
629 ret = check_dir_flags(flags);
630 if (ret) {
631 dev_dbg(dev,
632 "%s error: set_dir_flags for gpio %s%d has invalid dir flags 0x%lx\n",
633 desc->dev->name,
634 uc_priv->bank_name ? uc_priv->bank_name : "",
635 desc->offset, flags);
636
637 return ret;
638 }
639
8fd9daf0
PD
640 /* GPIOD_ are directly managed by driver in set_dir_flags*/
641 if (ops->set_dir_flags) {
642 ret = ops->set_dir_flags(dev, desc->offset, flags);
643 } else {
644 if (flags & GPIOD_IS_OUT) {
645 ret = ops->direction_output(dev, desc->offset,
646 GPIOD_FLAGS_OUTPUT(flags));
647 } else if (flags & GPIOD_IS_IN) {
648 ret = ops->direction_input(dev, desc->offset);
649 }
ae7123f8 650 }
788ea834 651
cd2faeba
HS
652 /* save the flags also in descriptor */
653 if (!ret)
654 desc->flags = flags;
655
788ea834
PD
656 return ret;
657}
658
659int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
660{
661 int ret;
662
663 ret = check_reserved(desc, "set_dir_flags");
ae7123f8
SG
664 if (ret)
665 return ret;
ae7123f8 666
695e5fd5
PD
667 /* combine the requested flags (for IN/OUT) and the descriptor flags */
668 flags |= desc->flags;
788ea834
PD
669 ret = _dm_gpio_set_dir_flags(desc, flags);
670
788ea834 671 return ret;
ae7123f8
SG
672}
673
674int dm_gpio_set_dir(struct gpio_desc *desc)
675{
788ea834
PD
676 int ret;
677
678 ret = check_reserved(desc, "set_dir");
679 if (ret)
680 return ret;
681
682 return _dm_gpio_set_dir_flags(desc, desc->flags);
96495d90
SG
683}
684
695e5fd5
PD
685int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags)
686{
d2c07e56
PD
687 struct udevice *dev = desc->dev;
688 int ret, value;
689 struct dm_gpio_ops *ops = gpio_get_ops(dev);
695e5fd5
PD
690 ulong dir_flags;
691
692 ret = check_reserved(desc, "get_dir_flags");
693 if (ret)
694 return ret;
695
d2c07e56
PD
696 /* GPIOD_ are directly provided by driver except GPIOD_ACTIVE_LOW */
697 if (ops->get_dir_flags) {
698 ret = ops->get_dir_flags(dev, desc->offset, &dir_flags);
699 if (ret)
700 return ret;
695e5fd5 701
d2c07e56
PD
702 /* GPIOD_ACTIVE_LOW is saved in desc->flags */
703 value = dir_flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
704 if (desc->flags & GPIOD_ACTIVE_LOW)
705 value = !value;
706 dir_flags &= ~(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE);
707 dir_flags |= (desc->flags & GPIOD_ACTIVE_LOW);
708 if (value)
709 dir_flags |= GPIOD_IS_OUT_ACTIVE;
710 } else {
711 dir_flags = desc->flags;
712 /* only GPIOD_IS_OUT_ACTIVE is provided by uclass */
713 dir_flags &= ~GPIOD_IS_OUT_ACTIVE;
714 if ((desc->flags & GPIOD_IS_OUT) && _gpio_get_value(desc))
715 dir_flags |= GPIOD_IS_OUT_ACTIVE;
716 }
695e5fd5
PD
717 *flags = dir_flags;
718
719 return 0;
720}
721
96495d90
SG
722/**
723 * gpio_get_value() - [COMPAT] Sample GPIO pin and return it's value
724 * gpio: GPIO number
725 *
726 * This function implements the API that's compatible with current
727 * GPIO API used in U-Boot. The request is forwarded to particular
728 * GPIO driver. Returns the value of the GPIO pin, or negative value
729 * on error.
730 */
731int gpio_get_value(unsigned gpio)
732{
96495d90
SG
733 int ret;
734
ae7123f8
SG
735 struct gpio_desc desc;
736
737 ret = gpio_to_device(gpio, &desc);
96495d90
SG
738 if (ret)
739 return ret;
ae7123f8 740 return dm_gpio_get_value(&desc);
96495d90
SG
741}
742
743/**
744 * gpio_set_value() - [COMPAT] Configure logical value on GPIO pin
745 * gpio: GPIO number
746 * value: Logical value to be set on the GPIO pin.
747 *
748 * This function implements the API that's compatible with current
749 * GPIO API used in U-Boot. The request is forwarded to particular
750 * GPIO driver. Returns 0 on success, negative value on error.
751 */
752int gpio_set_value(unsigned gpio, int value)
753{
ae7123f8 754 struct gpio_desc desc;
96495d90
SG
755 int ret;
756
ae7123f8 757 ret = gpio_to_device(gpio, &desc);
96495d90
SG
758 if (ret)
759 return ret;
ae7123f8 760 return dm_gpio_set_value(&desc, value);
96495d90
SG
761}
762
54c5d08a 763const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
96495d90
SG
764{
765 struct gpio_dev_priv *priv;
766
767 /* Must be called on an active device */
e564f054 768 priv = dev_get_uclass_priv(dev);
96495d90
SG
769 assert(priv);
770
771 *bit_count = priv->gpio_count;
772 return priv->bank_name;
773}
774
6449a506
SG
775static const char * const gpio_function[GPIOF_COUNT] = {
776 "input",
777 "output",
778 "unused",
779 "unknown",
780 "func",
781};
782
fb07f97d
MY
783static int get_function(struct udevice *dev, int offset, bool skip_unused,
784 const char **namep)
6449a506 785{
e564f054 786 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
6449a506
SG
787 struct dm_gpio_ops *ops = gpio_get_ops(dev);
788
789 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
790 if (!device_active(dev))
791 return -ENODEV;
792 if (offset < 0 || offset >= uc_priv->gpio_count)
793 return -EINVAL;
794 if (namep)
795 *namep = uc_priv->name[offset];
796 if (skip_unused && !uc_priv->name[offset])
797 return GPIOF_UNUSED;
798 if (ops->get_function) {
799 int ret;
800
801 ret = ops->get_function(dev, offset);
802 if (ret < 0)
803 return ret;
804 if (ret >= ARRAY_SIZE(gpio_function))
805 return -ENODATA;
806 return ret;
807 }
808
809 return GPIOF_UNKNOWN;
810}
811
812int gpio_get_function(struct udevice *dev, int offset, const char **namep)
813{
814 return get_function(dev, offset, true, namep);
815}
816
817int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep)
818{
819 return get_function(dev, offset, false, namep);
820}
821
0757535a
SG
822int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
823{
824 struct dm_gpio_ops *ops = gpio_get_ops(dev);
825 struct gpio_dev_priv *priv;
826 char *str = buf;
827 int func;
828 int ret;
829 int len;
830
831 BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
832
833 *buf = 0;
e564f054 834 priv = dev_get_uclass_priv(dev);
0757535a
SG
835 ret = gpio_get_raw_function(dev, offset, NULL);
836 if (ret < 0)
837 return ret;
838 func = ret;
839 len = snprintf(str, buffsize, "%s%d: %s",
840 priv->bank_name ? priv->bank_name : "",
841 offset, gpio_function[func]);
842 if (func == GPIOF_INPUT || func == GPIOF_OUTPUT ||
843 func == GPIOF_UNUSED) {
844 const char *label;
845 bool used;
846
847 ret = ops->get_value(dev, offset);
848 if (ret < 0)
849 return ret;
850 used = gpio_get_function(dev, offset, &label) != GPIOF_UNUSED;
851 snprintf(str + len, buffsize - len, ": %d [%c]%s%s",
852 ret,
853 used ? 'x' : ' ',
854 used ? " " : "",
855 label ? label : "");
856 }
857
858 return 0;
859}
860
2912686c
SG
861#if CONFIG_IS_ENABLED(ACPIGEN)
862int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio)
863{
864 struct dm_gpio_ops *ops;
865
866 memset(gpio, '\0', sizeof(*gpio));
867 if (!dm_gpio_is_valid(desc)) {
868 /* Indicate that the GPIO is not valid */
869 gpio->pin_count = 0;
870 gpio->pins[0] = 0;
871 return -EINVAL;
872 }
873
874 ops = gpio_get_ops(desc->dev);
875 if (!ops->get_acpi)
876 return -ENOSYS;
877
878 return ops->get_acpi(desc, gpio);
879}
880#endif
881
962f5caf
SG
882int gpio_claim_vector(const int *gpio_num_array, const char *fmt)
883{
884 int i, ret;
885 int gpio;
886
887 for (i = 0; i < 32; i++) {
888 gpio = gpio_num_array[i];
889 if (gpio == -1)
890 break;
891 ret = gpio_requestf(gpio, fmt, i);
892 if (ret)
893 goto err;
894 ret = gpio_direction_input(gpio);
895 if (ret) {
896 gpio_free(gpio);
897 goto err;
898 }
899 }
900
901 return 0;
902err:
903 for (i--; i >= 0; i--)
904 gpio_free(gpio_num_array[i]);
905
906 return ret;
907}
908
e5901c94
SG
909/*
910 * get a number comprised of multiple GPIO values. gpio_num_array points to
911 * the array of gpio pin numbers to scan, terminated by -1.
912 */
962f5caf 913int gpio_get_values_as_int(const int *gpio_list)
e5901c94
SG
914{
915 int gpio;
916 unsigned bitmask = 1;
917 unsigned vector = 0;
962f5caf 918 int ret;
e5901c94
SG
919
920 while (bitmask &&
962f5caf
SG
921 ((gpio = *gpio_list++) != -1)) {
922 ret = gpio_get_value(gpio);
923 if (ret < 0)
924 return ret;
925 else if (ret)
e5901c94
SG
926 vector |= bitmask;
927 bitmask <<= 1;
928 }
962f5caf 929
e5901c94
SG
930 return vector;
931}
932
17c43f1a 933int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count)
bbf24780
SG
934{
935 unsigned bitmask = 1;
936 unsigned vector = 0;
937 int ret, i;
938
939 for (i = 0; i < count; i++) {
940 ret = dm_gpio_get_value(&desc_list[i]);
941 if (ret < 0)
942 return ret;
943 else if (ret)
944 vector |= bitmask;
945 bitmask <<= 1;
946 }
947
948 return vector;
949}
950
49b10cb4
HS
951/**
952 * gpio_request_tail: common work for requesting a gpio.
953 *
954 * ret: return value from previous work in function which calls
955 * this function.
956 * This seems bogus (why calling this function instead not
957 * calling it and end caller function instead?).
958 * Because on error in caller function we want to set some
959 * default values in gpio desc and have a common error
960 * debug message, which provides this function.
961 * nodename: Name of node for which gpio gets requested
962 * used for gpio label name.
963 * args: pointer to output arguments structure
964 * list_name: Name of GPIO list
965 * used for gpio label name.
966 * index: gpio index in gpio list
967 * used for gpio label name.
968 * desc: pointer to gpio descriptor, filled from this
969 * function.
970 * flags: gpio flags to use.
971 * add_index: should index added to gpio label name
972 * gpio_dev: pointer to gpio device from which the gpio
973 * will be requested. If NULL try to get the
974 * gpio device with uclass_get_device_by_ofnode()
975 *
976 * return: In error case this function sets default values in
977 * gpio descriptor, also emmits a debug message.
978 * On success it returns 0 else the error code from
979 * function calls, or the error code passed through
980 * ret to this function.
981 *
982 */
5fc7cf8c 983static int gpio_request_tail(int ret, const char *nodename,
3a57123e
SG
984 struct ofnode_phandle_args *args,
985 const char *list_name, int index,
5fc7cf8c 986 struct gpio_desc *desc, int flags,
49b10cb4 987 bool add_index, struct udevice *gpio_dev)
3669e0e7 988{
9f2b066c 989 gpio_desc_init(desc, gpio_dev, 0);
3a57123e 990 if (ret)
3669e0e7 991 goto err;
3669e0e7 992
5fc7cf8c
HS
993 if (!desc->dev) {
994 ret = uclass_get_device_by_ofnode(UCLASS_GPIO, args->node,
995 &desc->dev);
996 if (ret) {
49b10cb4
HS
997 debug("%s: uclass_get_device_by_ofnode failed\n",
998 __func__);
5fc7cf8c
HS
999 goto err;
1000 }
3669e0e7 1001 }
3a57123e 1002 ret = gpio_find_and_xlate(desc, args);
3669e0e7
SG
1003 if (ret) {
1004 debug("%s: gpio_find_and_xlate failed\n", __func__);
1005 goto err;
1006 }
1007 ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
5fc7cf8c 1008 nodename, list_name, index);
3669e0e7
SG
1009 if (ret) {
1010 debug("%s: dm_gpio_requestf failed\n", __func__);
1011 goto err;
1012 }
695e5fd5 1013 ret = dm_gpio_set_dir_flags(desc, flags);
3669e0e7
SG
1014 if (ret) {
1015 debug("%s: dm_gpio_set_dir failed\n", __func__);
1016 goto err;
1017 }
1018
1019 return 0;
1020err:
1021 debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
5fc7cf8c 1022 __func__, nodename, list_name, index, ret);
3669e0e7
SG
1023 return ret;
1024}
1025
150c5afe
SG
1026static int _gpio_request_by_name_nodev(ofnode node, const char *list_name,
1027 int index, struct gpio_desc *desc,
1028 int flags, bool add_index)
3a57123e
SG
1029{
1030 struct ofnode_phandle_args args;
1031 int ret;
1032
150c5afe
SG
1033 ret = ofnode_parse_phandle_with_args(node, list_name, "#gpio-cells", 0,
1034 index, &args);
3a57123e 1035
5fc7cf8c
HS
1036 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1037 index, desc, flags, add_index, NULL);
3a57123e
SG
1038}
1039
150c5afe 1040int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
3669e0e7
SG
1041 struct gpio_desc *desc, int flags)
1042{
150c5afe
SG
1043 return _gpio_request_by_name_nodev(node, list_name, index, desc, flags,
1044 index > 0);
3669e0e7
SG
1045}
1046
150c5afe 1047int gpio_request_by_name(struct udevice *dev, const char *list_name, int index,
3669e0e7
SG
1048 struct gpio_desc *desc, int flags)
1049{
150c5afe 1050 struct ofnode_phandle_args args;
5fc7cf8c 1051 ofnode node;
150c5afe
SG
1052 int ret;
1053
1054 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0,
1055 index, &args);
5fc7cf8c
HS
1056 node = dev_ofnode(dev);
1057 return gpio_request_tail(ret, ofnode_get_name(node), &args, list_name,
1058 index, desc, flags, index > 0, NULL);
3669e0e7
SG
1059}
1060
150c5afe 1061int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
3669e0e7
SG
1062 struct gpio_desc *desc, int max_count,
1063 int flags)
1064{
1065 int count;
1066 int ret;
1067
2984e7a1 1068 for (count = 0; count < max_count; count++) {
150c5afe 1069 ret = _gpio_request_by_name_nodev(node, list_name, count,
3669e0e7
SG
1070 &desc[count], flags, true);
1071 if (ret == -ENOENT)
1072 break;
1073 else if (ret)
1074 goto err;
1075 }
1076
1077 /* We ran out of GPIOs in the list */
1078 return count;
1079
1080err:
1081 gpio_free_list_nodev(desc, count - 1);
1082
1083 return ret;
1084}
1085
1086int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
1087 struct gpio_desc *desc, int max_count,
1088 int flags)
1089{
1090 /*
1091 * This isn't ideal since we don't use dev->name in the debug()
1092 * calls in gpio_request_by_name(), but we can do this until
1093 * gpio_request_list_by_name_nodev() can be dropped.
1094 */
150c5afe
SG
1095 return gpio_request_list_by_name_nodev(dev_ofnode(dev), list_name, desc,
1096 max_count, flags);
3669e0e7
SG
1097}
1098
1099int gpio_get_list_count(struct udevice *dev, const char *list_name)
1100{
1101 int ret;
1102
85582171
PD
1103 ret = dev_read_phandle_with_args(dev, list_name, "#gpio-cells", 0, -1,
1104 NULL);
3669e0e7
SG
1105 if (ret) {
1106 debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
1107 __func__, dev->name, list_name, ret);
1108 }
1109
1110 return ret;
1111}
1112
1113int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
1114{
1115 /* For now, we don't do any checking of dev */
1116 return _dm_gpio_free(desc->dev, desc->offset);
1117}
1118
1119int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
1120{
1121 int i;
1122
1123 /* For now, we don't do any checking of dev */
1124 for (i = 0; i < count; i++)
1125 dm_gpio_free(dev, &desc[i]);
1126
1127 return 0;
1128}
1129
1130int gpio_free_list_nodev(struct gpio_desc *desc, int count)
1131{
1132 return gpio_free_list(NULL, desc, count);
1133}
1134
96495d90 1135/* We need to renumber the GPIOs when any driver is probed/removed */
b892d127 1136static int gpio_renumber(struct udevice *removed_dev)
96495d90
SG
1137{
1138 struct gpio_dev_priv *uc_priv;
54c5d08a 1139 struct udevice *dev;
96495d90
SG
1140 struct uclass *uc;
1141 unsigned base;
1142 int ret;
1143
1144 ret = uclass_get(UCLASS_GPIO, &uc);
1145 if (ret)
1146 return ret;
1147
1148 /* Ensure that we have a base for each bank */
1149 base = 0;
1150 uclass_foreach_dev(dev, uc) {
b892d127 1151 if (device_active(dev) && dev != removed_dev) {
e564f054 1152 uc_priv = dev_get_uclass_priv(dev);
96495d90
SG
1153 uc_priv->gpio_base = base;
1154 base += uc_priv->gpio_count;
1155 }
1156 }
1157
1158 return 0;
1159}
1160
17c43f1a 1161int gpio_get_number(const struct gpio_desc *desc)
56a71f89
SG
1162{
1163 struct udevice *dev = desc->dev;
1164 struct gpio_dev_priv *uc_priv;
1165
1166 if (!dev)
1167 return -1;
1168 uc_priv = dev->uclass_priv;
1169
1170 return uc_priv->gpio_base + desc->offset;
1171}
1172
54c5d08a 1173static int gpio_post_probe(struct udevice *dev)
96495d90 1174{
e564f054 1175 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
b892d127
SG
1176
1177 uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
1178 if (!uc_priv->name)
1179 return -ENOMEM;
1180
1181 return gpio_renumber(NULL);
96495d90
SG
1182}
1183
54c5d08a 1184static int gpio_pre_remove(struct udevice *dev)
96495d90 1185{
e564f054 1186 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
b892d127
SG
1187 int i;
1188
1189 for (i = 0; i < uc_priv->gpio_count; i++) {
1190 if (uc_priv->name[i])
1191 free(uc_priv->name[i]);
1192 }
1193 free(uc_priv->name);
1194
1195 return gpio_renumber(dev);
96495d90
SG
1196}
1197
5fc7cf8c
HS
1198int gpio_dev_request_index(struct udevice *dev, const char *nodename,
1199 char *list_name, int index, int flags,
1200 int dtflags, struct gpio_desc *desc)
1201{
1202 struct ofnode_phandle_args args;
1203
1204 args.node = ofnode_null();
1205 args.args_count = 2;
1206 args.args[0] = index;
1207 args.args[1] = dtflags;
1208
1209 return gpio_request_tail(0, nodename, &args, list_name, index, desc,
1210 flags, 0, dev);
1211}
1212
d4b722e3
JJH
1213static void devm_gpiod_release(struct udevice *dev, void *res)
1214{
1215 dm_gpio_free(dev, res);
1216}
1217
1218static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
1219{
1220 return res == data;
1221}
1222
1223struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
1224 unsigned int index, int flags)
1225{
1226 int rc;
1227 struct gpio_desc *desc;
1228 char *propname;
1229 static const char suffix[] = "-gpios";
1230
1231 propname = malloc(strlen(id) + sizeof(suffix));
1232 if (!propname) {
1233 rc = -ENOMEM;
1234 goto end;
1235 }
1236
1237 strcpy(propname, id);
1238 strcat(propname, suffix);
1239
1240 desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
1241 __GFP_ZERO);
1242 if (unlikely(!desc)) {
1243 rc = -ENOMEM;
1244 goto end;
1245 }
1246
1247 rc = gpio_request_by_name(dev, propname, index, desc, flags);
1248
1249end:
1250 if (propname)
1251 free(propname);
1252
1253 if (rc)
1254 return ERR_PTR(rc);
1255
1256 devres_add(dev, desc);
1257
1258 return desc;
1259}
1260
1261struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
1262 const char *id,
1263 unsigned int index,
1264 int flags)
1265{
1266 struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
1267
1268 if (IS_ERR(desc))
1269 return NULL;
1270
1271 return desc;
1272}
1273
1274void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
1275{
1276 int rc;
1277
1278 rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
1279 WARN_ON(rc);
1280}
1281
1b4c2aa2
MS
1282static int gpio_post_bind(struct udevice *dev)
1283{
5fc7cf8c
HS
1284 struct udevice *child;
1285 ofnode node;
5fc7cf8c 1286
1b4c2aa2
MS
1287#if defined(CONFIG_NEEDS_MANUAL_RELOC)
1288 struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev);
1289 static int reloc_done;
1290
1291 if (!reloc_done) {
1292 if (ops->request)
1293 ops->request += gd->reloc_off;
093152f2
SG
1294 if (ops->rfree)
1295 ops->rfree += gd->reloc_off;
1b4c2aa2
MS
1296 if (ops->direction_input)
1297 ops->direction_input += gd->reloc_off;
1298 if (ops->direction_output)
1299 ops->direction_output += gd->reloc_off;
1300 if (ops->get_value)
1301 ops->get_value += gd->reloc_off;
1302 if (ops->set_value)
1303 ops->set_value += gd->reloc_off;
1b4c2aa2
MS
1304 if (ops->get_function)
1305 ops->get_function += gd->reloc_off;
1306 if (ops->xlate)
1307 ops->xlate += gd->reloc_off;
8fd9daf0
PD
1308 if (ops->set_dir_flags)
1309 ops->set_dir_flags += gd->reloc_off;
d2c07e56
PD
1310 if (ops->get_dir_flags)
1311 ops->get_dir_flags += gd->reloc_off;
1b4c2aa2
MS
1312
1313 reloc_done++;
1314 }
1315#endif
5fc7cf8c 1316
49b10cb4
HS
1317 if (IS_ENABLED(CONFIG_GPIO_HOG)) {
1318 dev_for_each_subnode(node, dev) {
1319 if (ofnode_read_bool(node, "gpio-hog")) {
1320 const char *name = ofnode_get_name(node);
1321 int ret;
1322
1323 ret = device_bind_driver_to_node(dev,
1324 "gpio_hog",
1325 name, node,
1326 &child);
1327 if (ret)
1328 return ret;
1329 }
5fc7cf8c
HS
1330 }
1331 }
1b4c2aa2
MS
1332 return 0;
1333}
1334
96495d90
SG
1335UCLASS_DRIVER(gpio) = {
1336 .id = UCLASS_GPIO,
1337 .name = "gpio",
ae89bb0d 1338 .flags = DM_UC_FLAG_SEQ_ALIAS,
96495d90 1339 .post_probe = gpio_post_probe,
1b4c2aa2 1340 .post_bind = gpio_post_bind,
96495d90 1341 .pre_remove = gpio_pre_remove,
41575d8e 1342 .per_device_auto = sizeof(struct gpio_dev_priv),
96495d90 1343};
This page took 0.442348 seconds and 4 git commands to generate.