mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
i2c: rk3x: Disable i2c controller after i2c transfer finished
If the slave hold the scl low for a long time, we will send the stop because the i2c transfer is timeout. Then reset the slave, the scl will be released to high by slave, the data hold low, but the controller's state is messy now, need to diable i2c controller, it is better to reset i2c controller, it will go back to normal state. The log like this: [ 117.444700] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x93, state: 2 [ 118.466410] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x00, state: 1 [ 119.486217] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x00, state: 1 or [ 91.733176] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x80, state: 1 [ 103.406776] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x00, state: 2 [ 104.426636] rk3x-i2c ff3d0000.i2c: timeout, ipd: 0x00, state: 2 Change-Id: I53e6e383c849cea22d870f9488c23720e74115df Signed-off-by: David Wu <david.wu@rock-chips.com>
This commit is contained in:
@@ -246,6 +246,13 @@ static inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c)
|
||||
i2c_writel(i2c, REG_INT_ALL, REG_IPD);
|
||||
}
|
||||
|
||||
static inline void rk3x_i2c_disable(struct rk3x_i2c *i2c)
|
||||
{
|
||||
u32 val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
|
||||
|
||||
i2c_writel(i2c, val, REG_CON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a START condition, which triggers a REG_INT_START interrupt.
|
||||
*/
|
||||
@@ -1118,6 +1125,8 @@ static int rk3x_i2c_xfer(struct i2c_adapter *adap,
|
||||
}
|
||||
}
|
||||
|
||||
rk3x_i2c_disable(i2c);
|
||||
|
||||
clk_disable(i2c->pclk);
|
||||
clk_disable(i2c->clk);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user