[PATCH] i2c: designware: Synchronize IRQs when unregistering slave client

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Make sure interrupt handler i2c_dw_irq_handler_slave() has finished
before clearing the the dev->slave pointer in i2c_dw_unreg_slave().

There is possibility for a race if i2c_dw_irq_handler_slave() is running
on another CPU while clearing the dev->slave pointer.

Reported-by: Krzysztof Adamski <krzysztof.adamski@xxxxxxxxx>
Reported-by: Wolfram Sang <wsa@xxxxxxxxxxxxx>
Signed-off-by: Jarkko Nikula <jarkko.nikula@xxxxxxxxxxxxxxx>
---
I tried testing simultaneous slave registration/unregistration while
accessing that slave from another I2C master with scripts below but
didn't see issue without or with this patch. But my testing time was
rather short and the race can be hard to hit while possible.

cd /sys/bus/i2c/devices/i2c-[slave port number]/;
while :; do echo slave-24c02 0x1065 >new_device; sleep 1; echo 0x1065 >delete_device; sleep 0.1; done
while :; do i2cdump -y [master port that is connected to slave] 0x65; done
---
 drivers/i2c/busses/i2c-designware-slave.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c
index e7f9305b2dd9..f5f001738df5 100644
--- a/drivers/i2c/busses/i2c-designware-slave.c
+++ b/drivers/i2c/busses/i2c-designware-slave.c
@@ -94,6 +94,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)
 
 	dev->disable_int(dev);
 	dev->disable(dev);
+	synchronize_irq(dev->irq);
 	dev->slave = NULL;
 	pm_runtime_put(dev->dev);
 
-- 
2.23.0.rc1




[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux