Coverage Report

Created: 2026-03-11 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/u-boot/test/dm/gpio.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
 * Copyright (C) 2013 Google, Inc
4
 */
5
6
#include <fdtdec.h>
7
#include <dm.h>
8
#include <log.h>
9
#include <malloc.h>
10
#include <acpi/acpi_device.h>
11
#include <asm/gpio.h>
12
#include <dm/device-internal.h>
13
#include <dm/root.h>
14
#include <dm/test.h>
15
#include <dm/util.h>
16
#include <test/test.h>
17
#include <test/ut.h>
18
19
/* Test that sandbox GPIOs work correctly */
20
static int dm_test_gpio(struct unit_test_state *uts)
21
0
{
22
0
  unsigned int offset, gpio;
23
0
  struct dm_gpio_ops *ops;
24
0
  struct udevice *dev;
25
0
  struct gpio_desc *desc;
26
0
  const char *name;
27
0
  int offset_count;
28
0
  char buf[80];
29
30
  /*
31
   * We expect to get 4 banks. One is anonymous (just numbered) and
32
   * comes from plat. The other are named a (25 gpios),
33
   * b (10 gpios) and c (10 gpios) and come from the device tree. See
34
   * test/dm/test.dts.
35
   */
36
0
  ut_assertok(gpio_lookup_name("b4", &dev, &offset, &gpio));
37
0
  ut_asserteq_str(dev->name, "extra-gpios");
38
0
  ut_asserteq(4, offset);
39
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 25 + 4, gpio);
40
41
0
  name = gpio_get_bank_info(dev, &offset_count);
42
0
  ut_asserteq_str("b", name);
43
0
  ut_asserteq(10, offset_count);
44
45
  /* Get the operations for this device */
46
0
  ops = gpio_get_ops(dev);
47
0
  ut_assert(ops->get_function);
48
49
  /* Cannot get a value until it is reserved */
50
0
  ut_asserteq(-EBUSY, gpio_get_value(gpio + 1));
51
  /*
52
   * Now some tests that use the 'sandbox' back door. All GPIOs
53
   * should default to input, include b4 that we are using here.
54
   */
55
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
56
0
  ut_asserteq_str("b4: input: 0 [ ]", buf);
57
58
  /* Change it to an output */
59
0
  sandbox_gpio_set_direction(dev, offset, 1);
60
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
61
0
  ut_asserteq_str("b4: output: 0 [ ]", buf);
62
63
0
  sandbox_gpio_set_value(dev, offset, 1);
64
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
65
0
  ut_asserteq_str("b4: output: 1 [ ]", buf);
66
67
0
  ut_assertok(gpio_request(gpio, "testing"));
68
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
69
0
  ut_asserteq_str("b4: output: 1 [x] testing", buf);
70
71
  /* Change the value a bit */
72
0
  ut_asserteq(1, ops->get_value(dev, offset));
73
0
  ut_assertok(ops->set_value(dev, offset, 0));
74
0
  ut_asserteq(0, ops->get_value(dev, offset));
75
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
76
0
  ut_asserteq_str("b4: output: 0 [x] testing", buf);
77
0
  ut_assertok(ops->set_value(dev, offset, 1));
78
0
  ut_asserteq(1, ops->get_value(dev, offset));
79
80
  /* Make it an open drain output, and reset it */
81
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
82
0
        sandbox_gpio_get_flags(dev, offset));
83
0
  ut_assertok(ops->set_flags(dev, offset,
84
0
           GPIOD_IS_OUT | GPIOD_OPEN_DRAIN));
85
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
86
0
        sandbox_gpio_get_flags(dev, offset));
87
0
  ut_assertok(ops->set_flags(dev, offset,
88
0
           GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE));
89
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
90
0
        sandbox_gpio_get_flags(dev, offset));
91
92
  /* Make it an input */
93
0
  ut_assertok(ops->direction_input(dev, offset));
94
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
95
0
  ut_asserteq_str("b4: input: 1 [x] testing", buf);
96
0
  sandbox_gpio_set_value(dev, offset, 0);
97
0
  ut_asserteq(0, sandbox_gpio_get_value(dev, offset));
98
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
99
0
  ut_asserteq_str("b4: input: 0 [x] testing", buf);
100
101
0
  ut_assertok(gpio_free(gpio));
102
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
103
0
  ut_asserteq_str("b4: input: 0 [ ]", buf);
104
105
  /* Check the 'a' bank also */
106
0
  ut_assertok(gpio_lookup_name("a15", &dev, &offset, &gpio));
107
0
  ut_asserteq_str(dev->name, "base-gpios");
108
0
  ut_asserteq(15, offset);
109
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 15, gpio);
110
111
0
  name = gpio_get_bank_info(dev, &offset_count);
112
0
  ut_asserteq_str("a", name);
113
0
  ut_asserteq(25, offset_count);
114
115
  /* add gpio hog tests */
