@@ -832,6 +832,52 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
832832 msm_gpio_irq_clear_unmask (d , false);
833833}
834834
835+ /**
836+ * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent.
837+ * @d: The irq dta.
838+ *
839+ * This is much like msm_gpio_update_dual_edge_pos() but for IRQs that are
840+ * normally handled by the parent irqchip. The logic here is slightly
841+ * different due to what's easy to do with our parent, but in principle it's
842+ * the same.
843+ */
844+ static void msm_gpio_update_dual_edge_parent (struct irq_data * d )
845+ {
846+ struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
847+ struct msm_pinctrl * pctrl = gpiochip_get_data (gc );
848+ const struct msm_pingroup * g = & pctrl -> soc -> groups [d -> hwirq ];
849+ int loop_limit = 100 ;
850+ unsigned int val ;
851+ unsigned int type ;
852+
853+ /* Read the value and make a guess about what edge we need to catch */
854+ val = msm_readl_io (pctrl , g ) & BIT (g -> in_bit );
855+ type = val ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING ;
856+
857+ do {
858+ /* Set the parent to catch the next edge */
859+ irq_chip_set_type_parent (d , type );
860+
861+ /*
862+ * Possibly the line changed between when we last read "val"
863+ * (and decided what edge we needed) and when set the edge.
864+ * If the value didn't change (or changed and then changed
865+ * back) then we're done.
866+ */
867+ val = msm_readl_io (pctrl , g ) & BIT (g -> in_bit );
868+ if (type == IRQ_TYPE_EDGE_RISING ) {
869+ if (!val )
870+ return ;
871+ type = IRQ_TYPE_EDGE_FALLING ;
872+ } else if (type == IRQ_TYPE_EDGE_FALLING ) {
873+ if (val )
874+ return ;
875+ type = IRQ_TYPE_EDGE_RISING ;
876+ }
877+ } while (loop_limit -- > 0 );
878+ dev_warn_once (pctrl -> dev , "dual-edge irq failed to stabilize\n" );
879+ }
880+
835881static void msm_gpio_irq_ack (struct irq_data * d )
836882{
837883 struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
@@ -840,8 +886,11 @@ static void msm_gpio_irq_ack(struct irq_data *d)
840886 unsigned long flags ;
841887 u32 val ;
842888
843- if (test_bit (d -> hwirq , pctrl -> skip_wake_irqs ))
889+ if (test_bit (d -> hwirq , pctrl -> skip_wake_irqs )) {
890+ if (test_bit (d -> hwirq , pctrl -> dual_edge_irqs ))
891+ msm_gpio_update_dual_edge_parent (d );
844892 return ;
893+ }
845894
846895 g = & pctrl -> soc -> groups [d -> hwirq ];
847896
@@ -860,6 +909,17 @@ static void msm_gpio_irq_ack(struct irq_data *d)
860909 raw_spin_unlock_irqrestore (& pctrl -> lock , flags );
861910}
862911
912+ static bool msm_gpio_needs_dual_edge_parent_workaround (struct irq_data * d ,
913+ unsigned int type )
914+ {
915+ struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
916+ struct msm_pinctrl * pctrl = gpiochip_get_data (gc );
917+
918+ return type == IRQ_TYPE_EDGE_BOTH &&
919+ pctrl -> soc -> wakeirq_dual_edge_errata && d -> parent_data &&
920+ test_bit (d -> hwirq , pctrl -> skip_wake_irqs );
921+ }
922+
863923static int msm_gpio_irq_set_type (struct irq_data * d , unsigned int type )
864924{
865925 struct gpio_chip * gc = irq_data_get_irq_chip_data (d );
@@ -868,11 +928,21 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
868928 unsigned long flags ;
869929 u32 val ;
870930
931+ if (msm_gpio_needs_dual_edge_parent_workaround (d , type )) {
932+ set_bit (d -> hwirq , pctrl -> dual_edge_irqs );
933+ irq_set_handler_locked (d , handle_fasteoi_ack_irq );
934+ msm_gpio_update_dual_edge_parent (d );
935+ return 0 ;
936+ }
937+
871938 if (d -> parent_data )
872939 irq_chip_set_type_parent (d , type );
873940
874- if (test_bit (d -> hwirq , pctrl -> skip_wake_irqs ))
941+ if (test_bit (d -> hwirq , pctrl -> skip_wake_irqs )) {
942+ clear_bit (d -> hwirq , pctrl -> dual_edge_irqs );
943+ irq_set_handler_locked (d , handle_fasteoi_irq );
875944 return 0 ;
945+ }
876946
877947 g = & pctrl -> soc -> groups [d -> hwirq ];
878948
0 commit comments