91
91
DW_IC_INTR_TX_ABRT | \
92
92
DW_IC_INTR_STOP_DET)
93
93
94
- #define DW_IC_STATUS_ACTIVITY 0x1
95
- #define DW_IC_STATUS_TFE BIT(2)
96
- #define DW_IC_STATUS_MST_ACTIVITY BIT(5)
94
+ #define DW_IC_STATUS_ACTIVITY 0x1
97
95
98
96
#define DW_IC_SDA_HOLD_RX_SHIFT 16
99
97
#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, DW_IC_SDA_HOLD_RX_SHIFT)
@@ -478,25 +476,9 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
478
476
{
479
477
struct i2c_msg * msgs = dev -> msgs ;
480
478
u32 ic_tar = 0 ;
481
- bool enabled ;
482
479
483
- enabled = dw_readl (dev , DW_IC_ENABLE_STATUS ) & 1 ;
484
-
485
- if (enabled ) {
486
- u32 ic_status ;
487
-
488
- /*
489
- * Only disable adapter if ic_tar and ic_con can't be
490
- * dynamically updated
491
- */
492
- ic_status = dw_readl (dev , DW_IC_STATUS );
493
- if (!dev -> dynamic_tar_update_enabled ||
494
- (ic_status & DW_IC_STATUS_MST_ACTIVITY ) ||
495
- !(ic_status & DW_IC_STATUS_TFE )) {
496
- __i2c_dw_enable_and_wait (dev , false);
497
- enabled = false;
498
- }
499
- }
480
+ /* Disable the adapter */
481
+ __i2c_dw_enable_and_wait (dev , false);
500
482
501
483
/* if the slave address is ten bit address, enable 10BITADDR */
502
484
if (dev -> dynamic_tar_update_enabled ) {
@@ -526,8 +508,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
526
508
/* enforce disabled interrupts (due to HW issues) */
527
509
i2c_dw_disable_int (dev );
528
510
529
- if (! enabled )
530
- __i2c_dw_enable (dev , true);
511
+ /* Enable the adapter */
512
+ __i2c_dw_enable (dev , true);
531
513
532
514
/* Clear and enable interrupts */
533
515
dw_readl (dev , DW_IC_CLR_INTR );
@@ -611,7 +593,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
611
593
if (msgs [dev -> msg_write_idx ].flags & I2C_M_RD ) {
612
594
613
595
/* avoid rx buffer overrun */
614
- if (rx_limit - dev -> rx_outstanding <= 0 )
596
+ if (dev -> rx_outstanding >= dev -> rx_fifo_depth )
615
597
break ;
616
598
617
599
dw_writel (dev , cmd | 0x100 , DW_IC_DATA_CMD );
@@ -708,8 +690,7 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
708
690
}
709
691
710
692
/*
711
- * Prepare controller for a transaction and start transfer by calling
712
- * i2c_dw_xfer_init()
693
+ * Prepare controller for a transaction and call i2c_dw_xfer_msg
713
694
*/
714
695
static int
715
696
i2c_dw_xfer (struct i2c_adapter * adap , struct i2c_msg msgs [], int num )
@@ -752,13 +733,23 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
752
733
goto done ;
753
734
}
754
735
736
+ /*
737
+ * We must disable the adapter before returning and signaling the end
738
+ * of the current transfer. Otherwise the hardware might continue
739
+ * generating interrupts which in turn causes a race condition with
740
+ * the following transfer. Needs some more investigation if the
741
+ * additional interrupts are a hardware bug or this driver doesn't
742
+ * handle them correctly yet.
743
+ */
744
+ __i2c_dw_enable (dev , false);
745
+
755
746
if (dev -> msg_err ) {
756
747
ret = dev -> msg_err ;
757
748
goto done ;
758
749
}
759
750
760
751
/* no error */
761
- if (likely (!dev -> cmd_err )) {
752
+ if (likely (!dev -> cmd_err && ! dev -> status )) {
762
753
ret = num ;
763
754
goto done ;
764
755
}
@@ -768,6 +759,11 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
768
759
ret = i2c_dw_handle_tx_abort (dev );
769
760
goto done ;
770
761
}
762
+
763
+ if (dev -> status )
764
+ dev_err (dev -> dev ,
765
+ "transfer terminated early - interrupt latency too high?\n" );
766
+
771
767
ret = - EIO ;
772
768
773
769
done :
@@ -888,19 +884,9 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
888
884
*/
889
885
890
886
tx_aborted :
891
- if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET ))
892
- || dev -> msg_err ) {
893
- /*
894
- * We must disable interruts before returning and signaling
895
- * the end of the current transfer. Otherwise the hardware
896
- * might continue generating interrupts for non-existent
897
- * transfers.
898
- */
899
- i2c_dw_disable_int (dev );
900
- dw_readl (dev , DW_IC_CLR_INTR );
901
-
887
+ if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET )) || dev -> msg_err )
902
888
complete (& dev -> cmd_complete );
903
- } else if (unlikely (dev -> accessor_flags & ACCESS_INTR_MASK )) {
889
+ else if (unlikely (dev -> accessor_flags & ACCESS_INTR_MASK )) {
904
890
/* workaround to trigger pending interrupt */
905
891
stat = dw_readl (dev , DW_IC_INTR_MASK );
906
892
i2c_dw_disable_int (dev );
0 commit comments