2121/* Register offsets */
2222#define REG_MTXFIFO 0x00
2323#define REG_MRXFIFO 0x04
24+ #define REG_XFSTA 0x0c
2425#define REG_SMSTA 0x14
2526#define REG_IMASK 0x18
2627#define REG_CTL 0x1c
5253#define CTL_UJM BIT(8)
5354#define CTL_CLK_M GENMASK(7, 0)
5455
56+ #define TRANSFER_TIMEOUT_MS 100
57+
5558static inline void reg_write (struct pasemi_smbus * smbus , int reg , int val )
5659{
5760 dev_dbg (smbus -> dev , "smbus write reg %x val %08x\n" , reg , val );
@@ -80,23 +83,51 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
8083 reinit_completion (& smbus -> irq_completion );
8184}
8285
83- static void pasemi_smb_clear (struct pasemi_smbus * smbus )
86+ static int pasemi_smb_clear (struct pasemi_smbus * smbus )
8487{
85- unsigned int status ;
88+ unsigned int status , xfstatus ;
89+ int timeout = TRANSFER_TIMEOUT_MS ;
8690
8791 status = reg_read (smbus , REG_SMSTA );
92+
93+ /* First wait for the bus to go idle */
94+ while ((status & (SMSTA_XIP | SMSTA_JAM )) && timeout -- ) {
95+ msleep (1 );
96+ status = reg_read (smbus , REG_SMSTA );
97+ }
98+
99+ xfstatus = reg_read (smbus , REG_XFSTA );
100+
101+ if (timeout < 0 ) {
102+ dev_warn (smbus -> dev , "Bus is still stuck (status 0x%08x xfstatus 0x%08x)\n" ,
103+ status , xfstatus );
104+ return - EIO ;
105+ }
106+
107+ /* If any badness happened or there is data in the FIFOs, reset the FIFOs */
108+ if ((status & (SMSTA_MRNE | SMSTA_JMD | SMSTA_MTO | SMSTA_TOM | SMSTA_MTN | SMSTA_MTA )) ||
109+ !(status & SMSTA_MTE )) {
110+ dev_warn (smbus -> dev , "Issuing reset due to status 0x%08x (xfstatus 0x%08x)\n" ,
111+ status , xfstatus );
112+ pasemi_reset (smbus );
113+ }
114+
115+ /* Clear the flags */
88116 reg_write (smbus , REG_SMSTA , status );
117+
118+ return 0 ;
89119}
90120
91121static int pasemi_smb_waitready (struct pasemi_smbus * smbus )
92122{
93- int timeout = 100 ;
123+ int timeout = TRANSFER_TIMEOUT_MS ;
94124 unsigned int status ;
95125
96126 if (smbus -> use_irq ) {
97127 reinit_completion (& smbus -> irq_completion );
98- reg_write (smbus , REG_IMASK , SMSTA_XEN | SMSTA_MTN );
99- wait_for_completion_timeout (& smbus -> irq_completion , msecs_to_jiffies (100 ));
128+ /* XEN should be set when a transaction terminates, whether due to error or not */
129+ reg_write (smbus , REG_IMASK , SMSTA_XEN );
130+ wait_for_completion_timeout (& smbus -> irq_completion , msecs_to_jiffies (timeout ));
100131 reg_write (smbus , REG_IMASK , 0 );
101132 status = reg_read (smbus , REG_SMSTA );
102133 } else {
@@ -107,16 +138,32 @@ static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
107138 }
108139 }
109140
110- /* Got NACK? */
111- if (status & SMSTA_MTN )
112- return - ENXIO ;
141+ /* Controller timeout? */
142+ if (status & SMSTA_TOM ) {
143+ dev_warn (smbus -> dev , "Controller timeout, status 0x%08x\n" , status );
144+ return - EIO ;
145+ }
113146
114- if ( timeout < 0 ) {
115- dev_warn ( smbus -> dev , "Timeout, status 0x%08x\n" , status );
116- reg_write (smbus , REG_SMSTA , status );
147+ /* Peripheral timeout? */
148+ if ( status & SMSTA_MTO ) {
149+ dev_warn (smbus -> dev , "Peripheral timeout, status 0x%08x\n" , status );
117150 return - ETIME ;
118151 }
119152
153+ /* Still stuck in a transaction? */
154+ if (status & SMSTA_XIP ) {
155+ dev_warn (smbus -> dev , "Bus stuck, status 0x%08x\n" , status );
156+ return - EIO ;
157+ }
158+
159+ /* Arbitration loss? */
160+ if (status & SMSTA_MTA )
161+ return - EBUSY ;
162+
163+ /* Got NACK? */
164+ if (status & SMSTA_MTN )
165+ return - ENXIO ;
166+
120167 /* Clear XEN */
121168 reg_write (smbus , REG_SMSTA , SMSTA_XEN );
122169
@@ -177,7 +224,8 @@ static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
177224 struct pasemi_smbus * smbus = adapter -> algo_data ;
178225 int ret , i ;
179226
180- pasemi_smb_clear (smbus );
227+ if (pasemi_smb_clear (smbus ))
228+ return - EIO ;
181229
182230 ret = 0 ;
183231
@@ -200,7 +248,8 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
200248 addr <<= 1 ;
201249 read_flag = read_write == I2C_SMBUS_READ ;
202250
203- pasemi_smb_clear (smbus );
251+ if (pasemi_smb_clear (smbus ))
252+ return - EIO ;
204253
205254 switch (size ) {
206255 case I2C_SMBUS_QUICK :
0 commit comments