From: wolfgang huang <huangjinhui@xxxxxxxxxxx> bind two or more slave devices to master device. while master device is process reading, dev->msgs used as a buffer to process the read data, while the other device uses i2c_dw_xfer to read/write, this will directly change dev->msgs, causing the first device reading process to crash or other confusion. so we should to check the device status before modifying dev->msgs and others. [ 1244.815334] i2c_dw_isr+0x2c8/0x5e0 [ 1244.819238] __handle_irq_event_percpu+0x5c/0x168 [ 1244.824350] handle_irq_event_percpu+0x1c/0x58 [ 1244.829201] handle_irq_event+0x40/0xa0 [ 1244.833449] handle_fasteoi_irq+0xcc/0x1b0 [ 1244.837956] generic_handle_irq+0x24/0x38 [ 1244.842376] __handle_domain_irq+0x5c/0xb8 [ 1244.846883] gic_handle_irq+0x94/0x1c8 [ 1244.851043] el1_irq+0xb8/0x140 [ 1244.854599] arch_cpu_idle+0x10/0x18 [ 1244.858588] do_idle+0x19c/0x260 [ 1244.862231] cpu_startup_entry+0x20/0x28 Signed-off-by: wolfgang huang <huangjinhui@xxxxxxxxxxx> --- drivers/i2c/busses/i2c-designware-master.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 44a94b225ed8..07f7d5e2d12d 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -557,6 +557,14 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) pm_runtime_get_sync(dev->dev); + ret = i2c_dw_acquire_lock(dev); + if (ret) + goto done_nolock; + + ret = i2c_dw_wait_bus_not_busy(dev); + if (ret) + goto done; + /* * Initiate I2C message transfer when AMD NAVI GPU card is enabled, * As it is polling based transfer mechanism, which does not support @@ -578,14 +586,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev->abort_source = 0; dev->rx_outstanding = 0; - ret = i2c_dw_acquire_lock(dev); - if (ret) - goto done_nolock; - - ret = i2c_dw_wait_bus_not_busy(dev); - if (ret < 0) - goto done; - /* Start the transfers */ i2c_dw_xfer_init(dev); -- 2.25.1