15
15
#include <linux/of_address.h>
16
16
#include <linux/of_irq.h>
17
17
18
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
19
+
18
20
#define IRQS_PER_BANK 32
19
21
20
22
struct stm32_exti_bank {
@@ -29,14 +31,24 @@ struct stm32_exti_bank {
29
31
30
32
#define UNDEF_REG ~0
31
33
34
+ struct stm32_desc_irq {
35
+ u32 exti ;
36
+ u32 irq_parent ;
37
+ };
38
+
32
39
struct stm32_exti_drv_data {
33
40
const struct stm32_exti_bank * * exti_banks ;
41
+ const struct stm32_desc_irq * desc_irqs ;
34
42
u32 bank_nr ;
43
+ u32 irq_nr ;
35
44
};
36
45
37
46
struct stm32_exti_chip_data {
38
47
struct stm32_exti_host_data * host_data ;
39
48
const struct stm32_exti_bank * reg_bank ;
49
+ struct raw_spinlock rlock ;
50
+ u32 wake_active ;
51
+ u32 mask_cache ;
40
52
u32 rtsr_cache ;
41
53
u32 ftsr_cache ;
42
54
};
@@ -107,6 +119,89 @@ static const struct stm32_exti_drv_data stm32h7xx_drv_data = {
107
119
.bank_nr = ARRAY_SIZE (stm32h7xx_exti_banks ),
108
120
};
109
121
122
+ static const struct stm32_exti_bank stm32mp1_exti_b1 = {
123
+ .imr_ofst = 0x80 ,
124
+ .emr_ofst = 0x84 ,
125
+ .rtsr_ofst = 0x00 ,
126
+ .ftsr_ofst = 0x04 ,
127
+ .swier_ofst = 0x08 ,
128
+ .rpr_ofst = 0x0C ,
129
+ .fpr_ofst = 0x10 ,
130
+ };
131
+
132
+ static const struct stm32_exti_bank stm32mp1_exti_b2 = {
133
+ .imr_ofst = 0x90 ,
134
+ .emr_ofst = 0x94 ,
135
+ .rtsr_ofst = 0x20 ,
136
+ .ftsr_ofst = 0x24 ,
137
+ .swier_ofst = 0x28 ,
138
+ .rpr_ofst = 0x2C ,
139
+ .fpr_ofst = 0x30 ,
140
+ };
141
+
142
+ static const struct stm32_exti_bank stm32mp1_exti_b3 = {
143
+ .imr_ofst = 0xA0 ,
144
+ .emr_ofst = 0xA4 ,
145
+ .rtsr_ofst = 0x40 ,
146
+ .ftsr_ofst = 0x44 ,
147
+ .swier_ofst = 0x48 ,
148
+ .rpr_ofst = 0x4C ,
149
+ .fpr_ofst = 0x50 ,
150
+ };
151
+
152
+ static const struct stm32_exti_bank * stm32mp1_exti_banks [] = {
153
+ & stm32mp1_exti_b1 ,
154
+ & stm32mp1_exti_b2 ,
155
+ & stm32mp1_exti_b3 ,
156
+ };
157
+
158
+ static const struct stm32_desc_irq stm32mp1_desc_irq [] = {
159
+ { .exti = 1 , .irq_parent = 7 },
160
+ { .exti = 2 , .irq_parent = 8 },
161
+ { .exti = 3 , .irq_parent = 9 },
162
+ { .exti = 4 , .irq_parent = 10 },
163
+ { .exti = 5 , .irq_parent = 23 },
164
+ { .exti = 6 , .irq_parent = 64 },
165
+ { .exti = 7 , .irq_parent = 65 },
166
+ { .exti = 8 , .irq_parent = 66 },
167
+ { .exti = 9 , .irq_parent = 67 },
168
+ { .exti = 10 , .irq_parent = 40 },
169
+ { .exti = 11 , .irq_parent = 42 },
170
+ { .exti = 12 , .irq_parent = 76 },
171
+ { .exti = 13 , .irq_parent = 77 },
172
+ { .exti = 14 , .irq_parent = 121 },
173
+ { .exti = 15 , .irq_parent = 127 },
174
+ { .exti = 16 , .irq_parent = 1 },
175
+ { .exti = 65 , .irq_parent = 144 },
176
+ { .exti = 68 , .irq_parent = 143 },
177
+ { .exti = 73 , .irq_parent = 129 },
178
+ };
179
+
180
+ static const struct stm32_exti_drv_data stm32mp1_drv_data = {
181
+ .exti_banks = stm32mp1_exti_banks ,
182
+ .bank_nr = ARRAY_SIZE (stm32mp1_exti_banks ),
183
+ .desc_irqs = stm32mp1_desc_irq ,
184
+ .irq_nr = ARRAY_SIZE (stm32mp1_desc_irq ),
185
+ };
186
+
187
+ static int stm32_exti_to_irq (const struct stm32_exti_drv_data * drv_data ,
188
+ irq_hw_number_t hwirq )
189
+ {
190
+ const struct stm32_desc_irq * desc_irq ;
191
+ int i ;
192
+
193
+ if (!drv_data -> desc_irqs )
194
+ return - EINVAL ;
195
+
196
+ for (i = 0 ; i < drv_data -> irq_nr ; i ++ ) {
197
+ desc_irq = & drv_data -> desc_irqs [i ];
198
+ if (desc_irq -> exti == hwirq )
199
+ return desc_irq -> irq_parent ;
200
+ }
201
+
202
+ return - EINVAL ;
203
+ }
204
+
110
205
static unsigned long stm32_exti_pending (struct irq_chip_generic * gc )
111
206
{
112
207
struct stm32_exti_chip_data * chip_data = gc -> private ;
@@ -282,6 +377,173 @@ static void stm32_irq_ack(struct irq_data *d)
282
377
283
378
irq_gc_unlock (gc );
284
379
}
380
+
381
+ static inline u32 stm32_exti_set_bit (struct irq_data * d , u32 reg )
382
+ {
383
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
384
+ void __iomem * base = chip_data -> host_data -> base ;
385
+ u32 val ;
386
+
387
+ val = readl_relaxed (base + reg );
388
+ val |= BIT (d -> hwirq % IRQS_PER_BANK );
389
+ writel_relaxed (val , base + reg );
390
+
391
+ return val ;
392
+ }
393
+
394
+ static inline u32 stm32_exti_clr_bit (struct irq_data * d , u32 reg )
395
+ {
396
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
397
+ void __iomem * base = chip_data -> host_data -> base ;
398
+ u32 val ;
399
+
400
+ val = readl_relaxed (base + reg );
401
+ val &= ~BIT (d -> hwirq % IRQS_PER_BANK );
402
+ writel_relaxed (val , base + reg );
403
+
404
+ return val ;
405
+ }
406
+
407
+ static void stm32_exti_h_eoi (struct irq_data * d )
408
+ {
409
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
410
+ const struct stm32_exti_bank * stm32_bank = chip_data -> reg_bank ;
411
+
412
+ raw_spin_lock (& chip_data -> rlock );
413
+
414
+ stm32_exti_set_bit (d , stm32_bank -> rpr_ofst );
415
+ if (stm32_bank -> fpr_ofst != UNDEF_REG )
416
+ stm32_exti_set_bit (d , stm32_bank -> fpr_ofst );
417
+
418
+ raw_spin_unlock (& chip_data -> rlock );
419
+
420
+ if (d -> parent_data -> chip )
421
+ irq_chip_eoi_parent (d );
422
+ }
423
+
424
+ static void stm32_exti_h_mask (struct irq_data * d )
425
+ {
426
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
427
+ const struct stm32_exti_bank * stm32_bank = chip_data -> reg_bank ;
428
+
429
+ raw_spin_lock (& chip_data -> rlock );
430
+ chip_data -> mask_cache = stm32_exti_clr_bit (d , stm32_bank -> imr_ofst );
431
+ raw_spin_unlock (& chip_data -> rlock );
432
+
433
+ if (d -> parent_data -> chip )
434
+ irq_chip_mask_parent (d );
435
+ }
436
+
437
+ static void stm32_exti_h_unmask (struct irq_data * d )
438
+ {
439
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
440
+ const struct stm32_exti_bank * stm32_bank = chip_data -> reg_bank ;
441
+
442
+ raw_spin_lock (& chip_data -> rlock );
443
+ chip_data -> mask_cache = stm32_exti_set_bit (d , stm32_bank -> imr_ofst );
444
+ raw_spin_unlock (& chip_data -> rlock );
445
+
446
+ if (d -> parent_data -> chip )
447
+ irq_chip_unmask_parent (d );
448
+ }
449
+
450
+ static int stm32_exti_h_set_type (struct irq_data * d , unsigned int type )
451
+ {
452
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
453
+ const struct stm32_exti_bank * stm32_bank = chip_data -> reg_bank ;
454
+ void __iomem * base = chip_data -> host_data -> base ;
455
+ u32 rtsr , ftsr ;
456
+ int err ;
457
+
458
+ raw_spin_lock (& chip_data -> rlock );
459
+ rtsr = readl_relaxed (base + stm32_bank -> rtsr_ofst );
460
+ ftsr = readl_relaxed (base + stm32_bank -> ftsr_ofst );
461
+
462
+ err = stm32_exti_set_type (d , type , & rtsr , & ftsr );
463
+ if (err ) {
464
+ raw_spin_unlock (& chip_data -> rlock );
465
+ return err ;
466
+ }
467
+
468
+ writel_relaxed (rtsr , base + stm32_bank -> rtsr_ofst );
469
+ writel_relaxed (ftsr , base + stm32_bank -> ftsr_ofst );
470
+ raw_spin_unlock (& chip_data -> rlock );
471
+
472
+ return 0 ;
473
+ }
474
+
475
+ static int stm32_exti_h_set_wake (struct irq_data * d , unsigned int on )
476
+ {
477
+ struct stm32_exti_chip_data * chip_data = irq_data_get_irq_chip_data (d );
478
+ u32 mask = BIT (d -> hwirq % IRQS_PER_BANK );
479
+
480
+ raw_spin_lock (& chip_data -> rlock );
481
+
482
+ if (on )
483
+ chip_data -> wake_active |= mask ;
484
+ else
485
+ chip_data -> wake_active &= ~mask ;
486
+
487
+ raw_spin_unlock (& chip_data -> rlock );
488
+
489
+ return 0 ;
490
+ }
491
+
492
+ static int stm32_exti_h_set_affinity (struct irq_data * d ,
493
+ const struct cpumask * dest , bool force )
494
+ {
495
+ if (d -> parent_data -> chip )
496
+ return irq_chip_set_affinity_parent (d , dest , force );
497
+
498
+ return - EINVAL ;
499
+ }
500
+
501
+ static struct irq_chip stm32_exti_h_chip = {
502
+ .name = "stm32-exti-h" ,
503
+ .irq_eoi = stm32_exti_h_eoi ,
504
+ .irq_mask = stm32_exti_h_mask ,
505
+ .irq_unmask = stm32_exti_h_unmask ,
506
+ .irq_retrigger = irq_chip_retrigger_hierarchy ,
507
+ .irq_set_type = stm32_exti_h_set_type ,
508
+ .irq_set_wake = stm32_exti_h_set_wake ,
509
+ .flags = IRQCHIP_MASK_ON_SUSPEND ,
510
+ #ifdef CONFIG_SMP
511
+ .irq_set_affinity = stm32_exti_h_set_affinity ,
512
+ #endif
513
+ };
514
+
515
+ static int stm32_exti_h_domain_alloc (struct irq_domain * dm ,
516
+ unsigned int virq ,
517
+ unsigned int nr_irqs , void * data )
518
+ {
519
+ struct stm32_exti_host_data * host_data = dm -> host_data ;
520
+ struct stm32_exti_chip_data * chip_data ;
521
+ struct irq_fwspec * fwspec = data ;
522
+ struct irq_fwspec p_fwspec ;
523
+ irq_hw_number_t hwirq ;
524
+ int p_irq , bank ;
525
+
526
+ hwirq = fwspec -> param [0 ];
527
+ bank = hwirq / IRQS_PER_BANK ;
528
+ chip_data = & host_data -> chips_data [bank ];
529
+
530
+ irq_domain_set_hwirq_and_chip (dm , virq , hwirq ,
531
+ & stm32_exti_h_chip , chip_data );
532
+
533
+ p_irq = stm32_exti_to_irq (host_data -> drv_data , hwirq );
534
+ if (p_irq >= 0 ) {
535
+ p_fwspec .fwnode = dm -> parent -> fwnode ;
536
+ p_fwspec .param_count = 3 ;
537
+ p_fwspec .param [0 ] = GIC_SPI ;
538
+ p_fwspec .param [1 ] = p_irq ;
539
+ p_fwspec .param [2 ] = IRQ_TYPE_LEVEL_HIGH ;
540
+
541
+ return irq_domain_alloc_irqs_parent (dm , virq , 1 , & p_fwspec );
542
+ }
543
+
544
+ return 0 ;
545
+ }
546
+
285
547
static struct
286
548
stm32_exti_host_data * stm32_exti_host_init (const struct stm32_exti_drv_data * dd ,
287
549
struct device_node * node )
@@ -323,6 +585,8 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
323
585
chip_data -> host_data = h_data ;
324
586
chip_data -> reg_bank = stm32_bank ;
325
587
588
+ raw_spin_lock_init (& chip_data -> rlock );
589
+
326
590
/* Determine number of irqs supported */
327
591
writel_relaxed (~0UL , base + stm32_bank -> rtsr_ofst );
328
592
irqs_mask = readl_relaxed (base + stm32_bank -> rtsr_ofst );
@@ -421,6 +685,56 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
421
685
return ret ;
422
686
}
423
687
688
+ static const struct irq_domain_ops stm32_exti_h_domain_ops = {
689
+ .alloc = stm32_exti_h_domain_alloc ,
690
+ .free = irq_domain_free_irqs_common ,
691
+ };
692
+
693
+ static int
694
+ __init stm32_exti_hierarchy_init (const struct stm32_exti_drv_data * drv_data ,
695
+ struct device_node * node ,
696
+ struct device_node * parent )
697
+ {
698
+ struct irq_domain * parent_domain , * domain ;
699
+ struct stm32_exti_host_data * host_data ;
700
+ int ret , i ;
701
+
702
+ parent_domain = irq_find_host (parent );
703
+ if (!parent_domain ) {
704
+ pr_err ("interrupt-parent not found\n" );
705
+ return - EINVAL ;
706
+ }
707
+
708
+ host_data = stm32_exti_host_init (drv_data , node );
709
+ if (!host_data ) {
710
+ ret = - ENOMEM ;
711
+ goto out_free_mem ;
712
+ }
713
+
714
+ for (i = 0 ; i < drv_data -> bank_nr ; i ++ )
715
+ stm32_exti_chip_init (host_data , i , node );
716
+
717
+ domain = irq_domain_add_hierarchy (parent_domain , 0 ,
718
+ drv_data -> bank_nr * IRQS_PER_BANK ,
719
+ node , & stm32_exti_h_domain_ops ,
720
+ host_data );
721
+
722
+ if (!domain ) {
723
+ pr_err ("%s: Could not register exti domain.\n" , node -> name );
724
+ ret = - ENOMEM ;
725
+ goto out_unmap ;
726
+ }
727
+
728
+ return 0 ;
729
+
730
+ out_unmap :
731
+ iounmap (host_data -> base );
732
+ out_free_mem :
733
+ kfree (host_data -> chips_data );
734
+ kfree (host_data );
735
+ return ret ;
736
+ }
737
+
424
738
static int __init stm32f4_exti_of_init (struct device_node * np ,
425
739
struct device_node * parent )
426
740
{
@@ -436,3 +750,11 @@ static int __init stm32h7_exti_of_init(struct device_node *np,
436
750
}
437
751
438
752
IRQCHIP_DECLARE (stm32h7_exti , "st,stm32h7-exti" , stm32h7_exti_of_init );
753
+
754
+ static int __init stm32mp1_exti_of_init (struct device_node * np ,
755
+ struct device_node * parent )
756
+ {
757
+ return stm32_exti_hierarchy_init (& stm32mp1_drv_data , np , parent );
758
+ }
759
+
760
+ IRQCHIP_DECLARE (stm32mp1_exti , "st,stm32mp1-exti" , stm32mp1_exti_of_init );
0 commit comments