@@ -576,6 +576,19 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
576
576
case IRQ_TYPE_EDGE_FALLING :
577
577
val |= (BIT (d -> hwirq % GPIO_PER_REG ));
578
578
break ;
579
+ case IRQ_TYPE_EDGE_BOTH : {
580
+ u32 in_val , in_reg = INPUT_VAL ;
581
+
582
+ armada_37xx_irq_update_reg (& in_reg , d );
583
+ regmap_read (info -> regmap , in_reg , & in_val );
584
+
585
+ /* Set initial polarity based on current input level. */
586
+ if (in_val & d -> mask )
587
+ val |= d -> mask ; /* falling */
588
+ else
589
+ val &= ~d -> mask ; /* rising */
590
+ break ;
591
+ }
579
592
default :
580
593
spin_unlock_irqrestore (& info -> irq_lock , flags );
581
594
return - EINVAL ;
@@ -586,6 +599,40 @@ static int armada_37xx_irq_set_type(struct irq_data *d, unsigned int type)
586
599
return 0 ;
587
600
}
588
601
602
+ static int armada_37xx_edge_both_irq_swap_pol (struct armada_37xx_pinctrl * info ,
603
+ u32 pin_idx )
604
+ {
605
+ u32 reg_idx = pin_idx / GPIO_PER_REG ;
606
+ u32 bit_num = pin_idx % GPIO_PER_REG ;
607
+ u32 p , l , ret ;
608
+ unsigned long flags ;
609
+
610
+ regmap_read (info -> regmap , INPUT_VAL + 4 * reg_idx , & l );
611
+
612
+ spin_lock_irqsave (& info -> irq_lock , flags );
613
+ p = readl (info -> base + IRQ_POL + 4 * reg_idx );
614
+ if ((p ^ l ) & (1 << bit_num )) {
615
+ /*
616
+ * For the gpios which are used for both-edge irqs, when their
617
+ * interrupts happen, their input levels are changed,
618
+ * yet their interrupt polarities are kept in old values, we
619
+ * should synchronize their interrupt polarities; for example,
620
+ * at first a gpio's input level is low and its interrupt
621
+ * polarity control is "Detect rising edge", then the gpio has
622
+ * a interrupt , its level turns to high, we should change its
623
+ * polarity control to "Detect falling edge" correspondingly.
624
+ */
625
+ p ^= 1 << bit_num ;
626
+ writel (p , info -> base + IRQ_POL + 4 * reg_idx );
627
+ ret = 0 ;
628
+ } else {
629
+ /* Spurious irq */
630
+ ret = -1 ;
631
+ }
632
+
633
+ spin_unlock_irqrestore (& info -> irq_lock , flags );
634
+ return ret ;
635
+ }
589
636
590
637
static void armada_37xx_irq_handler (struct irq_desc * desc )
591
638
{
@@ -609,6 +656,23 @@ static void armada_37xx_irq_handler(struct irq_desc *desc)
609
656
u32 hwirq = ffs (status ) - 1 ;
610
657
u32 virq = irq_find_mapping (d , hwirq +
611
658
i * GPIO_PER_REG );
659
+ u32 t = irq_get_trigger_type (virq );
660
+
661
+ if ((t & IRQ_TYPE_SENSE_MASK ) == IRQ_TYPE_EDGE_BOTH ) {
662
+ /* Swap polarity (race with GPIO line) */
663
+ if (armada_37xx_edge_both_irq_swap_pol (info ,
664
+ hwirq + i * GPIO_PER_REG )) {
665
+ /*
666
+ * For spurious irq, which gpio level
667
+ * is not as expected after incoming
668
+ * edge, just ack the gpio irq.
669
+ */
670
+ writel (1 << hwirq ,
671
+ info -> base +
672
+ IRQ_STATUS + 4 * i );
673
+ continue ;
674
+ }
675
+ }
612
676
613
677
generic_handle_irq (virq );
614
678
0 commit comments