116
0
  ut_assertok(gpio_hog_lookup_name("hog_input_active_low", &desc));
117
0
  ut_asserteq(GPIOD_IS_IN | GPIOD_ACTIVE_LOW, desc->flags);
118
0
  ut_asserteq(10, desc->offset);
119
0
  ut_asserteq(1, dm_gpio_get_value(desc));
120
0
  ut_assertok(gpio_hog_lookup_name("hog_input_active_high", &desc));
121
0
  ut_asserteq(GPIOD_IS_IN, desc->flags);
122
0
  ut_asserteq(11, desc->offset);
123
0
  ut_asserteq(0, dm_gpio_get_value(desc));
124
0
  ut_assertok(gpio_hog_lookup_name("hog_output_low", &desc));
125
0
  ut_asserteq(GPIOD_IS_OUT, desc->flags);
126
0
  ut_asserteq(12, desc->offset);
127
0
  ut_asserteq(0, dm_gpio_get_value(desc));
128
0
  ut_assertok(dm_gpio_set_value(desc, 1));
129
0
  ut_asserteq(1, dm_gpio_get_value(desc));
130
0
  ut_assertok(gpio_hog_lookup_name("hog_output_high", &desc));
131
0
  ut_asserteq(GPIOD_IS_OUT, desc->flags);
132
0
  ut_asserteq(13, desc->offset);
133
0
  ut_asserteq(1, dm_gpio_get_value(desc));
134
0
  ut_assertok(dm_gpio_set_value(desc, 0));
135
0
  ut_asserteq(0, dm_gpio_get_value(desc));
136
137
  /* Check if lookup for labels work */
138
0
  ut_assertok(gpio_lookup_name("hog_input_active_low.gpio-hog", &dev, &offset,
139
0
             &gpio));
140
0
  ut_asserteq_str(dev->name, "base-gpios");
141
0
  ut_asserteq(10, offset);
142
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 10, gpio);
143
0
  ut_assert(gpio_lookup_name("hog_not_exist", &dev, &offset,
144
0
           &gpio));
145
146
  /* Check if lookup for gpio-line-names work */
147
0
  ut_assertok(gpio_lookup_name("factory-reset", &dev, &offset, &gpio));
148
0
  ut_asserteq_str(dev->name, "extra-gpios");
149
0
  ut_asserteq(0, offset);
150
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 25 + 0, gpio);
151
152
0
  ut_assertok(gpio_lookup_name("rtc-irq", &dev, &offset, &gpio));
153
0
  ut_asserteq_str(dev->name, "base-gpios");
154
0
  ut_asserteq(2, offset);
155
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT + 2, gpio);
156
157
0
  return 0;
158
0
}
159
DM_TEST(dm_test_gpio, UTF_SCAN_PDATA | UTF_SCAN_FDT);
160
161
/* Test that GPIO open-drain/open-source emulation works correctly */
162
static int dm_test_gpio_opendrain_opensource(struct unit_test_state *uts)
163
0
{
164
0
  struct gpio_desc desc_list[8];
165
0
  struct udevice *dev, *gpio_c;
166
0
  char buf[80];
167
168
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
169
0
  ut_asserteq_str("a-test", dev->name);
170
171
0
  ut_assertok(uclass_get_device(UCLASS_GPIO, 3, &gpio_c));
172
0
  ut_asserteq_str("pinmux-gpios", gpio_c->name);
173
174
0
  ut_asserteq(8, gpio_request_list_by_name(dev, "test3-gpios", desc_list,
175
0
             ARRAY_SIZE(desc_list), 0));
176
177
0
  ut_asserteq(true, !!device_active(gpio_c));
178
0
  ut_asserteq_ptr(gpio_c, desc_list[0].dev);
179
0
  ut_asserteq_ptr(gpio_c, desc_list[1].dev);
180
0
  ut_asserteq_ptr(gpio_c, desc_list[2].dev);
181
0
  ut_asserteq_ptr(gpio_c, desc_list[3].dev);
182
0
  ut_asserteq_ptr(gpio_c, desc_list[4].dev);
183
0
  ut_asserteq_ptr(gpio_c, desc_list[5].dev);
184
0
  ut_asserteq_ptr(gpio_c, desc_list[6].dev);
185
0
  ut_asserteq_ptr(gpio_c, desc_list[7].dev);
186
187
  /* GPIO 0 is (GPIO_OUT|GPIO_OPEN_DRAIN) */
188
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
189
0
        sandbox_gpio_get_flags(gpio_c, 0));
190
191
  /* Set it as output high */
192
0
  ut_assertok(dm_gpio_set_value(&desc_list[0], 1));
193
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN | GPIOD_IS_OUT_ACTIVE,
194
0
        sandbox_gpio_get_flags(gpio_c, 0));
195
196
  /* Set it as output low */
197
0
  ut_assertok(dm_gpio_set_value(&desc_list[0], 0));
198
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN,
199
0
        sandbox_gpio_get_flags(gpio_c, 0));
