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 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 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 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 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 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 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 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 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_get_by_index(fdt, node, 0, "test", &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_get_by_index(fdt, node, 1, "test", &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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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