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