200
201
  /* GPIO 1 is (GPIO_OUT|GPIO_OPEN_SOURCE) */
202
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
203
0
        sandbox_gpio_get_flags(gpio_c, 1));
204
205
  /* Set it as output high, should become output high */
206
0
  ut_assertok(dm_gpio_set_value(&desc_list[1], 1));
207
0
  ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
208
0
  ut_asserteq_str("c1: output: 1 [x] a-test.test3-gpios1", buf);
209
210
  /* Set it as output low */
211
0
  ut_assertok(dm_gpio_set_value(&desc_list[1], 0));
212
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
213
0
        sandbox_gpio_get_flags(gpio_c, 1));
214
215
0
  ut_assertok(gpio_get_status(gpio_c, 1, buf, sizeof(buf)));
216
0
  ut_asserteq_str("c1: output: 0 [x] a-test.test3-gpios1", buf);
217
218
  /*
219
   * GPIO 6 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN). Looking at it
220
   * directlt from the driver, we get GPIOD_IS_OUT_ACTIVE also, since it
221
   * is active low
222
   */
223
0
  ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
224
0
        GPIOD_IS_OUT_ACTIVE,
225
0
        sandbox_gpio_get_flags(gpio_c, 6));
226
227
  /* Set it as output high, should become output low */
228
0
  ut_assertok(dm_gpio_set_value(&desc_list[6], 1));
229
0
  ut_assertok(gpio_get_status(gpio_c, 6, buf, sizeof(buf)));
230
0
  ut_asserteq_str("c6: output: 0 [x] a-test.test3-gpios6", buf);
231
232
  /* Set it as output low */
233
0
  ut_assertok(dm_gpio_set_value(&desc_list[6], 0));
234
0
  ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_DRAIN |
235
0
        GPIOD_IS_OUT_ACTIVE,
236
0
        sandbox_gpio_get_flags(gpio_c, 6));
237
238
  /* GPIO 7 is (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE) */
239
0
  ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE |
240
0
        GPIOD_IS_OUT_ACTIVE,
241
0
        sandbox_gpio_get_flags(gpio_c, 7));
242
243
  /* Set it as output high */
244
0
  ut_assertok(dm_gpio_set_value(&desc_list[7], 1));
245
0
  ut_asserteq(GPIOD_ACTIVE_LOW | GPIOD_IS_OUT | GPIOD_OPEN_SOURCE,
246
0
        sandbox_gpio_get_flags(gpio_c, 7));
247
248
  /* Set it as output low, should become output high */
249
0
  ut_assertok(dm_gpio_set_value(&desc_list[7], 0));
250
0
  ut_assertok(gpio_get_status(gpio_c, 7, buf, sizeof(buf)));
251
0
  ut_asserteq_str("c7: output: 1 [x] a-test.test3-gpios7", buf);
252
253
0
  ut_assertok(gpio_free_list(dev, desc_list, 8));
254
255
0
  return 0;
256
0
}
257
DM_TEST(dm_test_gpio_opendrain_opensource,
258
  UTF_SCAN_PDATA | UTF_SCAN_FDT);
259
260
/* Test that sandbox anonymous GPIOs work correctly */
261
static int dm_test_gpio_anon(struct unit_test_state *uts)
262
0
{
263
0
  unsigned int offset, gpio;
264
0
  struct udevice *dev;
265
0
  const char *name;
266
0
  int offset_count;
267
268
  /* And the anonymous bank */
269
0
  ut_assertok(gpio_lookup_name("14", &dev, &offset, &gpio));
270
0
  ut_asserteq_str(dev->name, "sandbox_gpio");
271
0
  ut_asserteq(14, offset);
272
0
  ut_asserteq(14, gpio);
273
274
0
  name = gpio_get_bank_info(dev, &offset_count);
275
0
  ut_asserteq_ptr(NULL, name);
276
0
  ut_asserteq(CONFIG_SANDBOX_GPIO_COUNT, offset_count);
277
278
0
  return 0;
279
0
}
280
DM_TEST(dm_test_gpio_anon, UTF_SCAN_PDATA | UTF_SCAN_FDT);
281
282
/* Test that gpio_requestf() works as expected */
283
static int dm_test_gpio_requestf(struct unit_test_state *uts)
284
0
{
285
0
  unsigned int offset, gpio;
286
0
  struct udevice *dev;
287
0
  char buf[80];
288
289
0
  ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio));
290
0
  ut_assertok(gpio_requestf(gpio, "testing %d %s", 1, "hi"));
291
0
  sandbox_gpio_set_direction(dev, offset, 1);
292
0
  sandbox_gpio_set_value(dev, offset, 1);
293
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
294
0
  ut_asserteq_str("b5: output: 1 [x] testing 1 hi", buf);
295
296
0
  return 0;
