1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 4 * Copyright (c) 2017-2024, STMicroelectronics 5 */ 6 7 /* 8 * STM32 ETPZC acts as a firewall on stm32mp SoC peripheral interfaces and 9 * internal memories. The driver expects a single instance of the controller 10 * in the platform. 11 */ 12 13 #include <assert.h> 14 #include <drivers/clk_dt.h> 15 #include <drivers/stm32_etzpc.h> 16 #include <drivers/firewall.h> 17 #include <drivers/firewall_device.h> 18 #include <drivers/stm32mp_dt_bindings.h> 19 #include <initcall.h> 20 #include <io.h> 21 #include <keep.h> 22 #include <kernel/boot.h> 23 #include <kernel/dt.h> 24 #include <kernel/panic.h> 25 #include <kernel/pm.h> 26 #include <kernel/spinlock.h> 27 #include <kernel/tee_misc.h> 28 #include <libfdt.h> 29 #include <mm/core_memprot.h> 30 #include <mm/core_mmu.h> 31 #include <stm32_util.h> 32 #include <util.h> 33 34 /* ID Registers */ 35 #define ETZPC_TZMA0_SIZE U(0x000) 36 #define ETZPC_DECPROT0 U(0x010) 37 #define ETZPC_DECPROT_LOCK0 U(0x030) 38 #define ETZPC_HWCFGR U(0x3F0) 39 #define ETZPC_VERR U(0x3F4) 40 41 /* ID Registers fields */ 42 #define ETZPC_TZMA0_SIZE_LOCK BIT(31) 43 #define ETZPC_DECPROT0_MASK GENMASK_32(1, 0) 44 #define ETZPC_HWCFGR_NUM_TZMA_MASK GENMASK_32(7, 0) 45 #define ETZPC_HWCFGR_NUM_TZMA_SHIFT 0 46 #define ETZPC_HWCFGR_NUM_PER_SEC_MASK GENMASK_32(15, 8) 47 #define ETZPC_HWCFGR_NUM_PER_SEC_SHIFT 8 48 #define ETZPC_HWCFGR_NUM_AHB_SEC_MASK GENMASK_32(23, 16) 49 #define ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT 16 50 #define ETZPC_HWCFGR_CHUNKS1N4_MASK GENMASK_32(31, 24) 51 #define ETZPC_HWCFGR_CHUNKS1N4_SHIFT 24 52 53 #define DECPROT_SHIFT 1 54 #define IDS_PER_DECPROT_REGS U(16) 55 #define IDS_PER_DECPROT_LOCK_REGS U(32) 56 57 /* 58 * Implementation uses uint8_t to store each securable DECPROT configuration 59 * and uint16_t to store each securable TZMA configuration. When resuming 60 * from deep suspend, the DECPROT configurations are restored. 61 */ 62 #define PERIPH_PM_LOCK_BIT BIT(7) 63 #define PERIPH_PM_ATTR_MASK GENMASK_32(2, 0) 64 #define TZMA_PM_LOCK_BIT BIT(15) 65 #define TZMA_PM_VALUE_MASK GENMASK_32(9, 0) 66 67 /* 68 * struct stm32_etzpc_platdata - Driver data set at initialization 69 * 70 * @name: Name of the peripheral 71 * @clk: ETZPC clock 72 * @periph_cfg: Peripheral DECPROT configuration 73 * @tzma_cfg: TZMA configuration 74 * @base: ETZPC IOMEM base address 75 */ 76 struct stm32_etzpc_platdata { 77 char *name; 78 struct clk *clk; 79 uint8_t *periph_cfg; 80 uint16_t *tzma_cfg; 81 struct io_pa_va base; 82 }; 83 84 /* 85 * struct stm32_etzpc_driver_data - configuration data from the hardware 86 * 87 * @num_tzma: Number of TZMA zones, read from the hardware 88 * @num_per_sec: Number of securable AHB & APB periphs, read from the hardware 89 * @num_ahb_sec: Number of securable AHB master zones, read from the hardware 90 */ 91 struct stm32_etzpc_driver_data { 92 unsigned int num_tzma; 93 unsigned int num_per_sec; 94 unsigned int num_ahb_sec; 95 }; 96 97 /* 98 * struct etzpc_device - ETZPC device driver instance 99 * @pdata: Platform data set during initialization 100 * @ddata: Device configuration data from the hardware 101 * @lock: Access contention 102 */ 103 struct etzpc_device { 104 struct stm32_etzpc_platdata pdata; 105 struct stm32_etzpc_driver_data ddata; 106 unsigned int lock; 107 }; 108 109 static struct etzpc_device *etzpc_device; 110 111 static const char *const etzpc_decprot_strings[] __maybe_unused = { 112 "ETZPC_DECPROT_S_RW", 113 "ETZPC_DECPROT_NS_R_S_W", 114 "ETZPC_DECPROT_MCU_ISOLATION", 115 "ETZPC_DECPROT_NS_RW", 116 }; 117 118 static uint32_t etzpc_lock(void) 119 { 120 return cpu_spin_lock_xsave(&etzpc_device->lock); 121 } 122 123 static void etzpc_unlock(uint32_t exceptions) 124 { 125 cpu_spin_unlock_xrestore(&etzpc_device->lock, exceptions); 126 } 127 128 static bool valid_decprot_id(unsigned int id) 129 { 130 return id < etzpc_device->ddata.num_per_sec; 131 } 132 133 static bool __maybe_unused valid_tzma_id(unsigned int id) 134 { 135 return id < etzpc_device->ddata.num_tzma; 136 } 137 138 static enum etzpc_decprot_attributes etzpc_binding2decprot(uint32_t mode) 139 { 140 switch (mode) { 141 case DECPROT_S_RW: 142 return ETZPC_DECPROT_S_RW; 143 case DECPROT_NS_R_S_W: 144 return ETZPC_DECPROT_NS_R_S_W; 145 #ifdef CFG_STM32MP15 146 case DECPROT_MCU_ISOLATION: 147 return ETZPC_DECPROT_MCU_ISOLATION; 148 #endif 149 case DECPROT_NS_RW: 150 return ETZPC_DECPROT_NS_RW; 151 default: 152 panic(); 153 } 154 } 155 156 static void etzpc_configure_decprot(uint32_t decprot_id, 157 enum etzpc_decprot_attributes attr) 158 { 159 size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS); 160 uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; 161 uint32_t masked_decprot = (uint32_t)attr & ETZPC_DECPROT0_MASK; 162 vaddr_t base = etzpc_device->pdata.base.va; 163 unsigned int exceptions = 0; 164 165 assert(valid_decprot_id(decprot_id)); 166 167 FMSG("ID : %"PRIu32", config %i", decprot_id, attr); 168 169 exceptions = etzpc_lock(); 170 171 io_clrsetbits32(base + ETZPC_DECPROT0 + offset, 172 ETZPC_DECPROT0_MASK << shift, 173 masked_decprot << shift); 174 175 etzpc_unlock(exceptions); 176 } 177 178 enum etzpc_decprot_attributes etzpc_get_decprot(uint32_t decprot_id) 179 { 180 size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_REGS); 181 uint32_t shift = (decprot_id % IDS_PER_DECPROT_REGS) << DECPROT_SHIFT; 182 vaddr_t base = etzpc_device->pdata.base.va; 183 uint32_t value = 0; 184 185 assert(valid_decprot_id(decprot_id)); 186 187 value = (io_read32(base + ETZPC_DECPROT0 + offset) >> shift) & 188 ETZPC_DECPROT0_MASK; 189 190 return (enum etzpc_decprot_attributes)value; 191 } 192 193 static void etzpc_lock_decprot(uint32_t decprot_id) 194 { 195 size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS); 196 uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS); 197 vaddr_t base = etzpc_device->pdata.base.va; 198 uint32_t exceptions = 0; 199 200 assert(valid_decprot_id(decprot_id)); 201 202 exceptions = etzpc_lock(); 203 204 io_write32(base + offset + ETZPC_DECPROT_LOCK0, mask); 205 206 etzpc_unlock(exceptions); 207 } 208 209 static bool decprot_is_locked(uint32_t decprot_id) 210 { 211 size_t offset = U(4) * (decprot_id / IDS_PER_DECPROT_LOCK_REGS); 212 uint32_t mask = BIT(decprot_id % IDS_PER_DECPROT_LOCK_REGS); 213 vaddr_t base = etzpc_device->pdata.base.va; 214 215 assert(valid_decprot_id(decprot_id)); 216 217 return io_read32(base + offset + ETZPC_DECPROT_LOCK0) & mask; 218 } 219 220 void etzpc_configure_tzma(uint32_t tzma_id, uint16_t tzma_value) 221 { 222 size_t offset = sizeof(uint32_t) * tzma_id; 223 vaddr_t base = etzpc_device->pdata.base.va; 224 uint32_t exceptions = 0; 225 226 assert(valid_tzma_id(tzma_id)); 227 228 exceptions = etzpc_lock(); 229 230 io_write32(base + ETZPC_TZMA0_SIZE + offset, tzma_value); 231 232 etzpc_unlock(exceptions); 233 } 234 235 static uint16_t etzpc_get_tzma(uint32_t tzma_id) 236 { 237 size_t offset = sizeof(uint32_t) * tzma_id; 238 vaddr_t base = etzpc_device->pdata.base.va; 239 240 assert(valid_tzma_id(tzma_id)); 241 242 return io_read32(base + ETZPC_TZMA0_SIZE + offset); 243 } 244 245 static void etzpc_lock_tzma(uint32_t tzma_id) 246 { 247 size_t offset = sizeof(uint32_t) * tzma_id; 248 vaddr_t base = etzpc_device->pdata.base.va; 249 uint32_t exceptions = 0; 250 251 assert(valid_tzma_id(tzma_id)); 252 253 exceptions = etzpc_lock(); 254 255 io_setbits32(base + ETZPC_TZMA0_SIZE + offset, ETZPC_TZMA0_SIZE_LOCK); 256 257 etzpc_unlock(exceptions); 258 } 259 260 static bool tzma_is_locked(uint32_t tzma_id) 261 { 262 size_t offset = sizeof(uint32_t) * tzma_id; 263 vaddr_t base = etzpc_device->pdata.base.va; 264 265 assert(valid_tzma_id(tzma_id)); 266 267 return io_read32(base + ETZPC_TZMA0_SIZE + offset) & 268 ETZPC_TZMA0_SIZE_LOCK; 269 } 270 271 static TEE_Result etzpc_pm(enum pm_op op, unsigned int pm_hint __unused, 272 const struct pm_callback_handle *pm_handle __unused) 273 { 274 struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata; 275 struct stm32_etzpc_platdata *pdata = &etzpc_device->pdata; 276 unsigned int n = 0; 277 278 if (op == PM_OP_SUSPEND) { 279 for (n = 0; n < ddata->num_per_sec; n++) { 280 pdata->periph_cfg[n] = 281 (uint8_t)etzpc_get_decprot(n); 282 if (decprot_is_locked(n)) 283 pdata->periph_cfg[n] |= PERIPH_PM_LOCK_BIT; 284 } 285 286 for (n = 0; n < ddata->num_tzma; n++) { 287 pdata->tzma_cfg[n] = 288 (uint8_t)etzpc_get_tzma(n); 289 if (tzma_is_locked(n)) 290 pdata->tzma_cfg[n] |= TZMA_PM_LOCK_BIT; 291 } 292 293 return TEE_SUCCESS; 294 } 295 296 /* PM_OP_RESUME */ 297 for (n = 0; n < ddata->num_per_sec; n++) { 298 unsigned int attr = pdata->periph_cfg[n] & PERIPH_PM_ATTR_MASK; 299 300 etzpc_configure_decprot(n, (enum etzpc_decprot_attributes)attr); 301 302 if (pdata->periph_cfg[n] & PERIPH_PM_LOCK_BIT) 303 etzpc_lock_decprot(n); 304 } 305 306 for (n = 0; n < ddata->num_tzma; n++) { 307 uint16_t value = pdata->tzma_cfg[n] & TZMA_PM_VALUE_MASK; 308 309 etzpc_configure_tzma(n, value); 310 311 if (pdata->tzma_cfg[n] & TZMA_PM_LOCK_BIT) 312 etzpc_lock_tzma(n); 313 } 314 315 return TEE_SUCCESS; 316 } 317 DECLARE_KEEP_PAGER(etzpc_pm); 318 319 static TEE_Result stm32_etzpc_acquire_access(struct firewall_query *firewall) 320 { 321 enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MCU_ISOLATION; 322 uint32_t id = 0; 323 324 if (!firewall || firewall->arg_count != 1) 325 return TEE_ERROR_BAD_PARAMETERS; 326 327 id = firewall->args[0] & ETZPC_ID_MASK; 328 if (id < etzpc_device->ddata.num_per_sec) { 329 attr = etzpc_get_decprot(id); 330 if (attr != ETZPC_DECPROT_S_RW && 331 attr != ETZPC_DECPROT_NS_R_S_W) 332 return TEE_ERROR_ACCESS_DENIED; 333 } else { 334 return TEE_ERROR_BAD_PARAMETERS; 335 } 336 337 return TEE_SUCCESS; 338 } 339 340 static TEE_Result 341 stm32_etzpc_acquire_memory_access(struct firewall_query *firewall, 342 paddr_t paddr, size_t size, 343 bool read __unused, bool write __unused) 344 { 345 paddr_t tzma_base = 0; 346 size_t prot_size = 0; 347 uint32_t id = 0; 348 349 if (!firewall || firewall->arg_count != 1) 350 return TEE_ERROR_BAD_PARAMETERS; 351 352 id = firewall->args[0] & ETZPC_ID_MASK; 353 switch (id) { 354 case ETZPC_TZMA0_ID: 355 tzma_base = ROM_BASE; 356 prot_size = etzpc_get_tzma(0) * SMALL_PAGE_SIZE; 357 break; 358 case ETZPC_TZMA1_ID: 359 tzma_base = SYSRAM_BASE; 360 prot_size = etzpc_get_tzma(1) * SMALL_PAGE_SIZE; 361 break; 362 default: 363 return TEE_ERROR_BAD_PARAMETERS; 364 } 365 366 DMSG("Acquiring access for TZMA%u, secured from %#"PRIxPA" to %#"PRIxPA, 367 id == ETZPC_TZMA0_ID ? 0 : 1, tzma_base, tzma_base + prot_size); 368 369 if (core_is_buffer_inside(paddr, size, tzma_base, prot_size)) 370 return TEE_SUCCESS; 371 372 return TEE_ERROR_ACCESS_DENIED; 373 } 374 375 static TEE_Result stm32_etzpc_configure(struct firewall_query *firewall) 376 { 377 enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; 378 uint32_t id = 0; 379 380 if (firewall->arg_count != 1) 381 return TEE_ERROR_BAD_PARAMETERS; 382 383 id = firewall->args[0] & ETZPC_ID_MASK; 384 385 if (id < etzpc_device->ddata.num_per_sec) { 386 uint32_t mode = 0; 387 388 /* 389 * Peripheral configuration, we assume the configuration is as 390 * follows: 391 * firewall->args[0]: Firewall configuration to apply 392 */ 393 394 mode = (firewall->args[0] & ETZPC_MODE_MASK) >> 395 ETZPC_MODE_SHIFT; 396 attr = etzpc_binding2decprot(mode); 397 398 if (decprot_is_locked(id)) { 399 EMSG("Peripheral configuration locked"); 400 return TEE_ERROR_ACCESS_DENIED; 401 } 402 403 DMSG("Setting access config for periph %"PRIu32" - attr %s", id, 404 etzpc_decprot_strings[attr]); 405 406 etzpc_configure_decprot(id, attr); 407 if (firewall->args[0] & ETZPC_LOCK_MASK) 408 etzpc_lock_decprot(id); 409 410 return TEE_SUCCESS; 411 } 412 EMSG("Unknown firewall ID: %"PRIu32, id); 413 414 return TEE_ERROR_BAD_PARAMETERS; 415 } 416 417 static void stm32_etzpc_set_driverdata(void) 418 { 419 struct stm32_etzpc_driver_data *ddata = &etzpc_device->ddata; 420 vaddr_t base = etzpc_device->pdata.base.va; 421 uint32_t reg = io_read32(base + ETZPC_HWCFGR); 422 423 ddata->num_tzma = (reg & ETZPC_HWCFGR_NUM_TZMA_MASK) >> 424 ETZPC_HWCFGR_NUM_TZMA_SHIFT; 425 ddata->num_per_sec = (reg & ETZPC_HWCFGR_NUM_PER_SEC_MASK) >> 426 ETZPC_HWCFGR_NUM_PER_SEC_SHIFT; 427 ddata->num_ahb_sec = (reg & ETZPC_HWCFGR_NUM_AHB_SEC_MASK) >> 428 ETZPC_HWCFGR_NUM_AHB_SEC_SHIFT; 429 430 DMSG("ETZPC revision 0x%02"PRIx8", per_sec %u, ahb_sec %u, tzma %u", 431 io_read8(base + ETZPC_VERR), 432 ddata->num_per_sec, ddata->num_ahb_sec, ddata->num_tzma); 433 } 434 435 static void fdt_etzpc_conf_decprot(const void *fdt, int node) 436 { 437 const fdt32_t *cuint = NULL; 438 size_t i = 0; 439 int len = 0; 440 441 cuint = fdt_getprop(fdt, node, "st,decprot", &len); 442 if (!cuint) { 443 DMSG("No ETZPC DECPROT configuration in DT"); 444 return; 445 } 446 447 clk_enable(etzpc_device->pdata.clk); 448 449 for (i = 0; i < len / sizeof(uint32_t); i++) { 450 uint32_t value = fdt32_to_cpu(cuint[i]); 451 uint32_t id = value & ETZPC_ID_MASK; 452 uint32_t mode = (value & ETZPC_MODE_MASK) >> ETZPC_MODE_SHIFT; 453 bool lock = value & ETZPC_LOCK_MASK; 454 enum etzpc_decprot_attributes attr = ETZPC_DECPROT_MAX; 455 456 if (!valid_decprot_id(id)) { 457 DMSG("Invalid DECPROT %"PRIu32, id); 458 panic(); 459 } 460 461 attr = etzpc_binding2decprot(mode); 462 etzpc_configure_decprot(id, attr); 463 464 if (lock) 465 etzpc_lock_decprot(id); 466 } 467 468 clk_disable(etzpc_device->pdata.clk); 469 } 470 471 static TEE_Result 472 stm32_etzpc_dt_probe_bus(const void *fdt, int node, 473 struct firewall_controller *ctrl __maybe_unused) 474 { 475 TEE_Result res = TEE_ERROR_GENERIC; 476 struct firewall_query *fw = NULL; 477 int subnode = 0; 478 479 DMSG("Populating %s firewall bus", ctrl->name); 480 481 fdt_for_each_subnode(subnode, fdt, node) { 482 unsigned int i = 0; 483 484 if (fdt_get_status(fdt, subnode) == DT_STATUS_DISABLED) 485 continue; 486 487 if (IS_ENABLED(CFG_INSECURE) && 488 stm32mp_allow_probe_shared_device(fdt, subnode)) { 489 DMSG("Skipping firewall attributes check for %s", 490 fdt_get_name(fdt, subnode, NULL)); 491 goto skip_check; 492 } 493 494 DMSG("Acquiring firewall access for %s when probing bus", 495 fdt_get_name(fdt, subnode, NULL)); 496 497 do { 498 /* 499 * The access-controllers property is mandatory for 500 * firewall bus devices 501 */ 502 res = firewall_dt_get_by_index(fdt, subnode, i, &fw); 503 if (res == TEE_ERROR_ITEM_NOT_FOUND) { 504 /* Stop when nothing more to parse */ 505 break; 506 } else if (res) { 507 EMSG("%s: Error on node %s: %#"PRIx32, 508 ctrl->name, 509 fdt_get_name(fdt, subnode, NULL), res); 510 panic(); 511 } 512 513 res = firewall_acquire_access(fw); 514 if (res) { 515 EMSG("%s: %s not accessible: %#"PRIx32, 516 ctrl->name, 517 fdt_get_name(fdt, subnode, NULL), res); 518 panic(); 519 } 520 521 firewall_put(fw); 522 i++; 523 } while (true); 524 525 skip_check: 526 res = dt_driver_maybe_add_probe_node(fdt, subnode); 527 if (res) { 528 EMSG("Failed on node %s with %#"PRIx32, 529 fdt_get_name(fdt, subnode, NULL), res); 530 panic(); 531 } 532 } 533 534 return TEE_SUCCESS; 535 } 536 537 static TEE_Result init_etzpc_from_dt(const void *fdt, int node) 538 { 539 TEE_Result res = TEE_ERROR_GENERIC; 540 struct dt_node_info etzpc_info = { }; 541 int len = 0; 542 543 fdt_fill_device_info(fdt, &etzpc_info, node); 544 if (etzpc_info.reg == DT_INFO_INVALID_REG || 545 etzpc_info.reg_size == DT_INFO_INVALID_REG_SIZE) 546 return TEE_ERROR_ITEM_NOT_FOUND; 547 548 etzpc_device->pdata.base.pa = etzpc_info.reg; 549 etzpc_device->pdata.name = strdup(fdt_get_name(fdt, node, &len)); 550 io_pa_or_va_secure(&etzpc_device->pdata.base, etzpc_info.reg_size); 551 res = clk_dt_get_by_index(fdt, node, 0, &etzpc_device->pdata.clk); 552 if (res) 553 return res; 554 555 stm32_etzpc_set_driverdata(); 556 557 etzpc_device->pdata.periph_cfg = 558 calloc(etzpc_device->ddata.num_per_sec, 559 sizeof(*etzpc_device->pdata.periph_cfg)); 560 if (!etzpc_device->pdata.periph_cfg) 561 return TEE_ERROR_OUT_OF_MEMORY; 562 563 etzpc_device->pdata.tzma_cfg = 564 calloc(etzpc_device->ddata.num_tzma, 565 sizeof(*etzpc_device->pdata.tzma_cfg)); 566 if (!etzpc_device->pdata.tzma_cfg) { 567 free(etzpc_device->pdata.periph_cfg); 568 return TEE_ERROR_OUT_OF_MEMORY; 569 } 570 571 return TEE_SUCCESS; 572 } 573 574 static const struct firewall_controller_ops firewall_ops = { 575 .set_conf = stm32_etzpc_configure, 576 .acquire_access = stm32_etzpc_acquire_access, 577 .acquire_memory_access = stm32_etzpc_acquire_memory_access, 578 }; 579 580 static TEE_Result stm32_etzpc_probe(const void *fdt, int node, 581 const void *compat_data __unused) 582 { 583 TEE_Result res = TEE_ERROR_GENERIC; 584 struct firewall_controller *controller = NULL; 585 586 etzpc_device = calloc(1, sizeof(*etzpc_device)); 587 if (!etzpc_device) 588 panic(); 589 590 res = init_etzpc_from_dt(fdt, node); 591 if (res) { 592 free(etzpc_device->pdata.periph_cfg); 593 free(etzpc_device->pdata.tzma_cfg); 594 free(etzpc_device->pdata.name); 595 free(etzpc_device); 596 free(controller); 597 return res; 598 } 599 600 controller = calloc(1, sizeof(*controller)); 601 if (!controller) 602 panic(); 603 604 controller->base = &etzpc_device->pdata.base; 605 controller->name = etzpc_device->pdata.name; 606 controller->priv = etzpc_device; 607 controller->ops = &firewall_ops; 608 609 res = firewall_dt_controller_register(fdt, node, controller); 610 if (res) 611 panic("Cannot register ETZPC as a firewall controller"); 612 613 fdt_etzpc_conf_decprot(fdt, node); 614 615 res = stm32_etzpc_dt_probe_bus(fdt, node, controller); 616 if (res) 617 panic("Cannot populate bus"); 618 619 register_pm_core_service_cb(etzpc_pm, NULL, "stm32-etzpc"); 620 621 return TEE_SUCCESS; 622 } 623 624 static const struct dt_device_match etzpc_match_table[] = { 625 { .compatible = "st,stm32-etzpc" }, 626 { } 627 }; 628 629 DEFINE_DT_DRIVER(etzpc_dt_driver) = { 630 .name = "stm32-etzpc", 631 .match_table = etzpc_match_table, 632 .probe = stm32_etzpc_probe, 633 }; 634