xref: /optee_os/core/drivers/stm32_exti.c (revision 273a583ea99627ff3b8ccbbaedbdacecd0909b2e)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021-2025, STMicroelectronics
4  */
5 
6 #include <drivers/stm32_rif.h>
7 #include <dt-bindings/interrupt-controller/irq.h>
8 #include <io.h>
9 #include <kernel/boot.h>
10 #include <kernel/dt.h>
11 #include <kernel/dt_driver.h>
12 #include <kernel/interrupt.h>
13 #include <kernel/pm.h>
14 #include <kernel/spinlock.h>
15 #include <libfdt.h>
16 #include <mm/core_memprot.h>
17 #include <tee_api_types.h>
18 #include <util.h>
19 
20 /* Registers */
21 #define _EXTI_RTSR(n)			(0x000U + (n) * 0x20U)
22 #define _EXTI_FTSR(n)			(0x004U + (n) * 0x20U)
23 #define _EXTI_RPR(n)			(0x00cU + (n) * 0x20U)
24 #define _EXTI_FPR(n)			(0x010U + (n) * 0x20U)
25 #define _EXTI_SECCFGR(n)		(0x014U + (n) * 0x20U)
26 #define _EXTI_PRIVCFGR(n)		(0x018U + (n) * 0x20U)
27 #define _EXTI_CR(n)			(0x060U + (n) * 4U)
28 #define _EXTI_LOCKR			0x070U
29 #define _EXTI_C1IMR(n)			(0x080U + (n) * 0x10U)
30 #define _EXTI_EnCIDCFGR(n)		(0x180U + (n) * 4U)
31 #define _EXTI_CmCIDCFGR(n)		(0x300U + (n) * 4U)
32 #define _EXTI_TRG(n)			(0x3ecU - (n) * 4U) /* HWCFGR2..4 */
33 #define _EXTI_HWCFGR1			0x3f0U
34 
35 /* SECCFGR register bitfields */
36 #define _EXTI_SECCFGR_MASK		GENMASK_32(31, 0)
37 
38 /* PRIVCFGR register bitfields */
39 #define _EXTI_PRIVCFGR_MASK		GENMASK_32(31, 0)
40 
41 /* LOCKR register bitfields */
42 #define _EXTI_LOCKR_GLOCK		BIT(0)
43 
44 /* CIDCFGR register bitfields */
45 #define _EXTI_CIDCFGR_CFEN		BIT(0)
46 #define _EXTI_CIDCFGR_SCID_MASK		GENMASK_32(6, 4)
47 #define _EXTI_CIDCFGR_SCID_SHIFT	4U
48 #define _EXTI_CIDCFGR_CONF_MASK		(_EXTI_CIDCFGR_CFEN | \
49 					 _EXTI_CIDCFGR_SCID_MASK)
50 
51 /* _EXTI_HWCFGR1 bit fields */
52 #define _EXTI_HWCFGR1_NBEVENTS_MASK	GENMASK_32(7, 0)
53 #define _EXTI_HWCFGR1_NBEVENTS_SHIFT	0U
54 #define _EXTI_HWCFGR1_NBCPUS_MASK	GENMASK_32(11, 8)
55 #define _EXTI_HWCFGR1_NBCPUS_SHIFT	8U
56 #define _EXTI_HWCFGR1_CIDWIDTH_MASK	GENMASK_32(27, 24)
57 #define _EXTI_HWCFGR1_CIDWIDTH_SHIFT	24U
58 
59 #define _EXTI_MAX_CR			4U
60 #define _EXTI_BANK_NR			3U
61 #define _EXTI_LINES_PER_BANK		32U
62 
63 #define _EXTI_CID1			0x1U
64 
65 /*
66  * struct stm32_exti_itr_hierarchy - EXTI line interrupt hierarchy
67  * @this: An EXTI interrupt number and its EXTI interrupt controller
68  * @parent: The interrupt (number and controller) that drives the interrupt
69  */
70 struct stm32_exti_itr_hierarchy {
71 	struct itr_desc this;
72 	struct itr_desc parent;
73 };
74 
75 struct stm32_exti_pdata {
76 	struct itr_chip chip;
77 	vaddr_t base;
78 	unsigned int lock;
79 	uint32_t hwcfgr1;
80 	uint32_t trg[_EXTI_BANK_NR];
81 	uint32_t wake_active[_EXTI_BANK_NR];
82 	uint32_t mask_cache[_EXTI_BANK_NR];
83 	uint32_t imr_cache[_EXTI_BANK_NR];
84 	uint32_t seccfgr_cache[_EXTI_BANK_NR];
85 	uint32_t privcfgr_cache[_EXTI_BANK_NR];
86 	uint32_t access_mask[_EXTI_BANK_NR];
87 	uint32_t rtsr_cache[_EXTI_BANK_NR];
88 	uint32_t ftsr_cache[_EXTI_BANK_NR];
89 	uint32_t port_sel_cache[_EXTI_MAX_CR];
90 	uint32_t *e_cids;
91 	uint32_t *c_cids;
92 	struct stm32_exti_itr_hierarchy *
93 		hierarchy[_EXTI_LINES_PER_BANK * _EXTI_BANK_NR];
94 	bool glock;
95 };
96 
97 static struct stm32_exti_pdata *
98 itr_chip_to_stm32_exti_pdata(struct itr_chip *chip)
99 {
100 	return container_of(chip, struct stm32_exti_pdata, chip);
101 }
102 
103 static unsigned int stm32_exti_get_bank(uint32_t exti_line)
104 {
105 	if (exti_line < _EXTI_LINES_PER_BANK)
106 		return 0;
107 
108 	if (exti_line < 2 * _EXTI_LINES_PER_BANK)
109 		return 1;
110 
111 	if (exti_line < 3 * _EXTI_LINES_PER_BANK)
112 		return 2;
113 
114 	panic();
115 }
116 
117 static inline uint32_t stm32_exti_maxcid(const struct stm32_exti_pdata *exti)
118 {
119 	uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_CIDWIDTH_MASK) >>
120 			    _EXTI_HWCFGR1_CIDWIDTH_SHIFT;
121 
122 	return BIT(bitfield) - 1;
123 }
124 
125 static inline uint32_t stm32_exti_nbevents(const struct stm32_exti_pdata *exti)
126 {
127 	uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_NBEVENTS_MASK) >>
128 			    _EXTI_HWCFGR1_NBEVENTS_SHIFT;
129 
130 	return bitfield + 1;
131 }
132 
133 static inline uint32_t stm32_exti_nbcpus(const struct stm32_exti_pdata *exti)
134 {
135 	uint32_t bitfield = (exti->hwcfgr1 & _EXTI_HWCFGR1_NBCPUS_MASK) >>
136 			    _EXTI_HWCFGR1_NBCPUS_SHIFT;
137 
138 	return bitfield + 1;
139 }
140 
141 static bool
142 stm32_exti_event_is_configurable(const struct stm32_exti_pdata *exti,
143 				 unsigned int exti_line)
144 {
145 	unsigned int i = stm32_exti_get_bank(exti_line);
146 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
147 
148 	return exti->trg[i] & mask;
149 }
150 
151 static void stm32_exti_set_type(struct stm32_exti_pdata *exti,
152 				uint32_t exti_line, uint32_t type)
153 {
154 	unsigned int i = stm32_exti_get_bank(exti_line);
155 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
156 	uint32_t r_trig = 0;
157 	uint32_t f_trig = 0;
158 	uint32_t exceptions = 0;
159 
160 	switch (type) {
161 	case IRQ_TYPE_EDGE_RISING:
162 		r_trig |= mask;
163 		f_trig &= ~mask;
164 		break;
165 	case IRQ_TYPE_EDGE_FALLING:
166 		r_trig &= ~mask;
167 		f_trig |= mask;
168 		break;
169 	case IRQ_TYPE_EDGE_BOTH:
170 		r_trig |= mask;
171 		f_trig |= mask;
172 		break;
173 	default:
174 		EMSG("Unsupported interrupt type 0x%"PRIx32, type);
175 		panic();
176 	}
177 
178 	exceptions = cpu_spin_lock_xsave(&exti->lock);
179 
180 	io_mask32(exti->base + _EXTI_RTSR(i), r_trig, mask);
181 	io_mask32(exti->base + _EXTI_FTSR(i), f_trig, mask);
182 
183 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
184 }
185 
186 static void stm32_exti_mask(struct stm32_exti_pdata *exti, uint32_t exti_line)
187 {
188 	unsigned int i = stm32_exti_get_bank(exti_line);
189 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
190 	uint32_t exceptions = 0;
191 
192 	exceptions = cpu_spin_lock_xsave(&exti->lock);
193 
194 	io_clrbits32(exti->base + _EXTI_C1IMR(i), mask);
195 	exti->mask_cache[i] &= ~mask;
196 
197 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
198 }
199 
200 static void stm32_exti_unmask(struct stm32_exti_pdata *exti,
201 			      uint32_t exti_line)
202 {
203 	unsigned int i = stm32_exti_get_bank(exti_line);
204 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
205 	uint32_t exceptions = 0;
206 
207 	exceptions = cpu_spin_lock_xsave(&exti->lock);
208 
209 	io_setbits32(exti->base + _EXTI_C1IMR(i), mask);
210 	exti->mask_cache[i] |= mask;
211 
212 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
213 }
214 
215 static void stm32_exti_enable_wake(struct stm32_exti_pdata *exti,
216 				   uint32_t exti_line)
217 {
218 	unsigned int i = stm32_exti_get_bank(exti_line);
219 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
220 	uint32_t exceptions = 0;
221 
222 	exceptions = cpu_spin_lock_xsave(&exti->lock);
223 
224 	exti->wake_active[i] |= mask;
225 
226 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
227 }
228 
229 static void stm32_exti_disable_wake(struct stm32_exti_pdata *exti,
230 				    uint32_t exti_line)
231 {
232 	unsigned int i = stm32_exti_get_bank(exti_line);
233 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
234 	uint32_t exceptions = 0;
235 
236 	exceptions = cpu_spin_lock_xsave(&exti->lock);
237 
238 	exti->wake_active[i] &= ~mask;
239 
240 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
241 }
242 
243 static void stm32_exti_clear(struct stm32_exti_pdata *exti, uint32_t exti_line)
244 {
245 	unsigned int i = stm32_exti_get_bank(exti_line);
246 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
247 	uint32_t exceptions = 0;
248 
249 	exceptions = cpu_spin_lock_xsave(&exti->lock);
250 
251 	io_setbits32(exti->base + _EXTI_RPR(i), mask);
252 	io_setbits32(exti->base + _EXTI_FPR(i), mask);
253 
254 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
255 }
256 
257 static void stm32_exti_set_tz(struct stm32_exti_pdata *exti,
258 			      uint32_t exti_line)
259 {
260 	unsigned int i = stm32_exti_get_bank(exti_line);
261 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
262 	uint32_t exceptions = 0;
263 
264 	exceptions = cpu_spin_lock_xsave(&exti->lock);
265 
266 	io_setbits32(exti->base + _EXTI_SECCFGR(i), mask);
267 
268 	cpu_spin_unlock_xrestore(&exti->lock, exceptions);
269 }
270 
271 static struct itr_desc *
272 stm32_exti_get_parent_itr(struct stm32_exti_pdata *exti, size_t it)
273 {
274 	if (!exti || it >= stm32_exti_nbevents(exti) || !exti->hierarchy[it])
275 		panic();
276 
277 	return &exti->hierarchy[it]->parent;
278 }
279 
280 /* Enable an interrupt */
281 static void stm32_exti_op_enable(struct itr_chip *chip, size_t it)
282 {
283 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
284 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
285 
286 	stm32_exti_unmask(exti, it);
287 
288 	interrupt_enable(parent->chip, parent->itr_num);
289 }
290 
291 /* Disable an interrupt */
292 static void stm32_exti_op_disable(struct itr_chip *chip, size_t it)
293 {
294 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
295 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
296 
297 	stm32_exti_mask(exti, it);
298 
299 	interrupt_disable(parent->chip, parent->itr_num);
300 }
301 
302 /* Mask an interrupt, may be called from an interrupt context */
303 static void stm32_exti_op_mask(struct itr_chip *chip, size_t it)
304 {
305 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
306 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
307 
308 	stm32_exti_mask(exti, it);
309 
310 	interrupt_mask(parent->chip, parent->itr_num);
311 }
312 
313 /* Unmask an interrupt, may be called from an interrupt context */
314 static void stm32_exti_op_unmask(struct itr_chip *chip, size_t it)
315 {
316 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
317 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
318 
319 	stm32_exti_unmask(exti, it);
320 
321 	interrupt_unmask(parent->chip, parent->itr_num);
322 }
323 
324 /* Raise per-cpu interrupt (optional) */
325 static void stm32_exti_op_raise_pi(struct itr_chip *chip, size_t it)
326 {
327 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
328 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
329 
330 	if (interrupt_can_raise_pi(parent->chip))
331 		interrupt_raise_pi(parent->chip, parent->itr_num);
332 }
333 
334 /* Raise a SGI (optional) */
335 static void stm32_exti_op_raise_sgi(struct itr_chip *chip, size_t it,
336 				    uint32_t cpu_mask)
337 {
338 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
339 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
340 
341 	if (interrupt_can_raise_sgi(parent->chip))
342 		interrupt_raise_sgi(parent->chip, parent->itr_num, cpu_mask);
343 }
344 
345 /* Set interrupt/cpu affinity (optional) */
346 static void stm32_exti_op_set_affinity(struct itr_chip *chip, size_t it,
347 				       uint8_t cpu_mask)
348 {
349 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
350 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
351 
352 	if (interrupt_can_set_affinity(parent->chip))
353 		interrupt_set_affinity(parent->chip, parent->itr_num,
354 				       cpu_mask);
355 }
356 
357 /* Enable/disable power-management wake-on of an interrupt (optional) */
358 static void stm32_exti_op_set_wake(struct itr_chip *chip, size_t it,
359 				   bool on)
360 {
361 	struct stm32_exti_pdata *exti = itr_chip_to_stm32_exti_pdata(chip);
362 	struct itr_desc *parent = stm32_exti_get_parent_itr(exti, it);
363 
364 	if (on)
365 		stm32_exti_enable_wake(exti, it);
366 	else
367 		stm32_exti_disable_wake(exti, it);
368 
369 	if (interrupt_can_set_wake(parent->chip))
370 		interrupt_set_wake(parent->chip, parent->itr_num, on);
371 }
372 
373 static const struct itr_ops stm32_exti_ops = {
374 	.enable		= stm32_exti_op_enable,
375 	.disable	= stm32_exti_op_disable,
376 	.mask		= stm32_exti_op_mask,
377 	.unmask		= stm32_exti_op_unmask,
378 	.raise_pi	= stm32_exti_op_raise_pi,
379 	.raise_sgi	= stm32_exti_op_raise_sgi,
380 	.set_affinity	= stm32_exti_op_set_affinity,
381 	.set_wake	= stm32_exti_op_set_wake,
382 };
383 DECLARE_KEEP_PAGER(stm32_exti_ops);
384 
385 static TEE_Result stm32_exti_rif_check_access(struct stm32_exti_pdata *exti,
386 					      uint32_t exti_line)
387 {
388 	unsigned int i = stm32_exti_get_bank(exti_line);
389 	uint32_t mask = BIT(exti_line % _EXTI_LINES_PER_BANK);
390 
391 	/* only configured as secure and privileged */
392 	if (!((exti->seccfgr_cache[i] & exti->privcfgr_cache[i] &
393 	       exti->access_mask[i]) & mask))
394 		return TEE_ERROR_ACCESS_DENIED;
395 
396 	if ((exti->e_cids[exti_line] & _EXTI_CIDCFGR_CFEN) &&
397 	    ((exti->e_cids[exti_line] & _EXTI_CIDCFGR_SCID_MASK) !=
398 	     SHIFT_U32(_EXTI_CID1, _EXTI_CIDCFGR_SCID_SHIFT)))
399 		return TEE_ERROR_ACCESS_DENIED;
400 
401 	return TEE_SUCCESS;
402 }
403 
404 static void stm32_exti_rif_parse_dt(struct stm32_exti_pdata *exti,
405 				    const void *fdt, int node)
406 {
407 	struct rif_conf_data conf_data = { };
408 	const fdt32_t *cuint = NULL;
409 	uint32_t rif_conf = 0;
410 	unsigned int i = 0;
411 	int len = 0;
412 
413 	if (fdt_getprop(fdt, node, "st,glocked", NULL))
414 		exti->glock = true;
415 	else
416 		DMSG("No global lock on RIF configuration");
417 
418 	cuint = fdt_getprop(fdt, node, "st,protreg", &len);
419 	if (!cuint) {
420 		DMSG("No RIF configuration available");
421 		return;
422 	}
423 
424 	exti->e_cids = calloc(stm32_exti_nbevents(exti), sizeof(uint32_t));
425 	exti->c_cids = calloc(stm32_exti_nbcpus(exti), sizeof(uint32_t));
426 	if (!exti->e_cids || !exti->c_cids)
427 		panic("Out of memory");
428 
429 	conf_data.cid_confs   = exti->e_cids;
430 	conf_data.sec_conf    = exti->seccfgr_cache;
431 	conf_data.priv_conf   = exti->privcfgr_cache;
432 	conf_data.access_mask = exti->access_mask;
433 
434 	for (i = 0; i < len / sizeof(uint32_t); i++) {
435 		rif_conf = fdt32_to_cpu(cuint[i]);
436 
437 		stm32_rif_parse_cfg(rif_conf, &conf_data,
438 				    stm32_exti_nbevents(exti));
439 	}
440 
441 	cuint = fdt_getprop(fdt, node, "st,proccid", &len);
442 	if (!cuint)
443 		panic("No RIF configuration available");
444 
445 	for (i = 0; i < len / (2 * sizeof(uint32_t)); i++) {
446 		unsigned int pos = fdt32_to_cpu(cuint[2 * i]);
447 		uint32_t c_cid = fdt32_to_cpu(cuint[2 * i + 1]);
448 
449 		if (pos == 0 || pos > stm32_exti_nbcpus(exti))
450 			panic("CID position out of range");
451 
452 		if (c_cid > stm32_exti_maxcid(exti))
453 			panic("CID out of range");
454 
455 		exti->c_cids[pos - 1] = SHIFT_U32(c_cid, _CIDCFGR_SCID_SHIFT) |
456 					_EXTI_CIDCFGR_CFEN;
457 	}
458 }
459 
460 static TEE_Result stm32_exti_rif_apply(const struct stm32_exti_pdata *exti)
461 {
462 	TEE_Result res = TEE_ERROR_GENERIC;
463 	unsigned int bit_offset = 0;
464 	bool is_tdcid = false;
465 	uint32_t event = 0;
466 	unsigned int i = 0;
467 
468 	res = stm32_rifsc_check_tdcid(&is_tdcid);
469 	if (res)
470 		return res;
471 
472 	/*
473 	 * If TDCID, clear EnCIDCFGR and CmCIDCFGR to prevent undesired
474 	 * events during the following configuration.
475 	 */
476 
477 	if (is_tdcid) {
478 		for (event = 0; event < stm32_exti_nbevents(exti); event++) {
479 			i = stm32_exti_get_bank(event);
480 			bit_offset = event % _EXTI_LINES_PER_BANK;
481 
482 			if (!(BIT(bit_offset) & exti->access_mask[i]))
483 				continue;
484 
485 			io_clrbits32(exti->base + _EXTI_EnCIDCFGR(event),
486 				     _EXTI_CIDCFGR_CONF_MASK);
487 		}
488 
489 		for (i = 0; i < stm32_exti_nbcpus(exti); i++)
490 			io_clrbits32(exti->base + _EXTI_CmCIDCFGR(i),
491 				     _EXTI_CIDCFGR_CONF_MASK);
492 	}
493 
494 	/* Security and privilege RIF configuration */
495 	for (i = 0; i < _EXTI_BANK_NR; i++) {
496 		if (!exti->access_mask[i])
497 			continue;
498 
499 		io_clrsetbits32(exti->base + _EXTI_PRIVCFGR(i),
500 				_EXTI_PRIVCFGR_MASK & exti->access_mask[i],
501 				exti->privcfgr_cache[i]);
502 		io_clrsetbits32(exti->base + _EXTI_SECCFGR(i),
503 				_EXTI_SECCFGR_MASK & exti->access_mask[i],
504 				exti->seccfgr_cache[i]);
505 	}
506 
507 	if (!is_tdcid)
508 		return TEE_SUCCESS;
509 
510 	/* If TDCID, configure EnCIDCFGR and CmCIDCFGR */
511 	for (event = 0; event < stm32_exti_nbevents(exti); event++) {
512 		i = stm32_exti_get_bank(event);
513 		bit_offset = event % _EXTI_LINES_PER_BANK;
514 
515 		if (!(BIT(bit_offset) & exti->access_mask[i]))
516 			continue;
517 
518 		io_clrsetbits32(exti->base + _EXTI_EnCIDCFGR(event),
519 				_EXTI_CIDCFGR_CONF_MASK, exti->e_cids[event]);
520 	}
521 	for (i = 0; i < stm32_exti_nbcpus(exti); i++) {
522 		if (!(exti->c_cids[i] & _EXTI_CIDCFGR_CFEN))
523 			continue;
524 
525 		io_clrsetbits32(exti->base + _EXTI_CmCIDCFGR(i),
526 				_EXTI_CIDCFGR_CONF_MASK, exti->c_cids[i]);
527 	}
528 
529 	/* If TDCID, configure global lock */
530 	if (exti->glock)
531 		io_setbits32(exti->base + _EXTI_LOCKR, _EXTI_LOCKR_GLOCK);
532 
533 	return TEE_SUCCESS;
534 }
535 
536 static void stm32_exti_rif_save(struct stm32_exti_pdata *exti)
537 {
538 	unsigned int bit_offset = 0;
539 	bool is_tdcid = false;
540 	uint32_t event = 0;
541 	unsigned int i = 0;
542 
543 	for (i = 0; i < _EXTI_BANK_NR; i++) {
544 		if (!exti->access_mask[i])
545 			continue;
546 
547 		exti->privcfgr_cache[i] =
548 			io_read32(exti->base + _EXTI_PRIVCFGR(i));
549 		exti->seccfgr_cache[i] =
550 			io_read32(exti->base + _EXTI_SECCFGR(i));
551 	}
552 
553 	stm32_rifsc_check_tdcid(&is_tdcid);
554 	if (!is_tdcid)
555 		return;
556 
557 	for (event = 0; event < stm32_exti_nbevents(exti); event++) {
558 		i = stm32_exti_get_bank(event);
559 		bit_offset = event % _EXTI_LINES_PER_BANK;
560 
561 		if (!(BIT(bit_offset) & exti->access_mask[i]))
562 			continue;
563 
564 		exti->e_cids[event] = io_read32(exti->base +
565 						_EXTI_EnCIDCFGR(event));
566 	}
567 	for (i = 0; i < stm32_exti_nbcpus(exti); i++)
568 		exti->c_cids[i] = io_read32(exti->base + _EXTI_CmCIDCFGR(i));
569 }
570 
571 static void stm32_exti_pm_suspend(struct stm32_exti_pdata *exti)
572 {
573 	uint32_t base = exti->base;
574 	uint32_t i = 0;
575 
576 	if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti))
577 		stm32_exti_rif_save(exti);
578 
579 	for (i = 0; i < _EXTI_BANK_NR; i++) {
580 		/* Save ftsr, rtsr and seccfgr registers */
581 		exti->ftsr_cache[i] = io_read32(base + _EXTI_FTSR(i));
582 		exti->rtsr_cache[i] = io_read32(base + _EXTI_RTSR(i));
583 		exti->seccfgr_cache[i] = io_read32(base + _EXTI_SECCFGR(i));
584 	}
585 
586 	/* Save EXTI port selection */
587 	for (i = 0; i < _EXTI_MAX_CR; i++)
588 		exti->port_sel_cache[i] = io_read32(base + _EXTI_CR(i));
589 }
590 
591 static void stm32_exti_pm_resume(struct stm32_exti_pdata *exti)
592 {
593 	uint32_t base = exti->base;
594 	uint32_t i = 0;
595 
596 	for (i = 0; i < _EXTI_BANK_NR; i++) {
597 		/* Restore ftsr, rtsr and seccfgr registers */
598 		io_write32(base + _EXTI_FTSR(i), exti->ftsr_cache[i]);
599 		io_write32(base + _EXTI_RTSR(i), exti->rtsr_cache[i]);
600 		io_write32(base + _EXTI_SECCFGR(i), exti->seccfgr_cache[i]);
601 	}
602 
603 	/* Restore EXTI port selection */
604 	for (i = 0; i < _EXTI_MAX_CR; i++)
605 		io_write32(base + _EXTI_CR(i), exti->port_sel_cache[i]);
606 
607 	if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti))
608 		stm32_exti_rif_apply(exti);
609 }
610 
611 /* PM function: configure the wake_up line for OP-TEE */
612 static void stm32_exti_configure_wake(struct stm32_exti_pdata *exti)
613 {
614 	uint32_t i = 0;
615 
616 	for (i = 0; i < _EXTI_BANK_NR; i++) {
617 		/* save IMR value, lost in Standby */
618 		exti->imr_cache[i] = io_read32(exti->base + _EXTI_C1IMR(i));
619 		/* deactivate in IMR the interruption activated in OP-TEE */
620 		io_clrbits32(exti->base + _EXTI_C1IMR(i), exti->mask_cache[i]);
621 		/* activate in IMR for OP-TEE wakeup interruption */
622 		io_setbits32(exti->base + _EXTI_C1IMR(i), exti->wake_active[i]);
623 	}
624 }
625 
626 static void stm32_exti_restore_wake(struct stm32_exti_pdata *exti)
627 {
628 	uint32_t i = 0;
629 
630 	/* restore saved IMR value: interruption secure/unsecure */
631 	for (i = 0; i < _EXTI_BANK_NR; i++)
632 		io_write32(exti->base + _EXTI_C1IMR(i), exti->imr_cache[i]);
633 }
634 
635 static TEE_Result
636 stm32_exti_pm(enum pm_op op, unsigned int pm_hint,
637 	      const struct pm_callback_handle *pm_handle)
638 {
639 	struct stm32_exti_pdata *exti =
640 		(struct stm32_exti_pdata *)PM_CALLBACK_GET_HANDLE(pm_handle);
641 
642 	if (op == PM_OP_SUSPEND)
643 		stm32_exti_configure_wake(exti);
644 	else
645 		stm32_exti_restore_wake(exti);
646 
647 	if (!PM_HINT_IS_STATE(pm_hint, CONTEXT))
648 		return TEE_SUCCESS;
649 
650 	if (op == PM_OP_SUSPEND)
651 		stm32_exti_pm_suspend(exti);
652 	else
653 		stm32_exti_pm_resume(exti);
654 
655 	return TEE_SUCCESS;
656 }
657 DECLARE_KEEP_PAGER(stm32_exti_pm);
658 
659 static enum itr_return stm32_exti_it_handler(struct itr_handler *h)
660 {
661 	struct stm32_exti_itr_hierarchy *hierarchy = h->data;
662 	struct itr_desc *itr_desc = &hierarchy->this;
663 	struct stm32_exti_pdata *exti =
664 		itr_chip_to_stm32_exti_pdata(itr_desc->chip);
665 
666 	interrupt_call_handlers(itr_desc->chip, itr_desc->itr_num);
667 
668 	if (stm32_exti_event_is_configurable(exti, itr_desc->itr_num))
669 		stm32_exti_clear(exti, itr_desc->itr_num);
670 
671 	return ITRR_HANDLED;
672 }
673 DECLARE_KEEP_PAGER(stm32_exti_it_handler);
674 
675 /* Callback for "interrupts" and "interrupts-extended" DT node properties */
676 static TEE_Result
677 stm32_exti_dt_get_chip_cb(struct dt_pargs *pargs, void *priv_data,
678 			  struct itr_desc *itr_desc)
679 {
680 	struct stm32_exti_pdata *exti = priv_data;
681 	struct stm32_exti_itr_hierarchy *hierarchy = NULL;
682 	size_t exti_line = 0;
683 	uint32_t type = 0;
684 	TEE_Result res = TEE_ERROR_GENERIC;
685 
686 	if (pargs->args_count != 2)
687 		return TEE_ERROR_GENERIC;
688 
689 	exti_line = pargs->args[0];
690 	type = pargs->args[1];
691 
692 	itr_desc->chip = &exti->chip;
693 	itr_desc->itr_num = exti_line;
694 
695 	if (exti_line >= stm32_exti_nbevents(exti))
696 		return TEE_ERROR_GENERIC;
697 
698 	/* With RIF, check the permission */
699 	if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti)) {
700 		res = stm32_exti_rif_check_access(exti, exti_line);
701 		if (res)
702 			return res;
703 	}
704 
705 	hierarchy = exti->hierarchy[exti_line];
706 	if (!hierarchy) {
707 		hierarchy = calloc(1, sizeof(*hierarchy));
708 		if (!hierarchy)
709 			return TEE_ERROR_OUT_OF_MEMORY;
710 		exti->hierarchy[exti_line] = hierarchy;
711 	}
712 
713 	hierarchy->this.chip = &exti->chip;
714 	hierarchy->this.itr_num = exti_line;
715 
716 	res = interrupt_dt_get_by_index(pargs->fdt, pargs->phandle_node,
717 					exti_line,
718 					&hierarchy->parent.chip,
719 					&hierarchy->parent.itr_num);
720 	if (res)
721 		return res;
722 
723 	res = interrupt_create_handler(hierarchy->parent.chip,
724 				       hierarchy->parent.itr_num,
725 				       stm32_exti_it_handler, hierarchy,
726 				       ITRF_TRIGGER_LEVEL, NULL);
727 	if (res)
728 		return res;
729 
730 	/* set_type valid for configurable events only */
731 	if (stm32_exti_event_is_configurable(exti, exti_line))
732 		stm32_exti_set_type(exti, exti_line, type);
733 
734 	/* Without RIF, predate the line by setting it as secure */
735 	if (!IS_ENABLED(CFG_STM32_RIF) || !stm32_exti_maxcid(exti))
736 		stm32_exti_set_tz(exti, exti_line);
737 
738 	return TEE_SUCCESS;
739 }
740 
741 static TEE_Result stm32_exti_probe(const void *fdt, int node,
742 				   const void *comp_data __unused)
743 {
744 	struct stm32_exti_pdata *exti = NULL;
745 	TEE_Result res = TEE_ERROR_GENERIC;
746 	struct io_pa_va base = { };
747 	size_t reg_size = 0;
748 	unsigned int i = 0;
749 
750 	exti = calloc(1, sizeof(*exti));
751 	if (!exti)
752 		panic("Out of memory");
753 
754 	exti->lock = SPINLOCK_UNLOCK;
755 	exti->chip.ops = &stm32_exti_ops;
756 	exti->chip.name = strdup(fdt_get_name(fdt, node, NULL));
757 
758 	res = itr_chip_dt_only_init(&exti->chip);
759 	if (res)
760 		panic();
761 
762 	if (fdt_reg_info(fdt, node, &base.pa, &reg_size))
763 		panic();
764 
765 	exti->base = io_pa_or_va_secure(&base, reg_size);
766 	assert(exti->base);
767 
768 	exti->hwcfgr1 = io_read32(exti->base + _EXTI_HWCFGR1);
769 	for (i = 0; i < _EXTI_BANK_NR; i++)
770 		exti->trg[i] = io_read32(exti->base + _EXTI_TRG(i));
771 
772 	if (IS_ENABLED(CFG_STM32_RIF) && stm32_exti_maxcid(exti)) {
773 		stm32_exti_rif_parse_dt(exti, fdt, node);
774 		res = stm32_exti_rif_apply(exti);
775 		if (res)
776 			goto err;
777 	}
778 
779 	res = interrupt_register_provider(fdt, node, stm32_exti_dt_get_chip_cb,
780 					  exti);
781 	if (res)
782 		goto err;
783 
784 	register_pm_core_service_cb(stm32_exti_pm, exti, "stm32-exti");
785 
786 	return TEE_SUCCESS;
787 
788 err:
789 	free(exti->e_cids);
790 	free(exti->c_cids);
791 	free((char *)exti->chip.name);
792 	free(exti);
793 	return res;
794 }
795 
796 static const struct dt_device_match stm32_exti_match_table[] = {
797 	{ .compatible = "st,stm32mp1-exti" },
798 	{ }
799 };
800 
801 DEFINE_DT_DRIVER(stm32_exti_dt_driver) = {
802 	.name = "stm32-exti",
803 	.match_table = stm32_exti_match_table,
804 	.probe = &stm32_exti_probe,
805 };
806