1616#include <linux/init.h>
1717#include <linux/interrupt.h>
1818#include <linux/io.h>
19+ #include <linux/iopoll.h>
1920#include <linux/kernel.h>
2021#include <linux/module.h>
2122#include <linux/of.h>
@@ -187,6 +188,10 @@ struct lpi2c_imx_struct {
187188 struct i2c_client * target ;
188189};
189190
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+
190195static void lpi2c_imx_intctrl (struct lpi2c_imx_struct * lpi2c_imx ,
191196 unsigned int enable )
192197{
@@ -195,33 +200,34 @@ static void lpi2c_imx_intctrl(struct lpi2c_imx_struct *lpi2c_imx,
195200
196201static int lpi2c_imx_bus_busy (struct lpi2c_imx_struct * lpi2c_imx )
197202{
198- unsigned long orig_jiffies = jiffies ;
199203 unsigned int temp ;
204+ int err ;
200205
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 ));
209208
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+ }
212214
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 ;
220221 }
221222
222223 return 0 ;
223224}
224225
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+
225231static void lpi2c_imx_set_mode (struct lpi2c_imx_struct * lpi2c_imx )
226232{
227233 unsigned int bitrate = lpi2c_imx -> bitrate ;
@@ -259,25 +265,18 @@ static int lpi2c_imx_start(struct lpi2c_imx_struct *lpi2c_imx,
259265
260266static void lpi2c_imx_stop (struct lpi2c_imx_struct * lpi2c_imx )
261267{
262- unsigned long orig_jiffies = jiffies ;
263268 unsigned int temp ;
269+ int err ;
264270
265271 writel (GEN_STOP << 8 , lpi2c_imx -> base + LPI2C_MTDR );
266272
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 );
271274
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+ }
281280}
282281
283282/* 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)
393392
394393static int lpi2c_imx_txfifo_empty (struct lpi2c_imx_struct * lpi2c_imx )
395394{
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 ;
401397
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 ));
406400
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+ }
414405
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+ }
416412
417413 return 0 ;
418414}
0 commit comments