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