9191 DW_IC_INTR_TX_ABRT | \
9292 DW_IC_INTR_STOP_DET)
9393
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
9795
9896#define DW_IC_SDA_HOLD_RX_SHIFT 16
9997#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)
478476{
479477 struct i2c_msg * msgs = dev -> msgs ;
480478 u32 ic_tar = 0 ;
481- bool enabled ;
482479
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);
500482
501483 /* if the slave address is ten bit address, enable 10BITADDR */
502484 if (dev -> dynamic_tar_update_enabled ) {
@@ -526,8 +508,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
526508 /* enforce disabled interrupts (due to HW issues) */
527509 i2c_dw_disable_int (dev );
528510
529- if (! enabled )
530- __i2c_dw_enable (dev , true);
511+ /* Enable the adapter */
512+ __i2c_dw_enable (dev , true);
531513
532514 /* Clear and enable interrupts */
533515 dw_readl (dev , DW_IC_CLR_INTR );
@@ -611,7 +593,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
611593 if (msgs [dev -> msg_write_idx ].flags & I2C_M_RD ) {
612594
613595 /* avoid rx buffer overrun */
614- if (rx_limit - dev -> rx_outstanding <= 0 )
596+ if (dev -> rx_outstanding >= dev -> rx_fifo_depth )
615597 break ;
616598
617599 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)
708690}
709691
710692/*
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
713694 */
714695static int
715696i2c_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)
752733 goto done ;
753734 }
754735
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+
755746 if (dev -> msg_err ) {
756747 ret = dev -> msg_err ;
757748 goto done ;
758749 }
759750
760751 /* no error */
761- if (likely (!dev -> cmd_err )) {
752+ if (likely (!dev -> cmd_err && ! dev -> status )) {
762753 ret = num ;
763754 goto done ;
764755 }
@@ -768,6 +759,11 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
768759 ret = i2c_dw_handle_tx_abort (dev );
769760 goto done ;
770761 }
762+
763+ if (dev -> status )
764+ dev_err (dev -> dev ,
765+ "transfer terminated early - interrupt latency too high?\n" );
766+
771767 ret = - EIO ;
772768
773769done :
@@ -888,19 +884,9 @@ static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
888884 */
889885
890886tx_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 )
902888 complete (& dev -> cmd_complete );
903- } else if (unlikely (dev -> accessor_flags & ACCESS_INTR_MASK )) {
889+ else if (unlikely (dev -> accessor_flags & ACCESS_INTR_MASK )) {
904890 /* workaround to trigger pending interrupt */
905891 stat = dw_readl (dev , DW_IC_INTR_MASK );
906892 i2c_dw_disable_int (dev );
0 commit comments