>-----Original Message----- >From: Wolfram Sang [mailto:w.sang@xxxxxxxxxxxxxx] >Sent: Tuesday, June 12, 2012 12:31 AM >To: Zhang, Sonic >Cc: Ben Dooks; linux-i2c@xxxxxxxxxxxxxxx; LKML; uclinux-dist- >devel@xxxxxxxxxxxxxxxxxxxx >Subject: Re: [PATCH 3/8] i2c: i2c-bfin-twi: Break dead waiting loop if i2c device >misbehaves. > >On Wed, May 16, 2012 at 03:20:21PM +0800, sonic.zhang@xxxxxxxxxx wrote: >> From: Sonic Zhang <sonic.zhang@xxxxxxxxxx> >> >> Some fault i2c device may hold the sda/scl line and cause i2c driver >> wait in the BUS busy loop. This patch breaks this potential dead loop. >> >> Signed-off-by: Sonic Zhang <sonic.zhang@xxxxxxxxxx> >> >> git-svn-id: svn://localhost/svn/linux-kernel/trunk@9291 >> 526b6c2d-f592-4532-a319-5dd88ccb003d > >^ > >> --- >> drivers/i2c/busses/i2c-bfin-twi.c | 14 ++++++++++++-- >> 1 files changed, 12 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/i2c/busses/i2c-bfin-twi.c >> b/drivers/i2c/busses/i2c-bfin-twi.c >> index 376e331..4abaf59 100644 >> --- a/drivers/i2c/busses/i2c-bfin-twi.c >> +++ b/drivers/i2c/busses/i2c-bfin-twi.c >> @@ -294,6 +294,8 @@ static irqreturn_t bfin_twi_interrupt_entry(int irq, void >*dev_id) >> return IRQ_HANDLED; >> } >> >> +#define BFIN_TWI_BUSY_TIMEOUT 1000 >> + > >Please use a unit like microseconds for the timeout. > Take a look at the I2C framework code again. I find this loop to poll BUSBUSY bit is not necessary. Just return -EAGAIN, the framework do retry before timeout already. Regards, Sonic >> /* >> * One i2c master transfer >> */ >> @@ -303,12 +305,16 @@ static int bfin_twi_do_master_xfer(struct i2c_adapter >*adap, >> struct bfin_twi_iface *iface = adap->algo_data; >> struct i2c_msg *pmsg; >> int rc = 0; >> + unsigned int busy_timeout = BFIN_TWI_BUSY_TIMEOUT; >> >> if (!(read_CONTROL(iface) & TWI_ENA)) >> return -ENXIO; >> >> - while (read_MASTER_STAT(iface) & BUSBUSY) >> + while (read_MASTER_STAT(iface) & BUSBUSY) { >> + if (--busy_timeout == 0) >> + return -EBUSY; >> yield(); >> + } >> >> iface->pmsg = msgs; >> iface->msg_num = num; >> @@ -403,12 +409,16 @@ int bfin_twi_do_smbus_xfer(struct i2c_adapter >> *adap, u16 addr, { >> struct bfin_twi_iface *iface = adap->algo_data; >> int rc = 0; >> + unsigned int busy_timeout = BFIN_TWI_BUSY_TIMEOUT; >> >> if (!(read_CONTROL(iface) & TWI_ENA)) >> return -ENXIO; >> >> - while (read_MASTER_STAT(iface) & BUSBUSY) >> + while (read_MASTER_STAT(iface) & BUSBUSY) { >> + if (--busy_timeout == 0) >> + return -EBUSY; >> yield(); >> + } >> >> iface->writeNum = 0; >> iface->readNum = 0; >> -- >> 1.7.0.4 >> >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-i2c" >> in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo >> info at http://vger.kernel.org/majordomo-info.html > >-- >Pengutronix e.K. | Wolfram Sang | >Industrial Linux Solutions | http://www.pengutronix.de/ | -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html