297
0
}
298
DM_TEST(dm_test_gpio_requestf, UTF_SCAN_PDATA | UTF_SCAN_FDT);
299
300
/* Test that gpio_request() copies its string */
301
static int dm_test_gpio_copy(struct unit_test_state *uts)
302
0
{
303
0
  unsigned int offset, gpio;
304
0
  struct udevice *dev;
305
0
  char buf[80], name[10];
306
307
0
  ut_assertok(gpio_lookup_name("b6", &dev, &offset, &gpio));
308
0
  strcpy(name, "odd_name");
309
0
  ut_assertok(gpio_request(gpio, name));
310
0
  sandbox_gpio_set_direction(dev, offset, 1);
311
0
  sandbox_gpio_set_value(dev, offset, 1);
312
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
313
0
  ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
314
0
  strcpy(name, "nothing");
315
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
316
0
  ut_asserteq_str("b6: output: 1 [x] odd_name", buf);
317
318
0
  return 0;
319
0
}
320
DM_TEST(dm_test_gpio_copy, UTF_SCAN_PDATA | UTF_SCAN_FDT);
321
322
/* Test that we don't leak memory with GPIOs */
323
/* Disabled for now as there seems to be a leak in the test framework itself. */
324
#if 0
325
static int dm_test_gpio_leak(struct unit_test_state *uts)
326
{
327
  ut_assertok(dm_test_gpio(uts));
328
  ut_assertok(dm_test_gpio_anon(uts));
329
  ut_assertok(dm_test_gpio_requestf(uts));
330
  ut_assertok(dm_leak_check_end(uts));
331
332
  return 0;
333
}
334
DM_TEST(dm_test_gpio_leak, UTF_SCAN_PDATA | UTF_SCAN_FDT);
335
#endif
336
337
/* Test that we can find GPIOs using phandles */
338
static int dm_test_gpio_phandles(struct unit_test_state *uts)
339
0
{
340
0
  struct gpio_desc desc, desc_list[8], desc_list2[8];
341
0
  struct udevice *dev, *gpio_a, *gpio_b;
342
343
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
344
0
  ut_asserteq_str("a-test", dev->name);
345
346
0
  ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
347
0
  ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a));
348
0
  ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b));
349
0
  ut_asserteq_str("base-gpios", gpio_a->name);
350
0
  ut_asserteq(true, !!device_active(gpio_a));
351
0
  ut_asserteq_ptr(gpio_a, desc.dev);
352
0
  ut_asserteq(4, desc.offset);
353
  /* GPIOF_INPUT is the sandbox GPIO driver default */
354
0
  ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL));
355
0
  ut_assertok(dm_gpio_free(dev, &desc));
356
357
0
  ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc,
358
0
              0));
359
0
  ut_asserteq_ptr(NULL, desc.dev);
360
0
  ut_asserteq(desc.offset, 0);
361
0
  ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc,
362
0
              0));
363
364
  /* Last GPIO is ignored as it comes after <0> */
365
0
  ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list,
366
0
             ARRAY_SIZE(desc_list), 0));
367
0
  ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios",
368
0
                  desc_list2,
369
0
                  ARRAY_SIZE(desc_list2),
370
0
                  0));
371
0
  ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL));
372
0
  ut_assertok(gpio_free_list(dev, desc_list, 3));
373
0
  ut_asserteq(GPIOF_UNUSED, gpio_get_function(gpio_a, 4, NULL));
374
0
  ut_asserteq(3, gpio_request_list_by_name(dev,  "test-gpios", desc_list,
375
0
             ARRAY_SIZE(desc_list),
376
0
             GPIOD_IS_OUT |
377
0
             GPIOD_IS_OUT_ACTIVE));
378
0
  ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 4, NULL));
379
0
  ut_asserteq_ptr(gpio_a, desc_list[0].dev);
380
0
  ut_asserteq(1, desc_list[0].offset);
381
0
  ut_asserteq_ptr(gpio_a, desc_list[1].dev);
382
0
  ut_asserteq(4, desc_list[1].offset);
383
0
  ut_asserteq_ptr(gpio_b, desc_list[2].dev);
384
0
  ut_asserteq(5, desc_list[2].offset);
385
0
  ut_asserteq(1, dm_gpio_get_value(desc_list));
386
0
  ut_assertok(gpio_free_list(dev, desc_list, 3));
387
388
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE,
389
0
        sandbox_gpio_get_flags(gpio_a, 1));
390
0
  ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list,
391
0
             ARRAY_SIZE(desc_list), 0));
392
393
  /* This was set to output previously but flags reset to 0 = INPUT */
394
0
  ut_asserteq(0, sandbox_gpio_get_flags(gpio_a, 1));
395
0
  ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 1, NULL));
396
397
  /* Active low should invert the input value */
398
0
  ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL));
399
0
  ut_asserteq(1, dm_gpio_get_value(&desc_list[2]));
400
401
0
  ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL));
402
0
  ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL));
403
0
  ut_asserteq(0, dm_gpio_get_value(&desc_list[4]));
404
0
  ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL));
405
0
  ut_asserteq(1, dm_gpio_get_value(&desc_list[5]));
