xref: /linux/drivers/irqchip/irq-stm32mp-exti.c (revision b485131995544741ba6dcc313d7eb573bca7bebc)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Maxime Coquelin 2015
4  * Copyright (C) STMicroelectronics 2017-2024
5  * Author:  Maxime Coquelin <mcoquelin.stm32@gmail.com>
6  */
7 
8 #include <linux/bitops.h>
9 #include <linux/hwspinlock.h>
10 #include <linux/interrupt.h>
11 #include <linux/io.h>
12 #include <linux/irq.h>
13 #include <linux/irqchip.h>
14 #include <linux/irqdomain.h>
15 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/of_irq.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm.h>
20 
21 #include <dt-bindings/interrupt-controller/arm-gic.h>
22 
23 #define IRQS_PER_BANK			32
24 
25 #define HWSPNLCK_TIMEOUT_MS		1
26 
27 #define EXTI_EnCIDCFGR(n)		(0x180 + (n) * 4)
28 #define EXTI_HWCFGR1			0x3f0
29 
30 /* Register: EXTI_EnCIDCFGR(n) */
31 #define EXTI_CIDCFGR_CFEN_MASK		BIT(0)
32 #define EXTI_CIDCFGR_CID_MASK		GENMASK(6, 4)
33 #define EXTI_CIDCFGR_CID_SHIFT		4
34 
35 /* Register: EXTI_HWCFGR1 */
36 #define EXTI_HWCFGR1_CIDWIDTH_MASK	GENMASK(27, 24)
37 
38 #define EXTI_CID1			1
39 
40 struct stm32mp_exti_bank {
41 	u32 imr_ofst;
42 	u32 rtsr_ofst;
43 	u32 ftsr_ofst;
44 	u32 swier_ofst;
45 	u32 rpr_ofst;
46 	u32 fpr_ofst;
47 	u32 trg_ofst;
48 	u32 seccfgr_ofst;
49 };
50 
51 struct stm32mp_exti_drv_data {
52 	const struct stm32mp_exti_bank	**exti_banks;
53 	const u8			*desc_irqs;
54 	u32				bank_nr;
55 };
56 
57 struct stm32mp_exti_chip_data {
58 	struct stm32mp_exti_host_data	*host_data;
59 	const struct stm32mp_exti_bank	*reg_bank;
60 	struct raw_spinlock		rlock;
61 	u32				wake_active;
62 	u32				mask_cache;
63 	u32				rtsr_cache;
64 	u32				ftsr_cache;
65 	u32				event_reserved;
66 };
67 
68 struct stm32mp_exti_host_data {
69 	void __iomem				*base;
70 	struct device				*dev;
71 	struct stm32mp_exti_chip_data		*chips_data;
72 	const struct stm32mp_exti_drv_data	*drv_data;
73 	struct hwspinlock			*hwlock;
74 	/* skip internal desc_irqs array and get it from DT */
75 	bool dt_has_irqs_desc;
76 };
77 
78 static const struct stm32mp_exti_bank stm32mp_exti_b1 = {
79 	.imr_ofst	= 0x80,
80 	.rtsr_ofst	= 0x00,
81 	.ftsr_ofst	= 0x04,
82 	.swier_ofst	= 0x08,
83 	.rpr_ofst	= 0x0C,
84 	.fpr_ofst	= 0x10,
85 	.trg_ofst	= 0x3EC,
86 	.seccfgr_ofst	= 0x14,
87 };
88 
89 static const struct stm32mp_exti_bank stm32mp_exti_b2 = {
90 	.imr_ofst	= 0x90,
91 	.rtsr_ofst	= 0x20,
92 	.ftsr_ofst	= 0x24,
93 	.swier_ofst	= 0x28,
94 	.rpr_ofst	= 0x2C,
95 	.fpr_ofst	= 0x30,
96 	.trg_ofst	= 0x3E8,
97 	.seccfgr_ofst	= 0x34,
98 };
99 
100 static const struct stm32mp_exti_bank stm32mp_exti_b3 = {
101 	.imr_ofst	= 0xA0,
102 	.rtsr_ofst	= 0x40,
103 	.ftsr_ofst	= 0x44,
104 	.swier_ofst	= 0x48,
105 	.rpr_ofst	= 0x4C,
106 	.fpr_ofst	= 0x50,
107 	.trg_ofst	= 0x3E4,
108 	.seccfgr_ofst	= 0x54,
109 };
110 
111 static const struct stm32mp_exti_bank *stm32mp_exti_banks[] = {
112 	&stm32mp_exti_b1,
113 	&stm32mp_exti_b2,
114 	&stm32mp_exti_b3,
115 };
116 
117 static struct irq_chip stm32mp_exti_chip;
118 static struct irq_chip stm32mp_exti_chip_direct;
119 
120 #define EXTI_INVALID_IRQ       U8_MAX
121 #define STM32MP_DESC_IRQ_SIZE  (ARRAY_SIZE(stm32mp_exti_banks) * IRQS_PER_BANK)
122 
123 /*
124  * Use some intentionally tricky logic here to initialize the whole array to
125  * EXTI_INVALID_IRQ, but then override certain fields, requiring us to indicate
126  * that we "know" that there are overrides in this structure, and we'll need to
127  * disable that warning from W=1 builds.
128  */
129 __diag_push();
130 __diag_ignore_all("-Woverride-init",
131 		  "logic to initialize all and then override some is OK");
132 
133 static const u8 stm32mp1_desc_irq[] = {
134 	/* default value */
135 	[0 ... (STM32MP_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ,
136 
137 	[0] = 6,
138 	[1] = 7,
139 	[2] = 8,
140 	[3] = 9,
141 	[4] = 10,
142 	[5] = 23,
143 	[6] = 64,
144 	[7] = 65,
145 	[8] = 66,
146 	[9] = 67,
147 	[10] = 40,
148 	[11] = 42,
149 	[12] = 76,
150 	[13] = 77,
151 	[14] = 121,
152 	[15] = 127,
153 	[16] = 1,
154 	[19] = 3,
155 	[21] = 31,
156 	[22] = 33,
157 	[23] = 72,
158 	[24] = 95,
159 	[25] = 107,
160 	[26] = 37,
161 	[27] = 38,
162 	[28] = 39,
163 	[29] = 71,
164 	[30] = 52,
165 	[31] = 53,
166 	[32] = 82,
167 	[33] = 83,
168 	[46] = 151,
169 	[47] = 93,
170 	[48] = 138,
171 	[50] = 139,
172 	[52] = 140,
173 	[53] = 141,
174 	[54] = 135,
175 	[61] = 100,
176 	[65] = 144,
177 	[68] = 143,
178 	[70] = 62,
179 	[73] = 129,
180 };
181 
182 static const u8 stm32mp13_desc_irq[] = {
183 	/* default value */
184 	[0 ... (STM32MP_DESC_IRQ_SIZE - 1)] = EXTI_INVALID_IRQ,
185 
186 	[0] = 6,
187 	[1] = 7,
188 	[2] = 8,
189 	[3] = 9,
190 	[4] = 10,
191 	[5] = 24,
192 	[6] = 65,
193 	[7] = 66,
194 	[8] = 67,
195 	[9] = 68,
196 	[10] = 41,
197 	[11] = 43,
198 	[12] = 77,
199 	[13] = 78,
200 	[14] = 106,
201 	[15] = 109,
202 	[16] = 1,
203 	[19] = 3,
204 	[21] = 32,
205 	[22] = 34,
206 	[23] = 73,
207 	[24] = 93,
208 	[25] = 114,
209 	[26] = 38,
210 	[27] = 39,
211 	[28] = 40,
212 	[29] = 72,
213 	[30] = 53,
214 	[31] = 54,
215 	[32] = 83,
216 	[33] = 84,
217 	[44] = 96,
218 	[47] = 92,
219 	[48] = 116,
220 	[50] = 117,
221 	[52] = 118,
222 	[53] = 119,
223 	[68] = 63,
224 	[70] = 98,
225 };
226 
227 __diag_pop();
228 
229 static const struct stm32mp_exti_drv_data stm32mp1_drv_data = {
230 	.exti_banks = stm32mp_exti_banks,
231 	.bank_nr = ARRAY_SIZE(stm32mp_exti_banks),
232 	.desc_irqs = stm32mp1_desc_irq,
233 };
234 
235 static const struct stm32mp_exti_drv_data stm32mp13_drv_data = {
236 	.exti_banks = stm32mp_exti_banks,
237 	.bank_nr = ARRAY_SIZE(stm32mp_exti_banks),
238 	.desc_irqs = stm32mp13_desc_irq,
239 };
240 
stm32mp_exti_convert_type(struct irq_data * d,unsigned int type,u32 * rtsr,u32 * ftsr)241 static int stm32mp_exti_convert_type(struct irq_data *d, unsigned int type, u32 *rtsr, u32 *ftsr)
242 {
243 	u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
244 
245 	switch (type) {
246 	case IRQ_TYPE_EDGE_RISING:
247 		*rtsr |= mask;
248 		*ftsr &= ~mask;
249 		break;
250 	case IRQ_TYPE_EDGE_FALLING:
251 		*rtsr &= ~mask;
252 		*ftsr |= mask;
253 		break;
254 	case IRQ_TYPE_EDGE_BOTH:
255 		*rtsr |= mask;
256 		*ftsr |= mask;
257 		break;
258 	default:
259 		return -EINVAL;
260 	}
261 
262 	return 0;
263 }
264 
stm32mp_chip_suspend(struct stm32mp_exti_chip_data * chip_data,u32 wake_active)265 static void stm32mp_chip_suspend(struct stm32mp_exti_chip_data *chip_data, u32 wake_active)
266 {
267 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
268 	void __iomem *base = chip_data->host_data->base;
269 
270 	/* save rtsr, ftsr registers */
271 	chip_data->rtsr_cache = readl_relaxed(base + bank->rtsr_ofst);
272 	chip_data->ftsr_cache = readl_relaxed(base + bank->ftsr_ofst);
273 
274 	writel_relaxed(wake_active, base + bank->imr_ofst);
275 }
276 
stm32mp_chip_resume(struct stm32mp_exti_chip_data * chip_data,u32 mask_cache)277 static void stm32mp_chip_resume(struct stm32mp_exti_chip_data *chip_data, u32 mask_cache)
278 {
279 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
280 	void __iomem *base = chip_data->host_data->base;
281 
282 	/* restore rtsr, ftsr, registers */
283 	writel_relaxed(chip_data->rtsr_cache, base + bank->rtsr_ofst);
284 	writel_relaxed(chip_data->ftsr_cache, base + bank->ftsr_ofst);
285 
286 	writel_relaxed(mask_cache, base + bank->imr_ofst);
287 }
288 
289 /* directly set the target bit without reading first. */
stm32mp_exti_write_bit(struct irq_data * d,u32 reg)290 static inline void stm32mp_exti_write_bit(struct irq_data *d, u32 reg)
291 {
292 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
293 	void __iomem *base = chip_data->host_data->base;
294 	u32 val = BIT(d->hwirq % IRQS_PER_BANK);
295 
296 	writel_relaxed(val, base + reg);
297 }
298 
stm32mp_exti_set_bit(struct irq_data * d,u32 reg)299 static inline u32 stm32mp_exti_set_bit(struct irq_data *d, u32 reg)
300 {
301 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
302 	void __iomem *base = chip_data->host_data->base;
303 	u32 val;
304 
305 	val = readl_relaxed(base + reg);
306 	val |= BIT(d->hwirq % IRQS_PER_BANK);
307 	writel_relaxed(val, base + reg);
308 
309 	return val;
310 }
311 
stm32mp_exti_clr_bit(struct irq_data * d,u32 reg)312 static inline u32 stm32mp_exti_clr_bit(struct irq_data *d, u32 reg)
313 {
314 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
315 	void __iomem *base = chip_data->host_data->base;
316 	u32 val;
317 
318 	val = readl_relaxed(base + reg);
319 	val &= ~BIT(d->hwirq % IRQS_PER_BANK);
320 	writel_relaxed(val, base + reg);
321 
322 	return val;
323 }
324 
stm32mp_exti_eoi(struct irq_data * d)325 static void stm32mp_exti_eoi(struct irq_data *d)
326 {
327 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
328 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
329 
330 	raw_spin_lock(&chip_data->rlock);
331 
332 	stm32mp_exti_write_bit(d, bank->rpr_ofst);
333 	stm32mp_exti_write_bit(d, bank->fpr_ofst);
334 
335 	raw_spin_unlock(&chip_data->rlock);
336 
337 	if (d->parent_data->chip)
338 		irq_chip_eoi_parent(d);
339 }
340 
stm32mp_exti_mask(struct irq_data * d)341 static void stm32mp_exti_mask(struct irq_data *d)
342 {
343 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
344 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
345 
346 	raw_spin_lock(&chip_data->rlock);
347 	chip_data->mask_cache = stm32mp_exti_clr_bit(d, bank->imr_ofst);
348 	raw_spin_unlock(&chip_data->rlock);
349 
350 	if (d->parent_data->chip)
351 		irq_chip_mask_parent(d);
352 }
353 
stm32mp_exti_unmask(struct irq_data * d)354 static void stm32mp_exti_unmask(struct irq_data *d)
355 {
356 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
357 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
358 
359 	raw_spin_lock(&chip_data->rlock);
360 	chip_data->mask_cache = stm32mp_exti_set_bit(d, bank->imr_ofst);
361 	raw_spin_unlock(&chip_data->rlock);
362 
363 	if (d->parent_data->chip)
364 		irq_chip_unmask_parent(d);
365 }
366 
stm32mp_exti_set_type(struct irq_data * d,unsigned int type)367 static int stm32mp_exti_set_type(struct irq_data *d, unsigned int type)
368 {
369 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
370 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
371 	struct hwspinlock *hwlock = chip_data->host_data->hwlock;
372 	void __iomem *base = chip_data->host_data->base;
373 	u32 rtsr, ftsr;
374 	int err;
375 
376 	raw_spin_lock(&chip_data->rlock);
377 
378 	if (hwlock) {
379 		err = hwspin_lock_timeout_in_atomic(hwlock, HWSPNLCK_TIMEOUT_MS);
380 		if (err) {
381 			pr_err("%s can't get hwspinlock (%d)\n", __func__, err);
382 			goto unlock;
383 		}
384 	}
385 
386 	rtsr = readl_relaxed(base + bank->rtsr_ofst);
387 	ftsr = readl_relaxed(base + bank->ftsr_ofst);
388 
389 	err = stm32mp_exti_convert_type(d, type, &rtsr, &ftsr);
390 	if (!err) {
391 		writel_relaxed(rtsr, base + bank->rtsr_ofst);
392 		writel_relaxed(ftsr, base + bank->ftsr_ofst);
393 	}
394 
395 	if (hwlock)
396 		hwspin_unlock_in_atomic(hwlock);
397 unlock:
398 	raw_spin_unlock(&chip_data->rlock);
399 	return err;
400 }
401 
stm32mp_exti_set_wake(struct irq_data * d,unsigned int on)402 static int stm32mp_exti_set_wake(struct irq_data *d, unsigned int on)
403 {
404 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
405 	u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
406 
407 	raw_spin_lock(&chip_data->rlock);
408 
409 	if (on)
410 		chip_data->wake_active |= mask;
411 	else
412 		chip_data->wake_active &= ~mask;
413 
414 	raw_spin_unlock(&chip_data->rlock);
415 
416 	return 0;
417 }
418 
stm32mp_exti_set_affinity(struct irq_data * d,const struct cpumask * dest,bool force)419 static int stm32mp_exti_set_affinity(struct irq_data *d, const struct cpumask *dest, bool force)
420 {
421 	if (d->parent_data->chip)
422 		return irq_chip_set_affinity_parent(d, dest, force);
423 
424 	return IRQ_SET_MASK_OK_DONE;
425 }
426 
stm32mp_exti_suspend(struct device * dev)427 static int stm32mp_exti_suspend(struct device *dev)
428 {
429 	struct stm32mp_exti_host_data *host_data = dev_get_drvdata(dev);
430 	struct stm32mp_exti_chip_data *chip_data;
431 	int i;
432 
433 	for (i = 0; i < host_data->drv_data->bank_nr; i++) {
434 		chip_data = &host_data->chips_data[i];
435 		stm32mp_chip_suspend(chip_data, chip_data->wake_active);
436 	}
437 
438 	return 0;
439 }
440 
stm32mp_exti_resume(struct device * dev)441 static int stm32mp_exti_resume(struct device *dev)
442 {
443 	struct stm32mp_exti_host_data *host_data = dev_get_drvdata(dev);
444 	struct stm32mp_exti_chip_data *chip_data;
445 	int i;
446 
447 	for (i = 0; i < host_data->drv_data->bank_nr; i++) {
448 		chip_data = &host_data->chips_data[i];
449 		stm32mp_chip_resume(chip_data, chip_data->mask_cache);
450 	}
451 
452 	return 0;
453 }
454 
stm32mp_exti_retrigger(struct irq_data * d)455 static int stm32mp_exti_retrigger(struct irq_data *d)
456 {
457 	struct stm32mp_exti_chip_data *chip_data = irq_data_get_irq_chip_data(d);
458 	const struct stm32mp_exti_bank *bank = chip_data->reg_bank;
459 	void __iomem *base = chip_data->host_data->base;
460 	u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
461 
462 	writel_relaxed(mask, base + bank->swier_ofst);
463 
464 	return 0;
465 }
466 
467 static struct irq_chip stm32mp_exti_chip = {
468 	.name			= "stm32mp-exti",
469 	.irq_eoi		= stm32mp_exti_eoi,
470 	.irq_mask		= stm32mp_exti_mask,
471 	.irq_unmask		= stm32mp_exti_unmask,
472 	.irq_retrigger		= stm32mp_exti_retrigger,
473 	.irq_set_type		= stm32mp_exti_set_type,
474 	.irq_set_wake		= stm32mp_exti_set_wake,
475 	.flags			= IRQCHIP_MASK_ON_SUSPEND,
476 	.irq_set_affinity	= IS_ENABLED(CONFIG_SMP) ? stm32mp_exti_set_affinity : NULL,
477 };
478 
479 static struct irq_chip stm32mp_exti_chip_direct = {
480 	.name			= "stm32mp-exti-direct",
481 	.irq_eoi		= irq_chip_eoi_parent,
482 	.irq_ack		= irq_chip_ack_parent,
483 	.irq_mask		= stm32mp_exti_mask,
484 	.irq_unmask		= stm32mp_exti_unmask,
485 	.irq_retrigger		= irq_chip_retrigger_hierarchy,
486 	.irq_set_type		= irq_chip_set_type_parent,
487 	.irq_set_wake		= stm32mp_exti_set_wake,
488 	.flags			= IRQCHIP_MASK_ON_SUSPEND,
489 	.irq_set_affinity	= IS_ENABLED(CONFIG_SMP) ? irq_chip_set_affinity_parent : NULL,
490 };
491 
stm32mp_exti_domain_alloc(struct irq_domain * dm,unsigned int virq,unsigned int nr_irqs,void * data)492 static int stm32mp_exti_domain_alloc(struct irq_domain *dm,
493 				     unsigned int virq,
494 				     unsigned int nr_irqs, void *data)
495 {
496 	struct stm32mp_exti_host_data *host_data = dm->host_data;
497 	struct stm32mp_exti_chip_data *chip_data;
498 	struct irq_fwspec *fwspec = data;
499 	struct irq_fwspec p_fwspec;
500 	irq_hw_number_t hwirq;
501 	struct irq_chip *chip;
502 	u32 event_trg;
503 	u8 desc_irq;
504 	int bank;
505 
506 	hwirq = fwspec->param[0];
507 	if (hwirq >= host_data->drv_data->bank_nr * IRQS_PER_BANK)
508 		return -EINVAL;
509 
510 	bank  = hwirq / IRQS_PER_BANK;
511 	chip_data = &host_data->chips_data[bank];
512 
513 	/* Check if event is reserved (Secure) */
514 	if (chip_data->event_reserved & BIT(hwirq % IRQS_PER_BANK)) {
515 		dev_err(host_data->dev, "event %lu is reserved, secure\n", hwirq);
516 		return -EPERM;
517 	}
518 
519 	event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst);
520 	chip = (event_trg & BIT(hwirq % IRQS_PER_BANK)) ?
521 	       &stm32mp_exti_chip : &stm32mp_exti_chip_direct;
522 
523 	irq_domain_set_hwirq_and_chip(dm, virq, hwirq, chip, chip_data);
524 
525 	if (host_data->dt_has_irqs_desc) {
526 		struct of_phandle_args out_irq;
527 		int ret;
528 
529 		ret = of_irq_parse_one(host_data->dev->of_node, hwirq, &out_irq);
530 		if (ret)
531 			return ret;
532 		/* we only support one parent, so far */
533 		if (of_fwnode_handle(out_irq.np) != dm->parent->fwnode)
534 			return -EINVAL;
535 
536 		of_phandle_args_to_fwspec(out_irq.np, out_irq.args,
537 					  out_irq.args_count, &p_fwspec);
538 
539 		return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec);
540 	}
541 
542 	if (!host_data->drv_data->desc_irqs)
543 		return -EINVAL;
544 
545 	desc_irq = host_data->drv_data->desc_irqs[hwirq];
546 	if (desc_irq != EXTI_INVALID_IRQ) {
547 		p_fwspec.fwnode = dm->parent->fwnode;
548 		p_fwspec.param_count = 3;
549 		p_fwspec.param[0] = GIC_SPI;
550 		p_fwspec.param[1] = desc_irq;
551 		p_fwspec.param[2] = IRQ_TYPE_LEVEL_HIGH;
552 
553 		return irq_domain_alloc_irqs_parent(dm, virq, 1, &p_fwspec);
554 	}
555 
556 	return 0;
557 }
558 
stm32mp_exti_chip_init(struct stm32mp_exti_host_data * h_data,u32 bank_idx,struct device_node * node)559 static struct stm32mp_exti_chip_data *stm32mp_exti_chip_init(struct stm32mp_exti_host_data *h_data,
560 							     u32 bank_idx, struct device_node *node)
561 {
562 	struct stm32mp_exti_chip_data *chip_data;
563 	const struct stm32mp_exti_bank *bank;
564 	void __iomem *base = h_data->base;
565 
566 	bank = h_data->drv_data->exti_banks[bank_idx];
567 	chip_data = &h_data->chips_data[bank_idx];
568 	chip_data->host_data = h_data;
569 	chip_data->reg_bank = bank;
570 
571 	raw_spin_lock_init(&chip_data->rlock);
572 
573 	/*
574 	 * This IP has no reset, so after hot reboot we should
575 	 * clear registers to avoid residue
576 	 */
577 	writel_relaxed(0, base + bank->imr_ofst);
578 
579 	/* reserve Secure events */
580 	chip_data->event_reserved = readl_relaxed(base + bank->seccfgr_ofst);
581 
582 	pr_info("%pOF: bank%d\n", node, bank_idx);
583 
584 	return chip_data;
585 }
586 
587 static const struct irq_domain_ops stm32mp_exti_domain_ops = {
588 	.alloc	= stm32mp_exti_domain_alloc,
589 	.free	= irq_domain_free_irqs_common,
590 	.xlate = irq_domain_xlate_twocell,
591 };
592 
stm32mp_exti_check_rif(struct stm32mp_exti_host_data * host_data)593 static void stm32mp_exti_check_rif(struct stm32mp_exti_host_data *host_data)
594 {
595 	unsigned int bank, i, event;
596 	u32 cid, cidcfgr, hwcfgr1;
597 
598 	/* quit on CID not supported */
599 	hwcfgr1 = readl_relaxed(host_data->base + EXTI_HWCFGR1);
600 	if ((hwcfgr1 & EXTI_HWCFGR1_CIDWIDTH_MASK) == 0)
601 		return;
602 
603 	for (bank = 0; bank < host_data->drv_data->bank_nr; bank++) {
604 		for (i = 0; i < IRQS_PER_BANK; i++) {
605 			event = bank * IRQS_PER_BANK + i;
606 			cidcfgr = readl_relaxed(host_data->base + EXTI_EnCIDCFGR(event));
607 			cid = (cidcfgr & EXTI_CIDCFGR_CID_MASK) >> EXTI_CIDCFGR_CID_SHIFT;
608 			if ((cidcfgr & EXTI_CIDCFGR_CFEN_MASK) && cid != EXTI_CID1)
609 				host_data->chips_data[bank].event_reserved |= BIT(i);
610 		}
611 	}
612 }
613 
stm32mp_exti_remove_irq(void * data)614 static void stm32mp_exti_remove_irq(void *data)
615 {
616 	struct irq_domain *domain = data;
617 
618 	irq_domain_remove(domain);
619 }
620 
stm32mp_exti_probe(struct platform_device * pdev)621 static int stm32mp_exti_probe(struct platform_device *pdev)
622 {
623 	const struct stm32mp_exti_drv_data *drv_data;
624 	struct irq_domain *parent_domain, *domain;
625 	struct stm32mp_exti_host_data *host_data;
626 	struct device *dev = &pdev->dev;
627 	struct device_node *np = dev->of_node;
628 	int ret, i;
629 
630 	host_data = devm_kzalloc(dev, sizeof(*host_data), GFP_KERNEL);
631 	if (!host_data)
632 		return -ENOMEM;
633 
634 	dev_set_drvdata(dev, host_data);
635 	host_data->dev = dev;
636 
637 	/* check for optional hwspinlock which may be not available yet */
638 	ret = of_hwspin_lock_get_id(np, 0);
639 	if (ret == -EPROBE_DEFER)
640 		/* hwspinlock framework not yet ready */
641 		return ret;
642 
643 	if (ret >= 0) {
644 		host_data->hwlock = devm_hwspin_lock_request_specific(dev, ret);
645 		if (!host_data->hwlock) {
646 			dev_err(dev, "Failed to request hwspinlock\n");
647 			return -EINVAL;
648 		}
649 	} else if (ret != -ENOENT) {
650 		/* note: ENOENT is a valid case (means 'no hwspinlock') */
651 		dev_err(dev, "Failed to get hwspinlock\n");
652 		return ret;
653 	}
654 
655 	/* initialize host_data */
656 	drv_data = of_device_get_match_data(dev);
657 	if (!drv_data) {
658 		dev_err(dev, "no of match data\n");
659 		return -ENODEV;
660 	}
661 	host_data->drv_data = drv_data;
662 
663 	host_data->chips_data = devm_kcalloc(dev, drv_data->bank_nr,
664 					     sizeof(*host_data->chips_data),
665 					     GFP_KERNEL);
666 	if (!host_data->chips_data)
667 		return -ENOMEM;
668 
669 	host_data->base = devm_platform_ioremap_resource(pdev, 0);
670 	if (IS_ERR(host_data->base))
671 		return PTR_ERR(host_data->base);
672 
673 	for (i = 0; i < drv_data->bank_nr; i++)
674 		stm32mp_exti_chip_init(host_data, i, np);
675 
676 	stm32mp_exti_check_rif(host_data);
677 
678 	parent_domain = irq_find_host(of_irq_find_parent(np));
679 	if (!parent_domain) {
680 		dev_err(dev, "GIC interrupt-parent not found\n");
681 		return -EINVAL;
682 	}
683 
684 	domain = irq_domain_create_hierarchy(parent_domain, 0, drv_data->bank_nr * IRQS_PER_BANK,
685 					     dev_fwnode(dev), &stm32mp_exti_domain_ops, host_data);
686 	if (!domain) {
687 		dev_err(dev, "Could not register exti domain\n");
688 		return -ENOMEM;
689 	}
690 
691 	ret = devm_add_action_or_reset(dev, stm32mp_exti_remove_irq, domain);
692 	if (ret)
693 		return ret;
694 
695 	host_data->dt_has_irqs_desc = of_property_present(np, "interrupts-extended");
696 
697 	return 0;
698 }
699 
700 static const struct of_device_id stm32mp_exti_ids[] = {
701 	{ .compatible = "st,stm32mp1-exti", .data = &stm32mp1_drv_data},
702 	{ .compatible = "st,stm32mp13-exti", .data = &stm32mp13_drv_data},
703 	{},
704 };
705 MODULE_DEVICE_TABLE(of, stm32mp_exti_ids);
706 
707 static const struct dev_pm_ops stm32mp_exti_dev_pm_ops = {
708 	NOIRQ_SYSTEM_SLEEP_PM_OPS(stm32mp_exti_suspend, stm32mp_exti_resume)
709 };
710 
711 static struct platform_driver stm32mp_exti_driver = {
712 	.probe		= stm32mp_exti_probe,
713 	.driver		= {
714 		.name		= "stm32mp_exti",
715 		.of_match_table	= stm32mp_exti_ids,
716 		.pm		= &stm32mp_exti_dev_pm_ops,
717 	},
718 };
719 
720 module_platform_driver(stm32mp_exti_driver);
721 
722 MODULE_AUTHOR("Maxime Coquelin <mcoquelin.stm32@gmail.com>");
723 MODULE_DESCRIPTION("STM32MP EXTI driver");
724 MODULE_LICENSE("GPL");
725