@@ -832,6 +832,52 @@ static void msm_gpio_irq_unmask(struct irq_data *d)
832
832
msm_gpio_irq_clear_unmask (d , false);
833
833
}
834
834
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
+
835
881
static void msm_gpio_irq_ack (struct irq_data * d )
836
882
{
837
883
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)
840
886
unsigned long flags ;
841
887
u32 val ;
842
888
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 );
844
892
return ;
893
+ }
845
894
846
895
g = & pctrl -> soc -> groups [d -> hwirq ];
847
896
@@ -860,6 +909,17 @@ static void msm_gpio_irq_ack(struct irq_data *d)
860
909
raw_spin_unlock_irqrestore (& pctrl -> lock , flags );
861
910
}
862
911
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
+
863
923
static int msm_gpio_irq_set_type (struct irq_data * d , unsigned int type )
864
924
{
865
925
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)
868
928
unsigned long flags ;
869
929
u32 val ;
870
930
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
+
871
938
if (d -> parent_data )
872
939
irq_chip_set_type_parent (d , type );
873
940
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 );
875
944
return 0 ;
945
+ }
876
946
877
947
g = & pctrl -> soc -> groups [d -> hwirq ];
878
948
0 commit comments