406
407
0
  return 0;
408
0
}
409
DM_TEST(dm_test_gpio_phandles, UTF_SCAN_PDATA | UTF_SCAN_FDT);
410
411
/* Check the gpio pin configuration get from device tree information */
412
static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts)
413
0
{
414
0
  struct gpio_desc desc_list[6];
415
0
  struct udevice *dev;
416
0
  ulong flags;
417
418
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
419
420
0
  ut_asserteq(6, gpio_request_list_by_name(dev, "test3-gpios", desc_list,
421
0
             ARRAY_SIZE(desc_list), 0));
422
423
0
  ut_assertok(dm_gpio_get_flags(&desc_list[0], &flags));
424
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_DRAIN, flags);
425
426
0
  ut_assertok(dm_gpio_get_flags(&desc_list[1], &flags));
427
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_OPEN_SOURCE, flags);
428
429
0
  ut_assertok(dm_gpio_get_flags(&desc_list[2], &flags));
430
0
  ut_asserteq(GPIOD_IS_OUT, flags);
431
432
0
  ut_assertok(dm_gpio_get_flags(&desc_list[3], &flags));
433
0
  ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
434
435
0
  ut_assertok(dm_gpio_get_flags(&desc_list[4], &flags));
436
0
  ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_DOWN, flags);
437
438
0
  ut_assertok(dm_gpio_get_flags(&desc_list[5], &flags));
439
0
  ut_asserteq(GPIOD_IS_IN, flags);
440
441
0
  ut_assertok(gpio_free_list(dev, desc_list, 6));
442
443
0
  return 0;
444
0
}
445
DM_TEST(dm_test_gpio_get_dir_flags, UTF_SCAN_PDATA | UTF_SCAN_FDT);
446
447
/* Test of gpio_get_acpi() */
448
static int dm_test_gpio_get_acpi(struct unit_test_state *uts)
449
0
{
450
0
  struct acpi_gpio agpio;
451
0
  struct udevice *dev;
452
0
  struct gpio_desc desc;
453
454
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
455
0
  ut_asserteq_str("a-test", dev->name);
456
0
  ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
457
458
  /* See sb_gpio_get_acpi() */
459
0
  ut_assertok(gpio_get_acpi(&desc, &agpio));
460
0
  ut_asserteq(1, agpio.pin_count);
461
0
  ut_asserteq(4, agpio.pins[0]);
462
0
  ut_asserteq(ACPI_GPIO_TYPE_IO, agpio.type);
463
0
  ut_asserteq(ACPI_GPIO_PULL_UP, agpio.pull);
464
0
  ut_asserteq_str("\\_SB.PINC", agpio.resource);
465
0
  ut_asserteq(0, agpio.interrupt_debounce_timeout);
466
0
  ut_asserteq(0, agpio.irq.pin);
467
0
  ut_asserteq(1234, agpio.output_drive_strength);
468
0
  ut_asserteq(true, agpio.io_shared);
469
0
  ut_asserteq(ACPI_GPIO_IO_RESTRICT_INPUT, agpio.io_restrict);
470
0
  ut_asserteq(ACPI_GPIO_ACTIVE_HIGH, agpio.polarity);
471
472
0
  return 0;
473
0
}
474
DM_TEST(dm_test_gpio_get_acpi, UTF_SCAN_PDATA | UTF_SCAN_FDT);
475
476
/* Test of gpio_get_acpi() with an interrupt GPIO */
477
static int dm_test_gpio_get_acpi_irq(struct unit_test_state *uts)
478
0
{
479
0
  struct acpi_gpio agpio;
480
0
  struct udevice *dev;
481
0
  struct gpio_desc desc;
482
483
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
484
0
  ut_asserteq_str("a-test", dev->name);
485
0
  ut_assertok(gpio_request_by_name(dev, "test2-gpios", 2, &desc, 0));
486
487
  /* See sb_gpio_get_acpi() */
488
0
  ut_assertok(gpio_get_acpi(&desc, &agpio));
489
0
  ut_asserteq(1, agpio.pin_count);
490
0
  ut_asserteq(6, agpio.pins[0]);
491
0
  ut_asserteq(ACPI_GPIO_TYPE_INTERRUPT, agpio.type);
492
0
  ut_asserteq(ACPI_GPIO_PULL_DOWN, agpio.pull);
493
0
  ut_asserteq_str("\\_SB.PINC", agpio.resource);
494
0
  ut_asserteq(4321, agpio.interrupt_debounce_timeout);
495
0
  ut_asserteq(6, agpio.irq.pin);
496
0
  ut_asserteq(ACPI_IRQ_ACTIVE_BOTH, agpio.irq.polarity);
497
0
  ut_asserteq(ACPI_IRQ_SHARED, agpio.irq.shared);
498
0
  ut_asserteq(true, agpio.irq.wake);
499
0
  ut_asserteq(0, agpio.output_drive_strength);
500
0
  ut_asserteq(false, agpio.io_shared);
501
0
  ut_asserteq(0, agpio.io_restrict);
502
0
  ut_asserteq(ACPI_GPIO_ACTIVE_LOW, agpio.polarity);
503
504
0
  return 0;
505
0
}
506
DM_TEST(dm_test_gpio_get_acpi_irq, UTF_SCAN_PDATA | UTF_SCAN_FDT);
507
508
/* Test that we can get/release GPIOs using managed API */
509
static int dm_test_gpio_devm(struct unit_test_state *uts)
510
0
{
511
0
  static const u32 flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
512
0
  struct gpio_desc *desc1, *desc2, *desc3, *desc_err;
513
0
  struct udevice *dev;
514
0
  struct udevice *dev2;
515
516
0
  ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
517
0
                &dev));
