1*69b8b983SEtienne Carriere // SPDX-License-Identifier: BSD-3-Clause 2*69b8b983SEtienne Carriere /* 3*69b8b983SEtienne Carriere * Copyright (c) 2021-2022, STMicroelectronics 4*69b8b983SEtienne Carriere */ 5*69b8b983SEtienne Carriere 6*69b8b983SEtienne Carriere #include <drivers/clk.h> 7*69b8b983SEtienne Carriere #include <drivers/clk_dt.h> 8*69b8b983SEtienne Carriere #include <drivers/stm32_tamp.h> 9*69b8b983SEtienne Carriere #include <io.h> 10*69b8b983SEtienne Carriere #include <kernel/dt.h> 11*69b8b983SEtienne Carriere #include <kernel/interrupt.h> 12*69b8b983SEtienne Carriere #include <libfdt.h> 13*69b8b983SEtienne Carriere #include <mm/core_memprot.h> 14*69b8b983SEtienne Carriere #include <stdbool.h> 15*69b8b983SEtienne Carriere 16*69b8b983SEtienne Carriere /* STM32 Registers */ 17*69b8b983SEtienne Carriere #define _TAMP_CR1 0x00U 18*69b8b983SEtienne Carriere #define _TAMP_CR2 0x04U 19*69b8b983SEtienne Carriere #define _TAMP_CR3 0x08U 20*69b8b983SEtienne Carriere #define _TAMP_FLTCR 0x0CU 21*69b8b983SEtienne Carriere #define _TAMP_ATCR1 0x10U 22*69b8b983SEtienne Carriere #define _TAMP_ATSEEDR 0x14U 23*69b8b983SEtienne Carriere #define _TAMP_ATOR 0x18U 24*69b8b983SEtienne Carriere #define _TAMP_ATCR2 0x1CU 25*69b8b983SEtienne Carriere #define _TAMP_SECCFGR 0x20U 26*69b8b983SEtienne Carriere #define _TAMP_SMCR 0x20U 27*69b8b983SEtienne Carriere #define _TAMP_PRIVCFGR 0x24U 28*69b8b983SEtienne Carriere #define _TAMP_IER 0x2CU 29*69b8b983SEtienne Carriere #define _TAMP_SR 0x30U 30*69b8b983SEtienne Carriere #define _TAMP_MISR 0x34U 31*69b8b983SEtienne Carriere #define _TAMP_SMISR 0x38U 32*69b8b983SEtienne Carriere #define _TAMP_SCR 0x3CU 33*69b8b983SEtienne Carriere #define _TAMP_COUNTR 0x40U 34*69b8b983SEtienne Carriere #define _TAMP_COUNT2R 0x44U 35*69b8b983SEtienne Carriere #define _TAMP_OR 0x50U 36*69b8b983SEtienne Carriere #define _TAMP_ERCFGR 0X54U 37*69b8b983SEtienne Carriere #define _TAMP_HWCFGR2 0x3ECU 38*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1 0x3F0U 39*69b8b983SEtienne Carriere #define _TAMP_VERR 0x3F4U 40*69b8b983SEtienne Carriere #define _TAMP_IPIDR 0x3F8U 41*69b8b983SEtienne Carriere #define _TAMP_SIDR 0x3FCU 42*69b8b983SEtienne Carriere 43*69b8b983SEtienne Carriere /* _TAMP_SECCFGR bit fields */ 44*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BKPRWSEC_MASK GENMASK_32(7, 0) 45*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BKPRWSEC_SHIFT 0U 46*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_CNT2SEC BIT(14) 47*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_CNT1SEC BIT(15) 48*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BKPWSEC_MASK GENMASK_32(23, 16) 49*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BKPWSEC_SHIFT 16U 50*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BHKLOCK BIT(30) 51*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_TAMPSEC BIT(31) 52*69b8b983SEtienne Carriere #define _TAMP_SECCFGR_BUT_BKP_MASK (GENMASK_32(31, 30) | \ 53*69b8b983SEtienne Carriere GENMASK_32(15, 14)) 54*69b8b983SEtienne Carriere 55*69b8b983SEtienne Carriere /* _TAMP_SMCR bit fields */ 56*69b8b983SEtienne Carriere #define _TAMP_SMCR_BKPRWDPROT_MASK GENMASK_32(7, 0) 57*69b8b983SEtienne Carriere #define _TAMP_SMCR_BKPRWDPROT_SHIFT 0U 58*69b8b983SEtienne Carriere #define _TAMP_SMCR_BKPWDPROT_MASK GENMASK_32(23, 16) 59*69b8b983SEtienne Carriere #define _TAMP_SMCR_BKPWDPROT_SHIFT 16U 60*69b8b983SEtienne Carriere #define _TAMP_SMCR_DPROT BIT(31) 61*69b8b983SEtienne Carriere /* 62*69b8b983SEtienne Carriere * _TAMP_PRIVCFGR bit fields 63*69b8b983SEtienne Carriere */ 64*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_CNT2PRIV BIT(14) 65*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_CNT1PRIV BIT(15) 66*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_BKPRWPRIV BIT(29) 67*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_BKPWPRIV BIT(30) 68*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_TAMPPRIV BIT(31) 69*69b8b983SEtienne Carriere #define _TAMP_PRIVCFGR_MASK (GENMASK_32(31, 29) | \ 70*69b8b983SEtienne Carriere GENMASK_32(15, 14)) 71*69b8b983SEtienne Carriere 72*69b8b983SEtienne Carriere /* 73*69b8b983SEtienne Carriere * _TAMP_PRIVCFGR bit fields 74*69b8b983SEtienne Carriere */ 75*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_CNT2PRIV BIT(14) 76*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_CNT1PRIV BIT(15) 77*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_BKPRWPRIV BIT(29) 78*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_BKPWPRIV BIT(30) 79*69b8b983SEtienne Carriere #define _TAMP_PRIVCFG_TAMPPRIV BIT(31) 80*69b8b983SEtienne Carriere #define _TAMP_PRIVCFGR_MASK (GENMASK_32(31, 29) | \ 81*69b8b983SEtienne Carriere GENMASK_32(15, 14)) 82*69b8b983SEtienne Carriere 83*69b8b983SEtienne Carriere /* _TAMP_HWCFGR2 bit fields */ 84*69b8b983SEtienne Carriere #define _TAMP_HWCFGR2_TZ GENMASK_32(11, 8) 85*69b8b983SEtienne Carriere #define _TAMP_HWCFGR2_OR GENMASK_32(7, 0) 86*69b8b983SEtienne Carriere 87*69b8b983SEtienne Carriere /* _TAMP_HWCFGR1 bit fields */ 88*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_BKPREG GENMASK_32(7, 0) 89*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_TAMPER GENMASK_32(11, 8) 90*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_ACTIVE GENMASK_32(15, 12) 91*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_INTERN GENMASK_32(31, 16) 92*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_ITAMP_MAX_ID 16U 93*69b8b983SEtienne Carriere #define _TAMP_HWCFGR1_ITAMP(id) BIT((id) - INT_TAMP1 + 16U) 94*69b8b983SEtienne Carriere 95*69b8b983SEtienne Carriere /* _TAMP_VERR bit fields */ 96*69b8b983SEtienne Carriere #define _TAMP_VERR_MINREV GENMASK_32(3, 0) 97*69b8b983SEtienne Carriere #define _TAMP_VERR_MAJREV GENMASK_32(7, 4) 98*69b8b983SEtienne Carriere 99*69b8b983SEtienne Carriere /* 100*69b8b983SEtienne Carriere * TAMP instance data 101*69b8b983SEtienne Carriere * @base - IOMEM base address 102*69b8b983SEtienne Carriere * @clock - TAMP clock 103*69b8b983SEtienne Carriere * @it - TAMP interrupt number 104*69b8b983SEtienne Carriere * @hwconf1 - Copy of TAMP HWCONF1 register content 105*69b8b983SEtienne Carriere * @hwconf2 - Copy of TAMP HWCONF2 register content 106*69b8b983SEtienne Carriere * @compat - Reference to compat data passed at driver initialization 107*69b8b983SEtienne Carriere */ 108*69b8b983SEtienne Carriere struct stm32_tamp_instance { 109*69b8b983SEtienne Carriere struct io_pa_va base; 110*69b8b983SEtienne Carriere struct clk *clock; 111*69b8b983SEtienne Carriere int it; 112*69b8b983SEtienne Carriere uint32_t hwconf1; 113*69b8b983SEtienne Carriere uint32_t hwconf2; 114*69b8b983SEtienne Carriere struct stm32_tamp_compat *compat; 115*69b8b983SEtienne Carriere }; 116*69b8b983SEtienne Carriere 117*69b8b983SEtienne Carriere /* 118*69b8b983SEtienne Carriere * Compatibility capabilities 119*69b8b983SEtienne Carriere * TAMP_HAS_REGISTER_SECCFG - Supports SECCFGR, otherwise supports SMCR register 120*69b8b983SEtienne Carriere * TAMP_HAS_REGISTER_PRIVCFG - Supports PRIVCFGR configuration register 121*69b8b983SEtienne Carriere */ 122*69b8b983SEtienne Carriere #define TAMP_HAS_REGISTER_SECCFG BIT(0) 123*69b8b983SEtienne Carriere #define TAMP_HAS_REGISTER_PRIVCFGR BIT(1) 124*69b8b983SEtienne Carriere 125*69b8b983SEtienne Carriere /* 126*69b8b983SEtienne Carriere * @nb_monotonic_counter - Number of monotic counter supported 127*69b8b983SEtienne Carriere * @tags - Bit flags TAMP_HAS_* for compatibily management 128*69b8b983SEtienne Carriere */ 129*69b8b983SEtienne Carriere struct stm32_tamp_compat { 130*69b8b983SEtienne Carriere int nb_monotonic_counter; 131*69b8b983SEtienne Carriere uint32_t tags; 132*69b8b983SEtienne Carriere }; 133*69b8b983SEtienne Carriere 134*69b8b983SEtienne Carriere /* Expects at most a single instance */ 135*69b8b983SEtienne Carriere static struct stm32_tamp_instance *stm32_tamp_device; 136*69b8b983SEtienne Carriere 137*69b8b983SEtienne Carriere TEE_Result stm32_tamp_set_secure_bkpregs(struct stm32_bkpregs_conf *bkr_conf) 138*69b8b983SEtienne Carriere { 139*69b8b983SEtienne Carriere struct stm32_tamp_instance *tamp = stm32_tamp_device; 140*69b8b983SEtienne Carriere vaddr_t base = 0; 141*69b8b983SEtienne Carriere uint32_t first_z2 = 0; 142*69b8b983SEtienne Carriere uint32_t first_z3 = 0; 143*69b8b983SEtienne Carriere 144*69b8b983SEtienne Carriere if (!tamp) 145*69b8b983SEtienne Carriere return TEE_ERROR_DEFER_DRIVER_INIT; 146*69b8b983SEtienne Carriere 147*69b8b983SEtienne Carriere if (!bkr_conf) 148*69b8b983SEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 149*69b8b983SEtienne Carriere 150*69b8b983SEtienne Carriere base = io_pa_or_va(&tamp->base, 1); 151*69b8b983SEtienne Carriere 152*69b8b983SEtienne Carriere first_z2 = bkr_conf->nb_zone1_regs; 153*69b8b983SEtienne Carriere first_z3 = bkr_conf->nb_zone1_regs + bkr_conf->nb_zone2_regs; 154*69b8b983SEtienne Carriere 155*69b8b983SEtienne Carriere if ((first_z2 > (tamp->hwconf1 & _TAMP_HWCFGR1_BKPREG)) || 156*69b8b983SEtienne Carriere (first_z3 > (tamp->hwconf1 & _TAMP_HWCFGR1_BKPREG))) 157*69b8b983SEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 158*69b8b983SEtienne Carriere 159*69b8b983SEtienne Carriere if (tamp->compat && (tamp->compat->tags & TAMP_HAS_REGISTER_SECCFG)) { 160*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_SECCFGR, 161*69b8b983SEtienne Carriere _TAMP_SECCFGR_BKPRWSEC_MASK, 162*69b8b983SEtienne Carriere (first_z2 << _TAMP_SECCFGR_BKPRWSEC_SHIFT) & 163*69b8b983SEtienne Carriere _TAMP_SECCFGR_BKPRWSEC_MASK); 164*69b8b983SEtienne Carriere 165*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_SECCFGR, 166*69b8b983SEtienne Carriere _TAMP_SECCFGR_BKPWSEC_MASK, 167*69b8b983SEtienne Carriere (first_z3 << _TAMP_SECCFGR_BKPWSEC_SHIFT) & 168*69b8b983SEtienne Carriere _TAMP_SECCFGR_BKPWSEC_MASK); 169*69b8b983SEtienne Carriere } else { 170*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_SMCR, 171*69b8b983SEtienne Carriere _TAMP_SMCR_BKPRWDPROT_MASK, 172*69b8b983SEtienne Carriere (first_z2 << _TAMP_SMCR_BKPRWDPROT_SHIFT) & 173*69b8b983SEtienne Carriere _TAMP_SMCR_BKPRWDPROT_MASK); 174*69b8b983SEtienne Carriere 175*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_SMCR, 176*69b8b983SEtienne Carriere _TAMP_SMCR_BKPWDPROT_MASK, 177*69b8b983SEtienne Carriere (first_z3 << _TAMP_SMCR_BKPWDPROT_SHIFT) & 178*69b8b983SEtienne Carriere _TAMP_SMCR_BKPWDPROT_MASK); 179*69b8b983SEtienne Carriere } 180*69b8b983SEtienne Carriere 181*69b8b983SEtienne Carriere return TEE_SUCCESS; 182*69b8b983SEtienne Carriere } 183*69b8b983SEtienne Carriere 184*69b8b983SEtienne Carriere static void stm32_tamp_set_secure(struct stm32_tamp_instance *tamp, 185*69b8b983SEtienne Carriere uint32_t mode) 186*69b8b983SEtienne Carriere { 187*69b8b983SEtienne Carriere vaddr_t base = io_pa_or_va(&tamp->base, 1); 188*69b8b983SEtienne Carriere 189*69b8b983SEtienne Carriere if (tamp->compat && (tamp->compat->tags & TAMP_HAS_REGISTER_SECCFG)) { 190*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_SECCFGR, 191*69b8b983SEtienne Carriere _TAMP_SECCFGR_BUT_BKP_MASK, 192*69b8b983SEtienne Carriere mode & _TAMP_SECCFGR_BUT_BKP_MASK); 193*69b8b983SEtienne Carriere } else { 194*69b8b983SEtienne Carriere /* 195*69b8b983SEtienne Carriere * Note: MP15 doesn't use SECCFG register and 196*69b8b983SEtienne Carriere * inverts the secure bit. 197*69b8b983SEtienne Carriere */ 198*69b8b983SEtienne Carriere if (mode & _TAMP_SECCFGR_TAMPSEC) 199*69b8b983SEtienne Carriere io_clrbits32(base + _TAMP_SMCR, _TAMP_SMCR_DPROT); 200*69b8b983SEtienne Carriere else 201*69b8b983SEtienne Carriere io_setbits32(base + _TAMP_SMCR, _TAMP_SMCR_DPROT); 202*69b8b983SEtienne Carriere } 203*69b8b983SEtienne Carriere } 204*69b8b983SEtienne Carriere 205*69b8b983SEtienne Carriere static void stm32_tamp_set_privilege(struct stm32_tamp_instance *tamp, 206*69b8b983SEtienne Carriere uint32_t mode) 207*69b8b983SEtienne Carriere { 208*69b8b983SEtienne Carriere vaddr_t base = io_pa_or_va(&tamp->base, 1); 209*69b8b983SEtienne Carriere 210*69b8b983SEtienne Carriere if (tamp->compat && (tamp->compat->tags & TAMP_HAS_REGISTER_PRIVCFGR)) 211*69b8b983SEtienne Carriere io_clrsetbits32(base + _TAMP_PRIVCFGR, _TAMP_PRIVCFGR_MASK, 212*69b8b983SEtienne Carriere mode & _TAMP_PRIVCFGR_MASK); 213*69b8b983SEtienne Carriere } 214*69b8b983SEtienne Carriere 215*69b8b983SEtienne Carriere static TEE_Result stm32_tamp_parse_fdt(struct stm32_tamp_instance *tamp, 216*69b8b983SEtienne Carriere const void *fdt, int node, 217*69b8b983SEtienne Carriere const void *compat) 218*69b8b983SEtienne Carriere { 219*69b8b983SEtienne Carriere struct dt_node_info dt_tamp = { }; 220*69b8b983SEtienne Carriere 221*69b8b983SEtienne Carriere _fdt_fill_device_info(fdt, &dt_tamp, node); 222*69b8b983SEtienne Carriere 223*69b8b983SEtienne Carriere if (dt_tamp.reg == DT_INFO_INVALID_REG || 224*69b8b983SEtienne Carriere dt_tamp.reg_size == DT_INFO_INVALID_REG_SIZE) 225*69b8b983SEtienne Carriere return TEE_ERROR_BAD_PARAMETERS; 226*69b8b983SEtienne Carriere 227*69b8b983SEtienne Carriere tamp->compat = (struct stm32_tamp_compat *)compat; 228*69b8b983SEtienne Carriere tamp->it = dt_tamp.interrupt; 229*69b8b983SEtienne Carriere tamp->base.pa = dt_tamp.reg; 230*69b8b983SEtienne Carriere io_pa_or_va_secure(&tamp->base, dt_tamp.reg_size); 231*69b8b983SEtienne Carriere 232*69b8b983SEtienne Carriere return clk_dt_get_by_index(fdt, node, 0, &tamp->clock); 233*69b8b983SEtienne Carriere } 234*69b8b983SEtienne Carriere 235*69b8b983SEtienne Carriere static TEE_Result stm32_tamp_probe(const void *fdt, int node, 236*69b8b983SEtienne Carriere const void *compat_data) 237*69b8b983SEtienne Carriere { 238*69b8b983SEtienne Carriere struct stm32_tamp_instance *tamp = NULL; 239*69b8b983SEtienne Carriere uint32_t __maybe_unused revision = 0; 240*69b8b983SEtienne Carriere TEE_Result res = TEE_SUCCESS; 241*69b8b983SEtienne Carriere vaddr_t base = 0; 242*69b8b983SEtienne Carriere 243*69b8b983SEtienne Carriere tamp = calloc(1, sizeof(*tamp)); 244*69b8b983SEtienne Carriere if (!tamp) 245*69b8b983SEtienne Carriere return TEE_ERROR_OUT_OF_MEMORY; 246*69b8b983SEtienne Carriere 247*69b8b983SEtienne Carriere res = stm32_tamp_parse_fdt(tamp, fdt, node, compat_data); 248*69b8b983SEtienne Carriere if (res) 249*69b8b983SEtienne Carriere goto err; 250*69b8b983SEtienne Carriere 251*69b8b983SEtienne Carriere clk_enable(tamp->clock); 252*69b8b983SEtienne Carriere 253*69b8b983SEtienne Carriere base = io_pa_or_va(&tamp->base, 1); 254*69b8b983SEtienne Carriere 255*69b8b983SEtienne Carriere tamp->hwconf1 = io_read32(base + _TAMP_HWCFGR1); 256*69b8b983SEtienne Carriere tamp->hwconf2 = io_read32(base + _TAMP_HWCFGR2); 257*69b8b983SEtienne Carriere 258*69b8b983SEtienne Carriere revision = io_read32(base + _TAMP_VERR); 259*69b8b983SEtienne Carriere FMSG("STM32 TAMPER V%"PRIx32".%"PRIu32, 260*69b8b983SEtienne Carriere (revision & _TAMP_VERR_MAJREV) >> 4, revision & _TAMP_VERR_MINREV); 261*69b8b983SEtienne Carriere 262*69b8b983SEtienne Carriere if (!(tamp->hwconf2 & _TAMP_HWCFGR2_TZ)) { 263*69b8b983SEtienne Carriere EMSG("TAMP doesn't support TrustZone"); 264*69b8b983SEtienne Carriere res = TEE_ERROR_NOT_SUPPORTED; 265*69b8b983SEtienne Carriere goto err_clk; 266*69b8b983SEtienne Carriere } 267*69b8b983SEtienne Carriere 268*69b8b983SEtienne Carriere /* 269*69b8b983SEtienne Carriere * Enforce secure only access to protected TAMP registers. 270*69b8b983SEtienne Carriere * Allow non-secure access to monotonic counter. 271*69b8b983SEtienne Carriere */ 272*69b8b983SEtienne Carriere stm32_tamp_set_secure(tamp, _TAMP_SECCFGR_TAMPSEC); 273*69b8b983SEtienne Carriere 274*69b8b983SEtienne Carriere /* 275*69b8b983SEtienne Carriere * Enforce privilege only access to TAMP registers, backup 276*69b8b983SEtienne Carriere * registers and monotonic counter. 277*69b8b983SEtienne Carriere */ 278*69b8b983SEtienne Carriere stm32_tamp_set_privilege(tamp, _TAMP_PRIVCFG_TAMPPRIV | 279*69b8b983SEtienne Carriere _TAMP_PRIVCFG_BKPRWPRIV | 280*69b8b983SEtienne Carriere _TAMP_PRIVCFG_BKPWPRIV); 281*69b8b983SEtienne Carriere 282*69b8b983SEtienne Carriere stm32_tamp_device = tamp; 283*69b8b983SEtienne Carriere 284*69b8b983SEtienne Carriere return TEE_SUCCESS; 285*69b8b983SEtienne Carriere 286*69b8b983SEtienne Carriere err_clk: 287*69b8b983SEtienne Carriere clk_disable(tamp->clock); 288*69b8b983SEtienne Carriere err: 289*69b8b983SEtienne Carriere free(tamp); 290*69b8b983SEtienne Carriere return res; 291*69b8b983SEtienne Carriere } 292*69b8b983SEtienne Carriere 293*69b8b983SEtienne Carriere static const struct stm32_tamp_compat mp13_compat = { 294*69b8b983SEtienne Carriere .nb_monotonic_counter = 2, 295*69b8b983SEtienne Carriere .tags = TAMP_HAS_REGISTER_SECCFG | TAMP_HAS_REGISTER_PRIVCFGR, 296*69b8b983SEtienne Carriere }; 297*69b8b983SEtienne Carriere 298*69b8b983SEtienne Carriere static const struct stm32_tamp_compat mp15_compat = { 299*69b8b983SEtienne Carriere .nb_monotonic_counter = 1, 300*69b8b983SEtienne Carriere .tags = 0, 301*69b8b983SEtienne Carriere }; 302*69b8b983SEtienne Carriere 303*69b8b983SEtienne Carriere static const struct dt_device_match stm32_tamp_match_table[] = { 304*69b8b983SEtienne Carriere { .compatible = "st,stm32mp13-tamp", .compat_data = &mp13_compat }, 305*69b8b983SEtienne Carriere { .compatible = "st,stm32-tamp", .compat_data = &mp15_compat }, 306*69b8b983SEtienne Carriere { } 307*69b8b983SEtienne Carriere }; 308*69b8b983SEtienne Carriere 309*69b8b983SEtienne Carriere DEFINE_DT_DRIVER(stm32_tamp_dt_driver) = { 310*69b8b983SEtienne Carriere .name = "stm32-tamp", 311*69b8b983SEtienne Carriere .match_table = stm32_tamp_match_table, 312*69b8b983SEtienne Carriere .probe = stm32_tamp_probe, 313*69b8b983SEtienne Carriere }; 314