1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2022, Linaro Limited
4 *
5 * Tests introduce dummy test drivers and assiciated devices defined in
6 * dt_driver_test.dtsi file with device resource dependencies.
7 */
8
9 #include <assert.h>
10 #include <config.h>
11 #include <crypto/crypto.h>
12 #include <drivers/clk.h>
13 #include <drivers/clk_dt.h>
14 #include <drivers/gpio.h>
15 #include <drivers/rstctrl.h>
16 #include <initcall.h>
17 #include <kernel/dt_driver.h>
18 #include <malloc.h>
19 #include <sys/queue.h>
20 #include <tee_api_defines_extensions.h>
21 #include <tee_api_types.h>
22
23 #define DT_TEST_MSG(...) FMSG("(dt-driver-test) " __VA_ARGS__)
24
25 /* Test state IDs */
26 enum dt_test_sid { DEFAULT = 0, IN_PROGRESS, SUCCESS, FAILED };
27
28 /*
29 * DT tests state to be reported from PTA_INVOKE_TESTS_CMD_DT_TEST_STATUS
30 * possibly printed to console. A test can be skipped (DEFAULT) or be
31 * successful (SUCCESS) orthewise it has failed (IN_PROGRESS, FAILED).
32 */
33 struct dt_test_state {
34 enum dt_test_sid probe_deferral;
35 enum dt_test_sid probe_clocks;
36 enum dt_test_sid probe_gpios;
37 enum dt_test_sid probe_resets;
38 enum dt_test_sid crypto_dependencies;
39 };
40
41 /*
42 * References allocated from heap to be free once test completed
43 * dt_test_alloc(), dt_test_free(), dt_test_free_all()
44 */
45 struct dt_test_free_ref {
46 void *p;
47 SLIST_ENTRY(dt_test_free_ref) link;
48 };
49
50 static struct dt_test_state dt_test_state;
51
52 static const char __maybe_unused * const dt_test_str_sid[] = {
53 [DEFAULT] = "not run",
54 [IN_PROGRESS] = "in-progress",
55 [SUCCESS] = "successful",
56 [FAILED] = "failed",
57 };
58
59 /* Reference allocations during test for release_init_resource initcall level */
60 static SLIST_HEAD(dt_test_free_refs, dt_test_free_ref) dt_test_free_list =
61 SLIST_HEAD_INITIALIZER(dt_test_free_list);
62
dt_test_alloc(size_t size)63 static void __maybe_unused *dt_test_alloc(size_t size)
64 {
65 struct dt_test_free_ref *ref = NULL;
66
67 ref = calloc(1, sizeof(*ref) + size);
68 if (!ref)
69 return NULL;
70
71 ref->p = ref + 1;
72 SLIST_INSERT_HEAD(&dt_test_free_list, ref, link);
73
74 return ref->p;
75 }
76
dt_test_free(void * p)77 static void __maybe_unused dt_test_free(void *p)
78 {
79 struct dt_test_free_ref *ref = NULL;
80 struct dt_test_free_ref *t_ref = NULL;
81
82 if (!p)
83 return;
84
85 SLIST_FOREACH_SAFE(ref, &dt_test_free_list, link, t_ref) {
86 if (ref->p == p) {
87 SLIST_REMOVE(&dt_test_free_list, ref,
88 dt_test_free_ref, link);
89 free(ref);
90 return;
91 }
92 }
93
94 panic();
95 }
96
dt_test_free_all(void)97 static void dt_test_free_all(void)
98 {
99 while (!SLIST_EMPTY(&dt_test_free_list)) {
100 struct dt_test_free_ref *ref = SLIST_FIRST(&dt_test_free_list);
101
102 SLIST_REMOVE(&dt_test_free_list, ref, dt_test_free_ref, link);
103 free(ref);
104 }
105 }
106
dt_test_release(void)107 static TEE_Result dt_test_release(void)
108 {
109 dt_test_free_all();
110
111 DT_TEST_MSG("Probe deferral: %s",
112 dt_test_str_sid[dt_test_state.probe_deferral]);
113 DT_TEST_MSG("Clocks probe: %s",
114 dt_test_str_sid[dt_test_state.probe_clocks]);
115 DT_TEST_MSG("GPIO ctrl probe: %s",
116 dt_test_str_sid[dt_test_state.probe_gpios]);
117 DT_TEST_MSG("Reset ctrl probe: %s",
118 dt_test_str_sid[dt_test_state.probe_resets]);
119 DT_TEST_MSG("Crypto deps.: %s",
120 dt_test_str_sid[dt_test_state.crypto_dependencies]);
121
122 return dt_driver_test_status();
123 }
124
125 release_init_resource(dt_test_release);
126
dt_driver_test_status(void)127 TEE_Result dt_driver_test_status(void)
128 {
129 TEE_Result res = TEE_SUCCESS;
130
131 if (dt_test_state.probe_deferral != SUCCESS) {
132 EMSG("Probe deferral test failed");
133 res = TEE_ERROR_GENERIC;
134 }
135 if (IS_ENABLED(CFG_DRIVERS_CLK) &&
136 dt_test_state.probe_clocks != SUCCESS) {
137 EMSG("Clocks probing test failed");
138 res = TEE_ERROR_GENERIC;
139 }
140 if (IS_ENABLED(CFG_DRIVERS_GPIOS) &&
141 dt_test_state.probe_gpios != SUCCESS) {
142 EMSG("GPIO controllers probing test failed");
143 res = TEE_ERROR_GENERIC;
144 }
145 if (IS_ENABLED(CFG_DRIVERS_RSTCTRL) &&
146 dt_test_state.probe_resets != SUCCESS) {
147 EMSG("Reset controllers probing test failed");
148 res = TEE_ERROR_GENERIC;
149 }
150 if (dt_test_state.crypto_dependencies != SUCCESS) {
151 EMSG("Probe deferral on crypto dependencies test failed");
152 res = TEE_ERROR_GENERIC;
153 }
154
155 return res;
156 }
157
probe_test_clocks(const void * fdt,int node)158 static TEE_Result probe_test_clocks(const void *fdt, int node)
159 {
160 TEE_Result res = TEE_ERROR_GENERIC;
161 struct clk *clk0 = NULL;
162 struct clk *clk1 = NULL;
163 struct clk *clk = NULL;
164
165 DT_TEST_MSG("Probe clocks");
166 dt_test_state.probe_clocks = IN_PROGRESS;
167
168 res = clk_dt_get_by_index(fdt, node, 0, &clk0);
169 if (res)
170 goto err;
171
172 res = clk_dt_get_by_index(fdt, node, 1, &clk1);
173 if (res)
174 goto err;
175
176 DT_TEST_MSG("Check valid clock references");
177
178 if (clk_enable(clk0)) {
179 DT_TEST_MSG("Can't enable %s", clk_get_name(clk0));
180 res = TEE_ERROR_GENERIC;
181 goto err;
182 }
183 clk_disable(clk0);
184
185 res = clk_dt_get_by_name(fdt, node, "clk0", &clk);
186 if (res || clk != clk0) {
187 DT_TEST_MSG("Unexpected clock reference");
188 res = TEE_ERROR_GENERIC;
189 goto err;
190 }
191
192 res = clk_dt_get_by_name(fdt, node, "clk1", &clk);
193 if (res || clk != clk1) {
194 DT_TEST_MSG("Unexpected clock reference");
195 res = TEE_ERROR_GENERIC;
196 goto err;
197 }
198
199 DT_TEST_MSG("Bad clock reference");
200
201 res = clk_dt_get_by_index(fdt, node, 3, &clk);
202 if (!res) {
203 DT_TEST_MSG("Unexpected clock found on invalid index");
204 res = TEE_ERROR_GENERIC;
205 goto err;
206 }
207
208 res = clk_dt_get_by_name(fdt, node, "clk2", &clk);
209 if (!res) {
210 DT_TEST_MSG("Unexpected clock found on invalid name");
211 res = TEE_ERROR_GENERIC;
212 goto err;
213 }
214
215 dt_test_state.probe_clocks = SUCCESS;
216 return TEE_SUCCESS;
217
218 err:
219 if (res != TEE_ERROR_DEFER_DRIVER_INIT)
220 dt_test_state.probe_clocks = FAILED;
221
222 return res;
223 }
224
probe_test_resets(const void * fdt,int node)225 static TEE_Result probe_test_resets(const void *fdt, int node)
226 {
227 TEE_Result res = TEE_ERROR_GENERIC;
228 struct rstctrl *rstctrl0 = NULL;
229 struct rstctrl *rstctrl1 = NULL;
230 struct rstctrl *rstctrl = NULL;
231
232 DT_TEST_MSG("Probe reset controllers");
233 dt_test_state.probe_resets = IN_PROGRESS;
234
235 res = rstctrl_dt_get_by_index(fdt, node, 0, &rstctrl0);
236 if (res)
237 goto err;
238
239 DT_TEST_MSG("Check valid reset controller");
240
241 if (rstctrl_assert(rstctrl0)) {
242 EMSG("Can't assert rstctrl %s", rstctrl_name(rstctrl0));
243 res = TEE_ERROR_GENERIC;
244 goto err;
245 }
246
247 res = rstctrl_dt_get_by_name(fdt, node, "rst0", &rstctrl);
248 if (res)
249 goto err;
250
251 if (rstctrl != rstctrl0) {
252 EMSG("Unexpected reset controller reference");
253 res = TEE_ERROR_GENERIC;
254 goto err;
255 }
256
257 res = rstctrl_dt_get_by_name(fdt, node, "rst1", &rstctrl1);
258 if (res)
259 goto err;
260
261 if (!rstctrl1 || rstctrl1 == rstctrl0) {
262 EMSG("Unexpected reset controller reference");
263 res = TEE_ERROR_GENERIC;
264 goto err;
265 }
266
267 dt_test_state.probe_resets = SUCCESS;
268 return TEE_SUCCESS;
269
270 err:
271 if (res != TEE_ERROR_DEFER_DRIVER_INIT)
272 dt_test_state.probe_resets = FAILED;
273
274 return res;
275 }
276
probe_test_gpios(const void * fdt,int node)277 static TEE_Result probe_test_gpios(const void *fdt, int node)
278 {
279 TEE_Result res = TEE_ERROR_GENERIC;
280 struct gpio *gpio = NULL;
281
282 DT_TEST_MSG("Probe GPIO controllers");
283 dt_test_state.probe_gpios = IN_PROGRESS;
284
285 res = gpio_dt_cfg_by_index(fdt, node, 0, "test", GPIO_IN, &gpio);
286 if (res)
287 goto err;
288
289 if (gpio_get_direction(gpio) != GPIO_DIR_IN) {
290 EMSG("Unexpected gpio_get_direction() return value");
291 res = TEE_ERROR_GENERIC;
292 goto err;
293 }
294
295 /* GPIO is declared as ACTIVE_LOW in device-tree */
296 if (gpio_get_value(gpio) != GPIO_LEVEL_LOW) {
297 EMSG("Unexpected gpio_get_value() return value");
298 res = TEE_ERROR_GENERIC;
299 goto err;
300 }
301
302 res = gpio_dt_cfg_by_index(fdt, node, 1, "test", GPIO_IN, &gpio);
303 if (res)
304 goto err;
305
306 if (gpio_get_direction(gpio) != GPIO_DIR_IN) {
307 EMSG("Unexpected gpio_get_direction() return value");
308 res = TEE_ERROR_GENERIC;
309 goto err;
310 }
311
312 if (gpio_get_value(gpio) != GPIO_LEVEL_HIGH) {
313 EMSG("Unexpected gpio_get_value() return value");
314 res = TEE_ERROR_GENERIC;
315 goto err;
316 }
317
318 dt_test_state.probe_gpios = SUCCESS;
319 return TEE_SUCCESS;
320
321 err:
322 if (res != TEE_ERROR_DEFER_DRIVER_INIT)
323 dt_test_state.probe_gpios = FAILED;
324
325 return res;
326 }
327
328 /*
329 * Consumer test driver: instance probed from the compatible
330 * node parsed in the DT. It consumes emulated resource obtained
331 * from DT references. Probe shall succeed only once all resources
332 * are found.
333 */
dt_test_consumer_probe(const void * fdt,int node,const void * compat_data __unused)334 static TEE_Result dt_test_consumer_probe(const void *fdt, int node,
335 const void *compat_data __unused)
336 {
337 TEE_Result res = TEE_ERROR_GENERIC;
338
339 if (IS_ENABLED(CFG_DRIVERS_CLK)) {
340 res = probe_test_clocks(fdt, node);
341 if (res)
342 goto err_probe;
343 }
344
345 if (IS_ENABLED(CFG_DRIVERS_RSTCTRL)) {
346 res = probe_test_resets(fdt, node);
347 if (res)
348 goto err_probe;
349 }
350
351 if (IS_ENABLED(CFG_DRIVERS_GPIO)) {
352 res = probe_test_gpios(fdt, node);
353 if (res)
354 goto err_probe;
355 }
356
357 if (dt_test_state.probe_deferral != IN_PROGRESS) {
358 dt_test_state.probe_deferral = FAILED;
359 return TEE_ERROR_GENERIC;
360 }
361
362 dt_test_state.probe_deferral = SUCCESS;
363
364 return TEE_SUCCESS;
365
366 err_probe:
367 assert(res);
368
369 if (res == TEE_ERROR_DEFER_DRIVER_INIT &&
370 dt_test_state.probe_deferral == DEFAULT) {
371 /* We expect at least a probe deferral */
372 dt_test_state.probe_deferral = IN_PROGRESS;
373 }
374
375 return res;
376 }
377
378 static const struct dt_device_match dt_test_consumer_match_table[] = {
379 { .compatible = "linaro,dt-test-consumer", },
380 { }
381 };
382
383 DEFINE_DT_DRIVER(dt_test_consumer_driver) = {
384 .name = "dt-test-consumer",
385 .match_table = dt_test_consumer_match_table,
386 .probe = dt_test_consumer_probe,
387 };
388
dt_test_crypt_consumer_probe(const void * fdt __unused,int node __unused,const void * compat_data __unused)389 static TEE_Result dt_test_crypt_consumer_probe(const void *fdt __unused,
390 int node __unused,
391 const void *compat_data __unused)
392 {
393 TEE_Result res = dt_driver_get_crypto();
394 uint8_t __maybe_unused byte = 0;
395
396 if (res == TEE_ERROR_DEFER_DRIVER_INIT &&
397 dt_test_state.crypto_dependencies == DEFAULT) {
398 /* We expect to be deferred */
399 dt_test_state.crypto_dependencies = IN_PROGRESS;
400 }
401
402 if (res)
403 return res;
404
405 if (dt_test_state.crypto_dependencies == DEFAULT) {
406 EMSG("Test expects at least a driver probe deferral");
407 dt_test_state.crypto_dependencies = FAILED;
408 return TEE_ERROR_GENERIC;
409 }
410
411 if (crypto_rng_read(&byte, sizeof(byte))) {
412 dt_test_state.crypto_dependencies = FAILED;
413 return TEE_ERROR_GENERIC;
414 }
415
416 dt_test_state.crypto_dependencies = SUCCESS;
417 return TEE_SUCCESS;
418 }
419
420 static const struct dt_device_match dt_test_crypt_consumer_match_table[] = {
421 { .compatible = "linaro,dt-test-crypt-consumer", },
422 { }
423 };
424
425 DEFINE_DT_DRIVER(dt_test_consumer_driver) = {
426 .name = "dt-test-crypt-consumer",
427 .match_table = dt_test_crypt_consumer_match_table,
428 .probe = dt_test_crypt_consumer_probe,
429 };
430
431 #ifdef CFG_DRIVERS_CLK
432 #define DT_TEST_CLK_COUNT 2
433
434 #define DT_TEST_CLK0_BINDING_ID 3
435 #define DT_TEST_CLK1_BINDING_ID 7
436
437 static const char *dt_test_clk_name[DT_TEST_CLK_COUNT] = {
438 "dt_test-clk3",
439 "dt_test-clk7",
440 };
441
442 /* Emulating a clock does not require operators */
443 static const struct clk_ops dt_test_clock_provider_ops;
444
dt_test_get_clk(struct dt_pargs * args,void * data,struct clk ** out_device)445 static TEE_Result dt_test_get_clk(struct dt_pargs *args, void *data,
446 struct clk **out_device)
447 {
448 struct clk *clk_ref = data;
449 struct clk *clk = NULL;
450
451 if (args->args_count != 1)
452 return TEE_ERROR_BAD_PARAMETERS;
453
454 switch (args->args[0]) {
455 case DT_TEST_CLK0_BINDING_ID:
456 clk = clk_ref;
457 break;
458 case DT_TEST_CLK1_BINDING_ID:
459 clk = clk_ref + 1;
460 break;
461 default:
462 EMSG("Unexpected binding ID %"PRIu32, args->args[0]);
463 return TEE_ERROR_BAD_PARAMETERS;
464 }
465
466 DT_TEST_MSG("Providing clock %s", clk_get_name(clk));
467
468 *out_device = clk;
469 return TEE_SUCCESS;
470 }
471
dt_test_clock_provider_probe(const void * fdt,int node,const void * compat_data __unused)472 static TEE_Result dt_test_clock_provider_probe(const void *fdt, int node,
473 const void *compat_data __unused)
474 {
475 TEE_Result res = TEE_ERROR_GENERIC;
476 struct clk *clk = NULL;
477 size_t n = 0;
478
479 DT_TEST_MSG("Register clocks");
480
481 clk = dt_test_alloc(DT_TEST_CLK_COUNT * sizeof(*clk));
482 if (!clk)
483 return TEE_ERROR_OUT_OF_MEMORY;
484
485 for (n = 0; n < DT_TEST_CLK_COUNT; n++) {
486 clk[n].ops = &dt_test_clock_provider_ops;
487 clk[n].name = dt_test_clk_name[n];
488
489 res = clk_register(clk + n);
490 if (res)
491 goto err;
492 }
493
494 res = clk_dt_register_clk_provider(fdt, node, dt_test_get_clk, clk);
495 if (res)
496 goto err;
497
498 return TEE_SUCCESS;
499
500 err:
501 dt_test_free(clk);
502 return res;
503 }
504
505 CLK_DT_DECLARE(dt_test_clock_provider, "linaro,dt-test-provider",
506 dt_test_clock_provider_probe);
507 #endif /* CFG_DRIVERS_CLK */
508
509 #ifdef CFG_DRIVERS_RSTCTRL
510 #define DT_TEST_RSTCTRL_COUNT 2
511
512 #define DT_TEST_RSTCTRL0_BINDING_ID 5
513 #define DT_TEST_RSTCTRL1_BINDING_ID 35
514
515 struct dt_test_rstctrl {
516 unsigned int dt_binding;
517 struct rstctrl rstctrl;
518 };
519
to_test_rstctrl(struct rstctrl * rstctrl)520 static struct dt_test_rstctrl *to_test_rstctrl(struct rstctrl *rstctrl)
521 {
522 return container_of(rstctrl, struct dt_test_rstctrl, rstctrl);
523 }
524
dt_test_rstctrl_stub(struct rstctrl * rstctrl __maybe_unused,unsigned int to_us __unused)525 static TEE_Result dt_test_rstctrl_stub(struct rstctrl *rstctrl __maybe_unused,
526 unsigned int to_us __unused)
527 {
528 struct dt_test_rstctrl *dev = to_test_rstctrl(rstctrl);
529
530 switch (dev->dt_binding) {
531 case DT_TEST_RSTCTRL0_BINDING_ID:
532 case DT_TEST_RSTCTRL1_BINDING_ID:
533 return TEE_SUCCESS;
534 default:
535 EMSG("Unexpected rstctrl reference");
536 return TEE_ERROR_GENERIC;
537 }
538 }
539
dt_test_rstctrl_name(struct rstctrl * rstctrl __maybe_unused)540 static const char *dt_test_rstctrl_name(struct rstctrl *rstctrl __maybe_unused)
541 {
542 static const char *rstctrl_name[DT_TEST_RSTCTRL_COUNT] = {
543 "dt_test-rstctrl5",
544 "dt_test-rstctrl35",
545 };
546 struct dt_test_rstctrl *dev = to_test_rstctrl(rstctrl);
547
548 switch (dev->dt_binding) {
549 case DT_TEST_RSTCTRL0_BINDING_ID:
550 return rstctrl_name[0];
551 case DT_TEST_RSTCTRL1_BINDING_ID:
552 return rstctrl_name[1];
553 default:
554 EMSG("Unexpected rstctrl reference");
555 return NULL;
556 }
557 }
558
559 const struct rstctrl_ops dt_test_rstctrl_ops = {
560 .assert_level = dt_test_rstctrl_stub,
561 .deassert_level = dt_test_rstctrl_stub,
562 .get_name = dt_test_rstctrl_name,
563 };
564
dt_test_get_rstctrl(struct dt_pargs * args,void * data,struct rstctrl ** out_device)565 static TEE_Result dt_test_get_rstctrl(struct dt_pargs *args, void *data,
566 struct rstctrl **out_device)
567 {
568 struct dt_test_rstctrl *ref = data;
569 struct rstctrl *rstctrl = NULL;
570
571 if (args->args_count != 1)
572 return TEE_ERROR_BAD_PARAMETERS;
573
574 switch (args->args[0]) {
575 case DT_TEST_RSTCTRL0_BINDING_ID:
576 rstctrl = &ref[0].rstctrl;
577 break;
578 case DT_TEST_RSTCTRL1_BINDING_ID:
579 rstctrl = &ref[1].rstctrl;
580 break;
581 default:
582 EMSG("Unexpected binding ID %"PRIu32, args->args[0]);
583 return TEE_ERROR_BAD_PARAMETERS;
584 }
585
586 DT_TEST_MSG("Providing reset controller %s", rstctrl_name(rstctrl));
587
588 *out_device = rstctrl;
589
590 return TEE_SUCCESS;
591 }
592
dt_test_rstctrl_provider_probe(const void * fdt,int offs,const void * data __unused)593 static TEE_Result dt_test_rstctrl_provider_probe(const void *fdt, int offs,
594 const void *data __unused)
595 {
596 TEE_Result res = TEE_ERROR_GENERIC;
597 struct dt_test_rstctrl *devices = NULL;
598
599 DT_TEST_MSG("Register reset controllers");
600
601 assert(rstctrl_ops_is_valid(&dt_test_rstctrl_ops));
602
603 devices = dt_test_alloc(DT_TEST_RSTCTRL_COUNT * sizeof(*devices));
604 if (!devices)
605 return TEE_ERROR_OUT_OF_MEMORY;
606
607 devices[0].rstctrl.ops = &dt_test_rstctrl_ops;
608 devices[0].dt_binding = DT_TEST_RSTCTRL0_BINDING_ID;
609
610 devices[1].rstctrl.ops = &dt_test_rstctrl_ops;
611 devices[1].dt_binding = DT_TEST_RSTCTRL1_BINDING_ID;
612
613 res = rstctrl_register_provider(fdt, offs, dt_test_get_rstctrl,
614 devices);
615 if (res) {
616 dt_test_free(devices);
617 return res;
618 }
619
620 return TEE_SUCCESS;
621 }
622
623 RSTCTRL_DT_DECLARE(dt_test_rstctrl_provider, "linaro,dt-test-provider",
624 dt_test_rstctrl_provider_probe);
625 #endif /* CFG_DRIVERS_RSTCTRL */
626
627 #ifdef CFG_DRIVERS_GPIO
628 #define DT_TEST_GPIO_COUNT 2
629
630 #define DT_TEST_GPIO0_PIN 1
631 #define DT_TEST_GPIO0_FLAGS GPIO_ACTIVE_LOW
632 #define DT_TEST_GPIO1_PIN 2
633 #define DT_TEST_GPIO1_FLAGS GPIO_PULL_UP
634
635 struct dt_test_gpio {
636 unsigned int pin;
637 unsigned int flags;
638 struct gpio_chip gpio_chip;
639 };
640
to_test_gpio(struct gpio_chip * chip)641 static struct dt_test_gpio *to_test_gpio(struct gpio_chip *chip)
642 {
643 return container_of(chip, struct dt_test_gpio, gpio_chip);
644 }
645
dt_test_gpio_get_direction(struct gpio_chip * chip,unsigned int gpio_pin)646 static enum gpio_dir dt_test_gpio_get_direction(struct gpio_chip *chip,
647 unsigned int gpio_pin)
648 {
649 struct dt_test_gpio *dtg = to_test_gpio(chip);
650
651 if (dtg->pin != gpio_pin)
652 panic("Invalid GPIO number");
653
654 return GPIO_DIR_IN;
655 }
656
dt_test_gpio_set_direction(struct gpio_chip * chip,unsigned int gpio_pin,enum gpio_dir direction __unused)657 static void dt_test_gpio_set_direction(struct gpio_chip *chip,
658 unsigned int gpio_pin,
659 enum gpio_dir direction __unused)
660 {
661 struct dt_test_gpio *dtg = to_test_gpio(chip);
662
663 if (dtg->pin != gpio_pin)
664 panic("Invalid GPIO number");
665 }
666
dt_test_gpio_get_value(struct gpio_chip * chip,unsigned int gpio_pin)667 static enum gpio_level dt_test_gpio_get_value(struct gpio_chip *chip,
668 unsigned int gpio_pin)
669 {
670 struct dt_test_gpio *dtg = to_test_gpio(chip);
671
672 if (dtg->pin != gpio_pin)
673 panic("Invalid GPIO number");
674
675 return GPIO_LEVEL_HIGH;
676 }
677
dt_test_gpio_set_value(struct gpio_chip * chip,unsigned int gpio_pin,enum gpio_level value __unused)678 static void dt_test_gpio_set_value(struct gpio_chip *chip,
679 unsigned int gpio_pin,
680 enum gpio_level value __unused)
681 {
682 struct dt_test_gpio *dtg = to_test_gpio(chip);
683
684 if (dtg->pin != gpio_pin)
685 panic("Invalid GPIO number");
686 }
687
688 static const struct gpio_ops dt_test_gpio_ops = {
689 .get_direction = dt_test_gpio_get_direction,
690 .set_direction = dt_test_gpio_set_direction,
691 .get_value = dt_test_gpio_get_value,
692 .set_value = dt_test_gpio_set_value,
693 };
694
dt_test_gpio_get_dt(struct dt_pargs * args,void * data,struct gpio ** out_device)695 static TEE_Result dt_test_gpio_get_dt(struct dt_pargs *args, void *data,
696 struct gpio **out_device)
697 {
698 TEE_Result res = TEE_ERROR_GENERIC;
699 struct gpio *gpio = NULL;
700 struct dt_test_gpio *gpios = (struct dt_test_gpio *)data;
701
702 res = gpio_dt_alloc_pin(args, &gpio);
703 if (res)
704 return res;
705
706 switch (gpio->pin) {
707 case DT_TEST_GPIO0_PIN:
708 gpio->chip = &gpios[0].gpio_chip;
709 if (gpio->dt_flags != gpios[0].flags) {
710 EMSG("Unexpected dt_flags %#"PRIx32, gpio->dt_flags);
711 free(gpio);
712 return TEE_ERROR_GENERIC;
713 }
714 break;
715 case DT_TEST_GPIO1_PIN:
716 gpio->chip = &gpios[1].gpio_chip;
717 if (gpio->dt_flags != gpios[1].flags) {
718 EMSG("Unexpected dt_flags %#"PRIx32, gpio->dt_flags);
719 free(gpio);
720 return TEE_ERROR_GENERIC;
721 }
722 break;
723 default:
724 EMSG("Unexpected pin ID %u", gpio->pin);
725 free(gpio);
726 return TEE_ERROR_BAD_PARAMETERS;
727 };
728
729 *out_device = gpio;
730
731 return TEE_SUCCESS;
732 }
733
dt_test_gpio_provider_probe(const void * fdt,int offs,const void * data __unused)734 static TEE_Result dt_test_gpio_provider_probe(const void *fdt, int offs,
735 const void *data __unused)
736 {
737 TEE_Result res = TEE_ERROR_GENERIC;
738 struct dt_test_gpio *gpios = NULL;
739
740 DT_TEST_MSG("Register GPIO controllers");
741
742 assert(gpio_ops_is_valid(&dt_test_gpio_ops));
743
744 gpios = dt_test_alloc(DT_TEST_GPIO_COUNT * sizeof(*gpios));
745 if (!gpios)
746 return TEE_ERROR_OUT_OF_MEMORY;
747
748 gpios[0].gpio_chip.ops = &dt_test_gpio_ops;
749 gpios[0].pin = DT_TEST_GPIO0_PIN;
750 gpios[0].flags = DT_TEST_GPIO0_FLAGS;
751
752 gpios[1].gpio_chip.ops = &dt_test_gpio_ops;
753 gpios[1].pin = DT_TEST_GPIO1_PIN;
754 gpios[1].flags = DT_TEST_GPIO1_FLAGS;
755
756 res = gpio_register_provider(fdt, offs, dt_test_gpio_get_dt, gpios);
757 if (res) {
758 dt_test_free(gpios);
759 return res;
760 }
761
762 return TEE_SUCCESS;
763 }
764
765 GPIO_DT_DECLARE(dt_test_gpio_provider, "linaro,dt-test-provider",
766 dt_test_gpio_provider_probe);
767 #endif /* CFG_DRIVERS_GPIO */
768