518
0
  ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "another-test",
519
0
                &dev2));
520
521
  /* Get 3 GPIOs from 'a-test' dev */
522
0
  desc1 = devm_gpiod_get_index(dev, "test4", 0, flags);
523
0
  ut_assert(!IS_ERR(desc1));
524
0
  desc2 = devm_gpiod_get_index(dev, "test4", 1, flags);
525
0
  ut_assert(!IS_ERR(desc2));
526
0
  desc3 = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
527
0
  ut_assert(!IS_ERR(desc3));
528
0
  ut_assert(desc3);
529
530
  /*
531
   * Try get the same 3 GPIOs from 'a-test' and 'another-test' devices.
532
   * check that it fails
533
   */
534
0
  desc_err = devm_gpiod_get_index(dev, "test4", 0, flags);
535
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
536
0
  desc_err = devm_gpiod_get_index(dev2, "test4", 0, flags);
537
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
538
0
  desc_err = devm_gpiod_get_index(dev, "test4", 1, flags);
539
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
540
0
  desc_err = devm_gpiod_get_index(dev2, "test4", 1, flags);
541
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
542
0
  desc_err = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
543
0
  ut_asserteq_ptr(NULL, desc_err);
544
0
  desc_err = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
545
0
  ut_asserteq_ptr(NULL, desc_err);
546
547
  /* Try get GPIOs outside of the list */
548
0
  desc_err = devm_gpiod_get_index(dev, "test4", 2, flags);
549
0
  ut_assert(IS_ERR(desc_err));
550
0
  desc_err = devm_gpiod_get_index_optional(dev, "test5", 1, flags);
551
0
  ut_asserteq_ptr(NULL, desc_err);
552
553
  /* Manipulate the GPIOs */
554
0
  ut_assertok(dm_gpio_set_value(desc1, 1));
555
0
  ut_asserteq(1, dm_gpio_get_value(desc1));
556
0
  ut_assertok(dm_gpio_set_value(desc1, 0));
557
0
  ut_asserteq(0, dm_gpio_get_value(desc1));
558
559
0
  ut_assertok(dm_gpio_set_value(desc2, 1));
560
0
  ut_asserteq(1, dm_gpio_get_value(desc2));
561
0
  ut_assertok(dm_gpio_set_value(desc2, 0));
562
0
  ut_asserteq(0, dm_gpio_get_value(desc2));
563
564
0
  ut_assertok(dm_gpio_set_value(desc3, 1));
565
0
  ut_asserteq(1, dm_gpio_get_value(desc3));
566
0
  ut_assertok(dm_gpio_set_value(desc3, 0));
567
0
  ut_asserteq(0, dm_gpio_get_value(desc3));
568
569
  /* Check that the GPIO cannot be owned by more than one device */
570
0
  desc_err = devm_gpiod_get_index(dev2, "test4", 0, flags);
571
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
572
0
  desc_err = devm_gpiod_get_index(dev2, "test4", 1, flags);
573
0
  ut_asserteq(-EBUSY, PTR_ERR(desc_err));
574
0
  desc_err = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
575
0
  ut_asserteq_ptr(NULL, desc_err);
576
577
  /*
578
   * Release one GPIO and check that we can get it back using
579
   * 'another-test' and then 'a-test'
580
   */
581
0
  devm_gpiod_put(dev, desc2);
582
0
  desc2 = devm_gpiod_get_index(dev2, "test4", 1, flags);
583
0
  ut_assert(!IS_ERR(desc2));
584
585
0
  devm_gpiod_put(dev2, desc2);
586
0
  desc2 = devm_gpiod_get_index(dev, "test4", 1, flags);
587
0
  ut_assert(!IS_ERR(desc2));
588
589
  /* Release one GPIO before removing the 'a-test' dev. */
590
0
  devm_gpiod_put(dev, desc2);
591
0
  device_remove(dev, DM_REMOVE_NORMAL);
592
593
  /* All the GPIOs must have been freed. We should be able to claim
594
   * them with the 'another-test' device.
595
   */
596
0
  desc1 = devm_gpiod_get_index(dev2, "test4", 0, flags);
597
0
  ut_assert(!IS_ERR(desc1));
