|
@@ -482,7 +482,8 @@ static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
|
|
|
static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
|
|
|
struct i2c_msg *msgs, int num)
|
|
|
{
|
|
|
- unsigned long timeout;
|
|
|
+ unsigned long iicstat, timeout;
|
|
|
+ int spins = 20;
|
|
|
int ret;
|
|
|
|
|
|
if (i2c->suspended)
|
|
@@ -521,7 +522,21 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
|
|
|
|
|
|
/* ensure the stop has been through the bus */
|
|
|
|
|
|
- msleep(1);
|
|
|
+ dev_dbg(i2c->dev, "waiting for bus idle\n");
|
|
|
+
|
|
|
+ /* first, try busy waiting briefly */
|
|
|
+ do {
|
|
|
+ iicstat = readl(i2c->regs + S3C2410_IICSTAT);
|
|
|
+ } while ((iicstat & S3C2410_IICSTAT_START) && --spins);
|
|
|
+
|
|
|
+ /* if that timed out sleep */
|
|
|
+ if (!spins) {
|
|
|
+ msleep(1);
|
|
|
+ iicstat = readl(i2c->regs + S3C2410_IICSTAT);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iicstat & S3C2410_IICSTAT_START)
|
|
|
+ dev_warn(i2c->dev, "timeout waiting for bus idle\n");
|
|
|
|
|
|
out:
|
|
|
return ret;
|