6
6
*/
7
7
8
8
#include <linux/bitops.h>
9
+ #include <linux/delay.h>
10
+ #include <linux/hwspinlock.h>
9
11
#include <linux/interrupt.h>
10
12
#include <linux/io.h>
11
13
#include <linux/irq.h>
20
22
21
23
#define IRQS_PER_BANK 32
22
24
25
+ #define HWSPNLCK_TIMEOUT 1000 /* usec */
26
+ #define HWSPNLCK_RETRY_DELAY 100 /* usec */
27
+
23
28
struct stm32_exti_bank {
24
29
u32 imr_ofst ;
25
30
u32 emr_ofst ;
@@ -32,6 +37,12 @@ struct stm32_exti_bank {
32
37
33
38
#define UNDEF_REG ~0
34
39
40
+ enum stm32_exti_hwspinlock {
41
+ HWSPINLOCK_UNKNOWN ,
42
+ HWSPINLOCK_NONE ,
43
+ HWSPINLOCK_READY ,
44
+ };
45
+
35
46
struct stm32_desc_irq {
36
47
u32 exti ;
37
48
u32 irq_parent ;
@@ -58,6 +69,9 @@ struct stm32_exti_host_data {
58
69
void __iomem * base ;
59
70
struct stm32_exti_chip_data * chips_data ;
60
71
const struct stm32_exti_drv_data * drv_data ;
72
+ struct device_node * node ;
73
+ enum stm32_exti_hwspinlock hwlock_state ;
74
+ struct hwspinlock * hwlock ;
61
75
};
62
76
63
77
static struct stm32_exti_host_data * stm32_host_data ;
@@ -269,6 +283,64 @@ static int stm32_exti_set_type(struct irq_data *d,
269
283
return 0 ;
270
284
}
271
285
286
+ static int stm32_exti_hwspin_lock (struct stm32_exti_chip_data * chip_data )
287
+ {
288
+ struct stm32_exti_host_data * host_data = chip_data -> host_data ;
289
+ struct hwspinlock * hwlock ;
290
+ int id , ret = 0 , timeout = 0 ;
291
+
292
+ /* first time, check for hwspinlock availability */
293
+ if (unlikely (host_data -> hwlock_state == HWSPINLOCK_UNKNOWN )) {
294
+ id = of_hwspin_lock_get_id (host_data -> node , 0 );
295
+ if (id >= 0 ) {
296
+ hwlock = hwspin_lock_request_specific (id );
297
+ if (hwlock ) {
298
+ /* found valid hwspinlock */
299
+ host_data -> hwlock_state = HWSPINLOCK_READY ;
300
+ host_data -> hwlock = hwlock ;
301
+ pr_debug ("%s hwspinlock = %d\n" , __func__ , id );
302
+ } else {
303
+ host_data -> hwlock_state = HWSPINLOCK_NONE ;
304
+ }
305
+ } else if (id != - EPROBE_DEFER ) {
306
+ host_data -> hwlock_state = HWSPINLOCK_NONE ;
307
+ } else {
308
+ /* hwspinlock driver shall be ready at that stage */
309
+ ret = - EPROBE_DEFER ;
310
+ }
311
+ }
312
+
313
+ if (likely (host_data -> hwlock_state == HWSPINLOCK_READY )) {
314
+ /*
315
+ * Use the x_raw API since we are under spin_lock protection.
316
+ * Do not use the x_timeout API because we are under irq_disable
317
+ * mode (see __setup_irq())
318
+ */
319
+ do {
320
+ ret = hwspin_trylock_raw (host_data -> hwlock );
321
+ if (!ret )
322
+ return 0 ;
323
+
324
+ udelay (HWSPNLCK_RETRY_DELAY );
325
+ timeout += HWSPNLCK_RETRY_DELAY ;
326
+ } while (timeout < HWSPNLCK_TIMEOUT );
327
+
328
+ if (ret == - EBUSY )
329
+ ret = - ETIMEDOUT ;
330
+ }
331
+
332
+ if (ret )
333
+ pr_err ("%s can't get hwspinlock (%d)\n" , __func__ , ret );
334
+
335
+ return ret ;
336
+ }
337
+
338
+ static void stm32_exti_hwspin_unlock (struct stm32_exti_chip_data * chip_data )
339
+ {
340
+ if (likely (chip_data -> host_data -> hwlock_state == HWSPINLOCK_READY ))
341
+ hwspin_unlock_raw (chip_data -> host_data -> hwlock );
342
+ }
343
+
272
344
static int stm32_irq_set_type (struct irq_data * d , unsigned int type )
273
345
{
274
346
struct irq_chip_generic * gc = irq_data_get_irq_chip_data (d );
@@ -279,21 +351,26 @@ static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
279
351
280
352
irq_gc_lock (gc );
281
353
354
+ err = stm32_exti_hwspin_lock (chip_data );
355
+ if (err )
356
+ goto unlock ;
357
+
282
358
rtsr = irq_reg_readl (gc , stm32_bank -> rtsr_ofst );
283
359
ftsr = irq_reg_readl (gc , stm32_bank -> ftsr_ofst );
284
360
285
361
err = stm32_exti_set_type (d , type , & rtsr , & ftsr );
286
- if (err ) {
287
- irq_gc_unlock (gc );
288
- return err ;
289
- }
362
+ if (err )
363
+ goto unspinlock ;
290
364
291
365
irq_reg_writel (gc , rtsr , stm32_bank -> rtsr_ofst );
292
366
irq_reg_writel (gc , ftsr , stm32_bank -> ftsr_ofst );
293
367
368
+ unspinlock :
369
+ stm32_exti_hwspin_unlock (chip_data );
370
+ unlock :
294
371
irq_gc_unlock (gc );
295
372
296
- return 0 ;
373
+ return err ;
297
374
}
298
375
299
376
static void stm32_chip_suspend (struct stm32_exti_chip_data * chip_data ,
@@ -460,20 +537,27 @@ static int stm32_exti_h_set_type(struct irq_data *d, unsigned int type)
460
537
int err ;
461
538
462
539
raw_spin_lock (& chip_data -> rlock );
540
+
541
+ err = stm32_exti_hwspin_lock (chip_data );
542
+ if (err )
543
+ goto unlock ;
544
+
463
545
rtsr = readl_relaxed (base + stm32_bank -> rtsr_ofst );
464
546
ftsr = readl_relaxed (base + stm32_bank -> ftsr_ofst );
465
547
466
548
err = stm32_exti_set_type (d , type , & rtsr , & ftsr );
467
- if (err ) {
468
- raw_spin_unlock (& chip_data -> rlock );
469
- return err ;
470
- }
549
+ if (err )
550
+ goto unspinlock ;
471
551
472
552
writel_relaxed (rtsr , base + stm32_bank -> rtsr_ofst );
473
553
writel_relaxed (ftsr , base + stm32_bank -> ftsr_ofst );
554
+
555
+ unspinlock :
556
+ stm32_exti_hwspin_unlock (chip_data );
557
+ unlock :
474
558
raw_spin_unlock (& chip_data -> rlock );
475
559
476
- return 0 ;
560
+ return err ;
477
561
}
478
562
479
563
static int stm32_exti_h_set_wake (struct irq_data * d , unsigned int on )
@@ -599,6 +683,8 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
599
683
return NULL ;
600
684
601
685
host_data -> drv_data = dd ;
686
+ host_data -> node = node ;
687
+ host_data -> hwlock_state = HWSPINLOCK_UNKNOWN ;
602
688
host_data -> chips_data = kcalloc (dd -> bank_nr ,
603
689
sizeof (struct stm32_exti_chip_data ),
604
690
GFP_KERNEL );
@@ -625,8 +711,7 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd,
625
711
626
712
static struct
627
713
stm32_exti_chip_data * stm32_exti_chip_init (struct stm32_exti_host_data * h_data ,
628
- u32 bank_idx ,
629
- struct device_node * node )
714
+ u32 bank_idx )
630
715
{
631
716
const struct stm32_exti_bank * stm32_bank ;
632
717
struct stm32_exti_chip_data * chip_data ;
@@ -656,8 +741,7 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
656
741
if (stm32_bank -> fpr_ofst != UNDEF_REG )
657
742
writel_relaxed (~0UL , base + stm32_bank -> fpr_ofst );
658
743
659
- pr_info ("%s: bank%d, External IRQs available:%#x\n" ,
660
- node -> full_name , bank_idx , irqs_mask );
744
+ pr_info ("%pOF: bank%d\n" , h_data -> node , bank_idx );
661
745
662
746
return chip_data ;
663
747
}
@@ -697,7 +781,7 @@ static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data,
697
781
struct stm32_exti_chip_data * chip_data ;
698
782
699
783
stm32_bank = drv_data -> exti_banks [i ];
700
- chip_data = stm32_exti_chip_init (host_data , i , node );
784
+ chip_data = stm32_exti_chip_init (host_data , i );
701
785
702
786
gc = irq_get_domain_generic_chip (domain , i * IRQS_PER_BANK );
703
787
@@ -760,7 +844,7 @@ __init stm32_exti_hierarchy_init(const struct stm32_exti_drv_data *drv_data,
760
844
return - ENOMEM ;
761
845
762
846
for (i = 0 ; i < drv_data -> bank_nr ; i ++ )
763
- stm32_exti_chip_init (host_data , i , node );
847
+ stm32_exti_chip_init (host_data , i );
764
848
765
849
domain = irq_domain_add_hierarchy (parent_domain , 0 ,
766
850
drv_data -> bank_nr * IRQS_PER_BANK ,
0 commit comments