598
0
  desc2 = devm_gpiod_get_index(dev2, "test4", 1, flags);
599
0
  ut_assert(!IS_ERR(desc2));
600
0
  desc3 = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
601
0
  ut_assert(!IS_ERR(desc3));
602
0
  ut_assert(desc3);
603
604
0
  device_remove(dev2, DM_REMOVE_NORMAL);
605
0
  return 0;
606
0
}
607
DM_TEST(dm_test_gpio_devm, UTF_SCAN_PDATA | UTF_SCAN_FDT);
608
609
static int dm_test_clrset_flags(struct unit_test_state *uts)
610
0
{
611
0
  struct gpio_desc desc;
612
0
  struct udevice *dev;
613
0
  ulong flags;
614
615
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
616
0
  ut_asserteq_str("a-test", dev->name);
617
0
  ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
618
619
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_OUT));
620
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
621
0
  ut_asserteq(GPIOD_IS_OUT, flags);
622
0
  ut_asserteq(GPIOD_IS_OUT, desc.flags);
623
0
  ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
624
625
0
  ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
626
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
627
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, flags);
628
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE, desc.flags);
629
0
  ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
630
0
  ut_asserteq(1, dm_gpio_get_value(&desc));
631
632
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_DIR, GPIOD_IS_IN));
633
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
634
0
  ut_asserteq(GPIOD_IS_IN, flags & GPIOD_MASK_DIR);
635
0
  ut_asserteq(GPIOD_IS_IN, desc.flags & GPIOD_MASK_DIR);
636
637
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_MASK_PULL,
638
0
           GPIOD_PULL_UP));
639
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
640
0
  ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, flags);
641
0
  ut_asserteq(GPIOD_IS_IN | GPIOD_PULL_UP, desc.flags);
642
643
  /* Check we cannot set both PULL_UP and PULL_DOWN */
644
0
  ut_asserteq(-EINVAL, dm_gpio_clrset_flags(&desc, 0, GPIOD_PULL_DOWN));
645
646
0
  return 0;
647
0
}
648
DM_TEST(dm_test_clrset_flags, UTF_SCAN_PDATA | UTF_SCAN_FDT);
649
650
/* Check that an active-low GPIO works as expected */
651
static int dm_test_clrset_flags_invert(struct unit_test_state *uts)
652
0
{
653
0
  struct gpio_desc desc;
654
0
  struct udevice *dev;
655
0
  ulong flags;
656
657
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
658
0
  ut_asserteq_str("a-test", dev->name);
659
0
  ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc,
660
0
           GPIOD_IS_OUT | GPIOD_ACTIVE_LOW));
661
662
  /*
663
   * From this size we see it as 0 (active low), but the sandbox driver
664
   * sees the pin value high
665
   */
666
0
  ut_asserteq(0, dm_gpio_get_value(&desc));
667
0
  ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
668
669
0
  ut_assertok(dm_gpio_set_value(&desc, 1));
670
0
  ut_asserteq(1, dm_gpio_get_value(&desc));
671
0
  ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
672
673
  /* Do the same with dm_gpio_clrset_flags() */
674
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
675
0
  ut_asserteq(0, dm_gpio_get_value(&desc));
676
0
  ut_asserteq(1, sandbox_gpio_get_value(desc.dev, desc.offset));
677
678
0
  ut_assertok(dm_gpio_clrset_flags(&desc, 0, GPIOD_IS_OUT_ACTIVE));
679
0
  ut_asserteq(1, dm_gpio_get_value(&desc));
680
0
  ut_asserteq(0, sandbox_gpio_get_value(desc.dev, desc.offset));
681
682
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
683
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
684
0
        flags);
685
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW | GPIOD_IS_OUT_ACTIVE,
686
0
        desc.flags);
687
688
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_OUT_ACTIVE, 0));
689
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
690
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, flags);
691
0
  ut_asserteq(GPIOD_IS_OUT | GPIOD_ACTIVE_LOW, desc.flags);
692
693
0
  return 0;
694
0
}
695
DM_TEST(dm_test_clrset_flags_invert, UTF_SCAN_PDATA | UTF_SCAN_FDT);
696
697
static int set_gpios(struct unit_test_state *uts, struct gpio_desc *desc,
698
         int count, uint value)
699
0
{
700
0
  int i;
701
702
0
  for (i = 0; i < count; i++) {
703
0
    const uint mask = 1 << i;
704
705
0
    ut_assertok(sandbox_gpio_set_value(desc[i].dev, desc[i].offset,
706
0
               value & mask));
707
0
  }
708
709
0
  return 0;
710
0
}
711
712
/* Check that an active-low GPIO works as expected */
713
static int dm_test_gpio_get_values_as_int(struct unit_test_state *uts)
714
0
{
715
0
  const int gpio_count = 3;
716
0
  struct gpio_desc desc[gpio_count];
717
0
  struct udevice *dev;
718
719
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
720
0
  ut_asserteq_str("a-test", dev->name);
721
722
0
  ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
723
0
             gpio_count, GPIOD_IS_IN));
