@@ -802,6 +802,265 @@ void thc_ltr_unconfig(struct thc_device *dev)
802
802
}
803
803
EXPORT_SYMBOL_NS_GPL (thc_ltr_unconfig , "INTEL_THC" );
804
804
805
+ /**
806
+ * thc_int_cause_read - Read interrupt cause register value
807
+ *
808
+ * @dev: The pointer of THC private device context
809
+ *
810
+ * Return: The interrupt cause register value
811
+ */
812
+ u32 thc_int_cause_read (struct thc_device * dev )
813
+ {
814
+ u32 int_cause ;
815
+
816
+ regmap_read (dev -> thc_regmap ,
817
+ THC_M_PRT_DEV_INT_CAUSE_REG_VAL_OFFSET , & int_cause );
818
+
819
+ return int_cause ;
820
+ }
821
+ EXPORT_SYMBOL_NS_GPL (thc_int_cause_read , "INTEL_THC" );
822
+
823
+ static void thc_print_txn_error_cause (const struct thc_device * dev )
824
+ {
825
+ bool known_error = false;
826
+ u32 cause = 0 ;
827
+
828
+ regmap_read (dev -> thc_regmap , THC_M_PRT_ERR_CAUSE_OFFSET , & cause );
829
+
830
+ if (cause & THC_M_PRT_ERR_CAUSE_PRD_ENTRY_ERR ) {
831
+ dev_err (dev -> dev , "TXN Error: Invalid PRD Entry\n" );
832
+ known_error = true;
833
+ }
834
+ if (cause & THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR ) {
835
+ dev_err (dev -> dev , "TXN Error: THC Buffer Overrun\n" );
836
+ known_error = true;
837
+ }
838
+ if (cause & THC_M_PRT_ERR_CAUSE_FRAME_BABBLE_ERR ) {
839
+ dev_err (dev -> dev , "TXN Error: Frame Babble\n" );
840
+ known_error = true;
841
+ }
842
+ if (cause & THC_M_PRT_ERR_CAUSE_INVLD_DEV_ENTRY ) {
843
+ dev_err (dev -> dev , "TXN Error: Invalid Device Register Setting\n" );
844
+ known_error = true;
845
+ }
846
+
847
+ /* Clear interrupt status bits */
848
+ regmap_write (dev -> thc_regmap , THC_M_PRT_ERR_CAUSE_OFFSET , cause );
849
+
850
+ if (!known_error )
851
+ dev_err (dev -> dev , "TXN Error does not match any known value: 0x%X\n" ,
852
+ cause );
853
+ }
854
+
855
+ /**
856
+ * thc_interrupt_handler - Handle THC interrupts
857
+ *
858
+ * THC interrupts include several types: external touch device (TIC) non-DMA
859
+ * interrupts, PIO completion interrupts, DMA interrtups, I2C subIP raw
860
+ * interrupts and error interrupts.
861
+ *
862
+ * This is a help function for interrupt processing, it detects interrupt
863
+ * type, clear the interrupt status bit and return the interrupt type to caller
864
+ * for future processing.
865
+ *
866
+ * @dev: The pointer of THC private device context
867
+ *
868
+ * Return: The combined flag for interrupt type
869
+ */
870
+ int thc_interrupt_handler (struct thc_device * dev )
871
+ {
872
+ u32 read_sts_1 , read_sts_2 , read_sts_sw , write_sts ;
873
+ u32 int_sts , err_cause , seq_cntrl , seq_sts ;
874
+ int interrupt_type = 0 ;
875
+
876
+ regmap_read (dev -> thc_regmap ,
877
+ THC_M_PRT_READ_DMA_INT_STS_1_OFFSET , & read_sts_1 );
878
+
879
+ if (read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS ) {
880
+ dev_dbg (dev -> dev , "THC non-DMA device interrupt\n" );
881
+
882
+ regmap_write (dev -> thc_regmap , THC_M_PRT_READ_DMA_INT_STS_1_OFFSET ,
883
+ NONDMA_INT_STS_BIT );
884
+
885
+ interrupt_type |= BIT (THC_NONDMA_INT );
886
+
887
+ return interrupt_type ;
888
+ }
889
+
890
+ regmap_read (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET , & int_sts );
891
+
892
+ if (int_sts & THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS ) {
893
+ dev_err (dev -> dev , "THC transaction error, int_sts: 0x%08X\n" , int_sts );
894
+ thc_print_txn_error_cause (dev );
895
+
896
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
897
+ TXN_ERR_INT_STS_BIT );
898
+
899
+ interrupt_type |= BIT (THC_TXN_ERR_INT );
900
+
901
+ return interrupt_type ;
902
+ }
903
+
904
+ regmap_read (dev -> thc_regmap , THC_M_PRT_ERR_CAUSE_OFFSET , & err_cause );
905
+ regmap_read (dev -> thc_regmap ,
906
+ THC_M_PRT_READ_DMA_INT_STS_2_OFFSET , & read_sts_2 );
907
+
908
+ if (err_cause & THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR ||
909
+ read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_STALL_STS ||
910
+ read_sts_2 & THC_M_PRT_READ_DMA_INT_STS_STALL_STS ) {
911
+ dev_err (dev -> dev , "Buffer overrun or RxDMA engine stalled!\n" );
912
+ thc_print_txn_error_cause (dev );
913
+
914
+ regmap_write (dev -> thc_regmap , THC_M_PRT_READ_DMA_INT_STS_2_OFFSET ,
915
+ THC_M_PRT_READ_DMA_INT_STS_STALL_STS );
916
+ regmap_write (dev -> thc_regmap , THC_M_PRT_READ_DMA_INT_STS_1_OFFSET ,
917
+ THC_M_PRT_READ_DMA_INT_STS_STALL_STS );
918
+ regmap_write (dev -> thc_regmap , THC_M_PRT_ERR_CAUSE_OFFSET ,
919
+ THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR );
920
+
921
+ interrupt_type |= BIT (THC_TXN_ERR_INT );
922
+
923
+ return interrupt_type ;
924
+ }
925
+
926
+ if (int_sts & THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS ) {
927
+ dev_err_once (dev -> dev , "THC FATAL error, int_sts: 0x%08X\n" , int_sts );
928
+
929
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
930
+ TXN_FATAL_INT_STS_BIT );
931
+
932
+ interrupt_type |= BIT (THC_FATAL_ERR_INT );
933
+
934
+ return interrupt_type ;
935
+ }
936
+
937
+ regmap_read (dev -> thc_regmap ,
938
+ THC_M_PRT_SW_SEQ_CNTRL_OFFSET , & seq_cntrl );
939
+ regmap_read (dev -> thc_regmap ,
940
+ THC_M_PRT_SW_SEQ_STS_OFFSET , & seq_sts );
941
+
942
+ if (seq_cntrl & THC_M_PRT_SW_SEQ_CNTRL_THC_SS_CD_IE &&
943
+ seq_sts & THC_M_PRT_SW_SEQ_STS_TSSDONE ) {
944
+ dev_dbg (dev -> dev , "THC_SS_CD_IE and TSSDONE are set\n" );
945
+ interrupt_type |= BIT (THC_PIO_DONE_INT );
946
+ }
947
+
948
+ if (read_sts_1 & THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS ) {
949
+ dev_dbg (dev -> dev , "Got RxDMA1 Read Interrupt\n" );
950
+
951
+ regmap_write (dev -> thc_regmap ,
952
+ THC_M_PRT_READ_DMA_INT_STS_1_OFFSET , read_sts_1 );
953
+
954
+ interrupt_type |= BIT (THC_RXDMA1_INT );
955
+ }
956
+
957
+ if (read_sts_2 & THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS ) {
958
+ dev_dbg (dev -> dev , "Got RxDMA2 Read Interrupt\n" );
959
+
960
+ regmap_write (dev -> thc_regmap ,
961
+ THC_M_PRT_READ_DMA_INT_STS_2_OFFSET , read_sts_2 );
962
+
963
+ interrupt_type |= BIT (THC_RXDMA2_INT );
964
+ }
965
+
966
+ regmap_read (dev -> thc_regmap ,
967
+ THC_M_PRT_READ_DMA_INT_STS_SW_OFFSET , & read_sts_sw );
968
+
969
+ if (read_sts_sw & THC_M_PRT_READ_DMA_INT_STS_DMACPL_STS ) {
970
+ dev_dbg (dev -> dev , "Got SwDMA Read Interrupt\n" );
971
+
972
+ regmap_write (dev -> thc_regmap ,
973
+ THC_M_PRT_READ_DMA_INT_STS_SW_OFFSET , read_sts_sw );
974
+
975
+ dev -> swdma_done = true;
976
+ wake_up_interruptible (& dev -> swdma_complete_wait );
977
+
978
+ interrupt_type |= BIT (THC_SWDMA_INT );
979
+ }
980
+
981
+ regmap_read (dev -> thc_regmap ,
982
+ THC_M_PRT_WRITE_INT_STS_OFFSET , & write_sts );
983
+
984
+ if (write_sts & THC_M_PRT_WRITE_INT_STS_THC_WRDMA_CMPL_STATUS ) {
985
+ dev_dbg (dev -> dev , "Got TxDMA Write complete Interrupt\n" );
986
+
987
+ regmap_write (dev -> thc_regmap ,
988
+ THC_M_PRT_WRITE_INT_STS_OFFSET , write_sts );
989
+
990
+ dev -> write_done = true;
991
+ wake_up_interruptible (& dev -> write_complete_wait );
992
+
993
+ interrupt_type |= BIT (THC_TXDMA_INT );
994
+ }
995
+
996
+ if (int_sts & THC_M_PRT_INT_STATUS_DEV_RAW_INT_STS ) {
997
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
998
+ THC_M_PRT_INT_STATUS_DEV_RAW_INT_STS );
999
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1000
+ }
1001
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_UNDER_INT_STS ) {
1002
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1003
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_UNDER_INT_STS );
1004
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1005
+ }
1006
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_OVER_INT_STS ) {
1007
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1008
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_OVER_INT_STS );
1009
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1010
+ }
1011
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_FULL_INT_STS ) {
1012
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1013
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_RX_FULL_INT_STS );
1014
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1015
+ }
1016
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_OVER_INT_STS ) {
1017
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1018
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_OVER_INT_STS );
1019
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1020
+ }
1021
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_EMPTY_INT_STS ) {
1022
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1023
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_EMPTY_INT_STS );
1024
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1025
+ }
1026
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_ABRT_INT_STS ) {
1027
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1028
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_TX_ABRT_INT_STS );
1029
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1030
+ }
1031
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_ACTIVITY_INT_STS ) {
1032
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1033
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_ACTIVITY_INT_STS );
1034
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1035
+ }
1036
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_SCL_STUCK_AT_LOW_INT_STS ) {
1037
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1038
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_SCL_STUCK_AT_LOW_INT_STS );
1039
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1040
+ }
1041
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_STOP_DET_INT_STS ) {
1042
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1043
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_STOP_DET_INT_STS );
1044
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1045
+ }
1046
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_START_DET_INT_STS ) {
1047
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1048
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_START_DET_INT_STS );
1049
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1050
+ }
1051
+ if (int_sts & THC_M_PRT_INT_STATUS_THC_I2C_IC_MST_ON_HOLD_INT_STS ) {
1052
+ regmap_write (dev -> thc_regmap , THC_M_PRT_INT_STATUS_OFFSET ,
1053
+ THC_M_PRT_INT_STATUS_THC_I2C_IC_MST_ON_HOLD_INT_STS );
1054
+ interrupt_type |= BIT (THC_I2CSUBIP_INT );
1055
+ }
1056
+
1057
+ if (!interrupt_type )
1058
+ interrupt_type |= BIT (THC_UNKNOWN_INT );
1059
+
1060
+ return interrupt_type ;
1061
+ }
1062
+ EXPORT_SYMBOL_NS_GPL (thc_interrupt_handler , "INTEL_THC" );
1063
+
805
1064
MODULE_AUTHOR (
"Xinpeng Sun <[email protected] >" );
806
1065
MODULE_AUTHOR (
"Even Xu <[email protected] >" );
807
1066
0 commit comments