Commit d7437fc0 authored by Wolfram Sang's avatar Wolfram Sang Committed by Wolfram Sang

i2c: emev2: avoid race when unregistering slave client

After we disabled interrupts, there might still be an active one
running. Sync before clearing the pointer to the slave device.

Fixes: c31d0a00 ("i2c: emev2: add slave support")
Reported-by: default avatarKrzysztof Adamski <krzysztof.adamski@nokia.com>
Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: default avatarKrzysztof Adamski <krzysztof.adamski@nokia.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 7b814d85
......@@ -69,6 +69,7 @@ struct em_i2c_device {
struct completion msg_done;
struct clk *sclk;
struct i2c_client *slave;
int irq;
};
static inline void em_clear_set_bit(struct em_i2c_device *priv, u8 clear, u8 set, u8 reg)
......@@ -339,6 +340,12 @@ static int em_i2c_unreg_slave(struct i2c_client *slave)
writeb(0, priv->base + I2C_OFS_SVA0);
/*
* Wait for interrupt to finish. New slave irqs cannot happen because we
* cleared the slave address and, thus, only extension codes will be
* detected which do not use the slave ptr.
*/
synchronize_irq(priv->irq);
priv->slave = NULL;
return 0;
......@@ -355,7 +362,7 @@ static int em_i2c_probe(struct platform_device *pdev)
{
struct em_i2c_device *priv;
struct resource *r;
int irq, ret;
int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
......@@ -390,8 +397,8 @@ static int em_i2c_probe(struct platform_device *pdev)
em_i2c_reset(&priv->adap);
irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, irq, em_i2c_irq_handler, 0,
priv->irq = platform_get_irq(pdev, 0);
ret = devm_request_irq(&pdev->dev, priv->irq, em_i2c_irq_handler, 0,
"em_i2c", priv);
if (ret)
goto err_clk;
......@@ -401,7 +408,8 @@ static int em_i2c_probe(struct platform_device *pdev)
if (ret)
goto err_clk;
dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr, irq);
dev_info(&pdev->dev, "Added i2c controller %d, irq %d\n", priv->adap.nr,
priv->irq);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment