16
16
#include <linux/init.h>
17
17
#include <linux/interrupt.h>
18
18
#include <linux/io.h>
19
+ #include <linux/iopoll.h>
19
20
#include <linux/kernel.h>
20
21
#include <linux/module.h>
21
22
#include <linux/of.h>
@@ -187,6 +188,10 @@ struct lpi2c_imx_struct {
187
188
struct i2c_client * target ;
188
189
};
189
190
191
+ #define lpi2c_imx_read_msr_poll_timeout (val , cond ) \
192
+ readl_poll_timeout(lpi2c_imx->base + LPI2C_MSR, val, cond, \
193
+ 0, 500000)
194
+
190
195
static void lpi2c_imx_intctrl (struct lpi2c_imx_struct * lpi2c_imx ,
191
196
unsigned int enable )
192
197
{
@@ -195,33 +200,34 @@ static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,
195
200
196
201
static int lpi2c_imx_bus_busy (struct lpi2c_imx_struct * lpi2c_imx )
197
202
{
198
- unsigned long orig_jiffies = jiffies ;
199
203
unsigned int temp ;
204
+ int err ;
200
205
201
- while (1 ) {
202
- temp = readl (lpi2c_imx -> base + LPI2C_MSR );
203
-
204
- /* check for arbitration lost, clear if set */
205
- if (temp & MSR_ALF ) {
206
- writel (temp , lpi2c_imx -> base + LPI2C_MSR );
207
- return - EAGAIN ;
208
- }
206
+ err = lpi2c_imx_read_msr_poll_timeout (temp ,
207
+ temp & (MSR_ALF | MSR_BBF | MSR_MBF ));
209
208
210
- if (temp & (MSR_BBF | MSR_MBF ))
211
- break ;
209
+ /* check for arbitration lost, clear if set */
210
+ if (temp & MSR_ALF ) {
211
+ writel (temp , lpi2c_imx -> base + LPI2C_MSR );
212
+ return - EAGAIN ;
213
+ }
212
214
213
- if (time_after (jiffies , orig_jiffies + msecs_to_jiffies (500 ))) {
214
- dev_dbg (& lpi2c_imx -> adapter .dev , "bus not work\n" );
215
- if (lpi2c_imx -> adapter .bus_recovery_info )
216
- i2c_recover_bus (& lpi2c_imx -> adapter );
217
- return - ETIMEDOUT ;
218
- }
219
- schedule ();
215
+ /* check for bus not busy */
216
+ if (err ) {
217
+ dev_dbg (& lpi2c_imx -> adapter .dev , "bus not work\n" );
218
+ if (lpi2c_imx -> adapter .bus_recovery_info )
219
+ i2c_recover_bus (& lpi2c_imx -> adapter );
220
+ return - ETIMEDOUT ;
220
221
}
221
222
222
223
return 0 ;
223
224
}
224
225
226
+ static u32 lpi2c_imx_txfifo_cnt (struct lpi2c_imx_struct * lpi2c_imx )
227
+ {
228
+ return readl (lpi2c_imx -> base + LPI2C_MFSR ) & 0xff ;
229
+ }
230
+
225
231
static void lpi2c_imx_set_mode (struct lpi2c_imx_struct * lpi2c_imx )
226
232
{
227
233
unsigned int bitrate = lpi2c_imx -> bitrate ;
@@ -259,25 +265,18 @@ static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx,
259
265
260
266
static void lpi2c_imx_stop (struct lpi2c_imx_struct * lpi2c_imx )
261
267
{
262
- unsigned long orig_jiffies = jiffies ;
263
268
unsigned int temp ;
269
+ int err ;
264
270
265
271
writel (GEN_STOP << 8 , lpi2c_imx -> base + LPI2C_MTDR );
266
272
267
- do {
268
- temp = readl (lpi2c_imx -> base + LPI2C_MSR );
269
- if (temp & MSR_SDF )
270
- break ;
273
+ err = lpi2c_imx_read_msr_poll_timeout (temp , temp & MSR_SDF );
271
274
272
- if (time_after (jiffies , orig_jiffies + msecs_to_jiffies (500 ))) {
273
- dev_dbg (& lpi2c_imx -> adapter .dev , "stop timeout\n" );
274
- if (lpi2c_imx -> adapter .bus_recovery_info )
275
- i2c_recover_bus (& lpi2c_imx -> adapter );
276
- break ;
277
- }
278
- schedule ();
279
-
280
- } while (1 );
275
+ if (err ) {
276
+ dev_dbg (& lpi2c_imx -> adapter .dev , "stop timeout\n" );
277
+ if (lpi2c_imx -> adapter .bus_recovery_info )
278
+ i2c_recover_bus (& lpi2c_imx -> adapter );
279
+ }
281
280
}
282
281
283
282
/* CLKLO = I2C_CLK_RATIO * CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2 */
@@ -393,26 +392,23 @@ static int lpi2c_imx_pio_msg_complete(struct lpi2c_imx_struct *lpi2c_imx)
393
392
394
393
static int lpi2c_imx_txfifo_empty (struct lpi2c_imx_struct * lpi2c_imx )
395
394
{
396
- unsigned long orig_jiffies = jiffies ;
397
- u32 txcnt ;
398
-
399
- do {
400
- txcnt = readl (lpi2c_imx -> base + LPI2C_MFSR ) & 0xff ;
395
+ unsigned int temp ;
396
+ int err ;
401
397
402
- if (readl (lpi2c_imx -> base + LPI2C_MSR ) & MSR_NDF ) {
403
- dev_dbg (& lpi2c_imx -> adapter .dev , "NDF detected\n" );
404
- return - EIO ;
405
- }
398
+ err = lpi2c_imx_read_msr_poll_timeout (temp ,
399
+ (temp & MSR_NDF ) || !lpi2c_imx_txfifo_cnt (lpi2c_imx ));
406
400
407
- if (time_after (jiffies , orig_jiffies + msecs_to_jiffies (500 ))) {
408
- dev_dbg (& lpi2c_imx -> adapter .dev , "txfifo empty timeout\n" );
409
- if (lpi2c_imx -> adapter .bus_recovery_info )
410
- i2c_recover_bus (& lpi2c_imx -> adapter );
411
- return - ETIMEDOUT ;
412
- }
413
- schedule ();
401
+ if (temp & MSR_NDF ) {
402
+ dev_dbg (& lpi2c_imx -> adapter .dev , "NDF detected\n" );
403
+ return - EIO ;
404
+ }
414
405
415
- } while (txcnt );
406
+ if (err ) {
407
+ dev_dbg (& lpi2c_imx -> adapter .dev , "txfifo empty timeout\n" );
408
+ if (lpi2c_imx -> adapter .bus_recovery_info )
409
+ i2c_recover_bus (& lpi2c_imx -> adapter );
410
+ return - ETIMEDOUT ;
411
+ }
416
412
417
413
return 0 ;
418
414
}
0 commit comments