724
0
  ut_assertok(set_gpios(uts, desc, gpio_count, 0));
725
0
  ut_asserteq(0, dm_gpio_get_values_as_int(desc, gpio_count));
726
727
0
  ut_assertok(set_gpios(uts, desc, gpio_count, 5));
728
0
  ut_asserteq(5, dm_gpio_get_values_as_int(desc, gpio_count));
729
730
0
  ut_assertok(set_gpios(uts, desc, gpio_count, 7));
731
0
  ut_asserteq(7, dm_gpio_get_values_as_int(desc, gpio_count));
732
733
0
  return 0;
734
0
}
735
DM_TEST(dm_test_gpio_get_values_as_int,
736
  UTF_SCAN_PDATA | UTF_SCAN_FDT);
737
738
/* Check that an active-low GPIO works as expected */
739
static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts)
740
0
{
741
0
  const int gpio_count = 3;
742
0
  struct gpio_desc desc[gpio_count];
743
0
  struct udevice *dev;
744
745
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
746
0
  ut_asserteq_str("a-test", dev->name);
747
748
0
  ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc,
749
0
             gpio_count, GPIOD_IS_IN));
750
751
  /*
752
   * First test the sandbox GPIO driver works as expected. The external
753
   * pull resistor should be stronger than the internal one.
754
   */
755
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
756
0
             GPIOD_IS_IN | GPIOD_EXT_PULL_UP | GPIOD_PULL_UP);
757
0
  ut_asserteq(1, dm_gpio_get_value(desc));
758
759
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_IS_IN |
760
0
             GPIOD_EXT_PULL_DOWN | GPIOD_PULL_UP);
761
0
  ut_asserteq(0, dm_gpio_get_value(desc));
762
763
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset,
764
0
             GPIOD_IS_IN | GPIOD_PULL_UP);
765
0
  ut_asserteq(1, dm_gpio_get_value(desc));
766
767
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_PULL_DOWN);
768
0
  ut_asserteq(0, dm_gpio_get_value(desc));
769
770
  /*
771
   * Set up pins: pull-up (1), pull-down (0) and floating (2). This should
772
   * result in digits 2 0 1, i.e. 2 * 9 + 1 * 3 = 19
773
   */
774
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, GPIOD_EXT_PULL_UP);
775
0
  sandbox_gpio_set_flags(desc[1].dev, desc[1].offset,
776
0
             GPIOD_EXT_PULL_DOWN);
777
0
  sandbox_gpio_set_flags(desc[2].dev, desc[2].offset, 0);
778
0
  ut_asserteq(19, dm_gpio_get_values_as_int_base3(desc, gpio_count));
779
780
  /*
781
   * Set up pins: floating (2), pull-up (1) and pull-down (0). This should
782
   * result in digits 0 1 2, i.e. 1 * 3 + 2 = 5
783
   */
784
0
  sandbox_gpio_set_flags(desc[0].dev, desc[0].offset, 0);
785
0
  sandbox_gpio_set_flags(desc[1].dev, desc[1].offset, GPIOD_EXT_PULL_UP);
786
0
  sandbox_gpio_set_flags(desc[2].dev, desc[2].offset,
787
0
             GPIOD_EXT_PULL_DOWN);
788
0
  ut_asserteq(5, dm_gpio_get_values_as_int_base3(desc, gpio_count));
789
790
0
  return 0;
791
0
}
792
DM_TEST(dm_test_gpio_get_values_as_int_base3,
793
  UTF_SCAN_PDATA | UTF_SCAN_FDT);
794
795
/* Check that gpio_get_status return the label of a GPIO configured as GPIOD_AF */
796
static int dm_test_gpio_function(struct unit_test_state *uts)
797
0
{
798
0
  struct gpio_desc desc;
799
0
  struct udevice *dev;
800
0
  ulong flags;
801
0
  unsigned int offset, gpio;
802
0
  char buf[80];
803
804
0
  ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
805
0
  ut_asserteq_str("a-test", dev->name);
806
807
  /* request gpio_b 5 */
808
0
  ut_assertok(gpio_request_by_name(dev, "test-gpios", 2, &desc, 0));
809
  /* update gpio_b 5 function to GPIO_AF */
810
0
  ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_AF, GPIOD_IS_AF));
811
0
  ut_assertok(dm_gpio_get_flags(&desc, &flags));
812
0
  ut_asserteq(GPIOD_IS_AF, flags);
813
  /* check using gpio_get_status that label is displayed for a pin with GPIO_AF function */
814
0
  ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio));
815
0
  ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf)));
816
0
  ut_asserteq_str("b5: func a-test.test-gpios2", buf);
817
818
0
  ut_assertok(dm_gpio_free(dev, &desc));
819
820
0
  return 0;
821
0
}
822
DM_TEST(dm_test_gpio_function,
823
  UTF_SCAN_PDATA | UTF_SCAN_FDT);