Message ID | 20201214045850.1026293-1-zhang.lyra@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v2] i2c: sprd: use a specific timeout to avoid system hang up issue | expand |
On Mon, Dec 14, 2020 at 12:58:50PM +0800, Chunyan Zhang wrote: > From: Chunyan Zhang <chunyan.zhang@unisoc.com> > > If the i2c device SCL bus being pulled up due to some exception before > message transfer done, the system cannot receive the completing interrupt > signal any more, it would not exit waiting loop until MAX_SCHEDULE_TIMEOUT > jiffies eclipse, that would make the system seemed hang up. To avoid that > happen, this patch adds a specific timeout for message transfer. > > Fixes: 8b9ec0719834 ("i2c: Add Spreadtrum I2C controller driver") > Signed-off-by: Linhua Xu <linhua.xu@unisoc.com> > Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com> Took the liberty to change the errno to ETIMEDOUT and applied to for-current, thanks!
On Tue, 5 Jan 2021 at 02:24, Wolfram Sang <wsa@kernel.org> wrote: > > On Mon, Dec 14, 2020 at 12:58:50PM +0800, Chunyan Zhang wrote: > > From: Chunyan Zhang <chunyan.zhang@unisoc.com> > > > > If the i2c device SCL bus being pulled up due to some exception before > > message transfer done, the system cannot receive the completing interrupt > > signal any more, it would not exit waiting loop until MAX_SCHEDULE_TIMEOUT > > jiffies eclipse, that would make the system seemed hang up. To avoid that > > happen, this patch adds a specific timeout for message transfer. > > > > Fixes: 8b9ec0719834 ("i2c: Add Spreadtrum I2C controller driver") > > Signed-off-by: Linhua Xu <linhua.xu@unisoc.com> > > Signed-off-by: Chunyan Zhang <chunyan.zhang@unisoc.com> > > Took the liberty to change the errno to ETIMEDOUT and applied to > for-current, thanks! Thanks! Chunyan >
diff --git a/drivers/i2c/busses/i2c-sprd.c b/drivers/i2c/busses/i2c-sprd.c index 19cda6742423..b9f58a4b2281 100644 --- a/drivers/i2c/busses/i2c-sprd.c +++ b/drivers/i2c/busses/i2c-sprd.c @@ -72,6 +72,8 @@ /* timeout (ms) for pm runtime autosuspend */ #define SPRD_I2C_PM_TIMEOUT 1000 +/* timeout (ms) for transfer message */ +#define I2C_XFER_TIMEOUT 1000 /* SPRD i2c data structure */ struct sprd_i2c { @@ -244,6 +246,7 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg *msg, bool is_last_msg) { struct sprd_i2c *i2c_dev = i2c_adap->algo_data; + unsigned long time_left; i2c_dev->msg = msg; i2c_dev->buf = msg->buf; @@ -273,7 +276,10 @@ static int sprd_i2c_handle_msg(struct i2c_adapter *i2c_adap, sprd_i2c_opt_start(i2c_dev); - wait_for_completion(&i2c_dev->complete); + time_left = wait_for_completion_timeout(&i2c_dev->complete, + msecs_to_jiffies(I2C_XFER_TIMEOUT)); + if (!time_left) + return -EIO; return i2c_dev->err; }