@@ -87,12 +87,31 @@ static void pasemi_reset(struct pasemi_smbus *smbus)
87
87
reinit_completion (& smbus -> irq_completion );
88
88
}
89
89
90
- static void pasemi_smb_clear (struct pasemi_smbus * smbus )
90
+ static int pasemi_smb_clear (struct pasemi_smbus * smbus )
91
91
{
92
92
unsigned int status ;
93
+ int ret ;
94
+
95
+ /* First wait for the bus to go idle */
96
+ ret = readx_poll_timeout (ioread32 , smbus -> ioaddr + REG_SMSTA ,
97
+ status , !(status & (SMSTA_XIP | SMSTA_JAM )),
98
+ USEC_PER_MSEC ,
99
+ USEC_PER_MSEC * PASEMI_TRANSFER_TIMEOUT_MS );
100
+
101
+ if (ret < 0 ) {
102
+ dev_err (smbus -> dev , "Bus is still stuck (status 0x%08x)\n" , status );
103
+ return - EIO ;
104
+ }
105
+
106
+ /* If any badness happened or there is data in the FIFOs, reset the FIFOs */
107
+ if ((status & (SMSTA_MRNE | SMSTA_JMD | SMSTA_MTO | SMSTA_TOM | SMSTA_MTN | SMSTA_MTA )) ||
108
+ !(status & SMSTA_MTE ))
109
+ pasemi_reset (smbus );
93
110
94
- status = reg_read ( smbus , REG_SMSTA );
111
+ /* Clear the flags */
95
112
reg_write (smbus , REG_SMSTA , status );
113
+
114
+ return 0 ;
96
115
}
97
116
98
117
static int pasemi_smb_waitready (struct pasemi_smbus * smbus )
@@ -130,9 +149,35 @@ static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
130
149
}
131
150
}
132
151
152
+ /* Controller timeout? */
153
+ if (status & SMSTA_TOM ) {
154
+ dev_err (smbus -> dev , "Controller timeout, status 0x%08x\n" , status );
155
+ return - EIO ;
156
+ }
157
+
158
+ /* Peripheral timeout? */
159
+ if (status & SMSTA_MTO ) {
160
+ dev_err (smbus -> dev , "Peripheral timeout, status 0x%08x\n" , status );
161
+ return - ETIME ;
162
+ }
163
+
164
+ /* Still stuck in a transaction? */
165
+ if (status & SMSTA_XIP ) {
166
+ dev_err (smbus -> dev , "Bus stuck, status 0x%08x\n" , status );
167
+ return - EIO ;
168
+ }
169
+
170
+ /* Arbitration loss? */
171
+ if (status & SMSTA_MTA ) {
172
+ dev_err (smbus -> dev , "Arbitration loss, status 0x%08x\n" , status );
173
+ return - EBUSY ;
174
+ }
175
+
133
176
/* Got NACK? */
134
- if (status & SMSTA_MTN )
177
+ if (status & SMSTA_MTN ) {
178
+ dev_err (smbus -> dev , "NACK, status 0x%08x\n" , status );
135
179
return - ENXIO ;
180
+ }
136
181
137
182
/* Clear XEN */
138
183
reg_write (smbus , REG_SMSTA , SMSTA_XEN );
@@ -194,9 +239,9 @@ static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
194
239
struct pasemi_smbus * smbus = adapter -> algo_data ;
195
240
int ret , i ;
196
241
197
- pasemi_smb_clear (smbus );
198
-
199
- ret = 0 ;
242
+ ret = pasemi_smb_clear (smbus );
243
+ if ( ret )
244
+ return ret ;
200
245
201
246
for (i = 0 ; i < num && !ret ; i ++ )
202
247
ret = pasemi_i2c_xfer_msg (adapter , & msgs [i ], (i == (num - 1 )));
@@ -217,7 +262,9 @@ static int pasemi_smb_xfer(struct i2c_adapter *adapter,
217
262
addr <<= 1 ;
218
263
read_flag = read_write == I2C_SMBUS_READ ;
219
264
220
- pasemi_smb_clear (smbus );
265
+ err = pasemi_smb_clear (smbus );
266
+ if (err )
267
+ return err ;
221
268
222
269
switch (size ) {
223
270
case I2C_SMBUS_QUICK :
0 commit comments