]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
i2c: rcar: ensure Gen3+ reset does not disturb local targets
authorWolfram Sang <wsa+renesas@sang-engineering.com>
Thu, 11 Jul 2024 08:30:44 +0000 (10:30 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Jul 2024 11:21:26 +0000 (13:21 +0200)
[ Upstream commit ea5ea84c9d3570dc06e8fc5ee2273eaa584aa3ac ]

R-Car Gen3+ needs a reset before every controller transfer. That erases
configuration of a potentially in parallel running local target
instance. To avoid this disruption, avoid controller transfers if a
local target is running. Also, disable SMBusHostNotify because it
requires being a controller and local target at the same time.

Fixes: 3b770017b03a ("i2c: rcar: handle RXDMA HW behaviour on Gen3")
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/i2c/busses/i2c-rcar.c

index 2719bc5a1a771fe53b606c0f491f1617dc886411..0ba88d44a7dbec314d337d4289f10a1ca5dfa878 100644 (file)
@@ -824,6 +824,10 @@ static int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
 {
        int ret;
 
+       /* Don't reset if a slave instance is currently running */
+       if (priv->slave)
+               return -EISCONN;
+
        ret = reset_control_reset(priv->rstc);
        if (ret)
                return ret;
@@ -1114,6 +1118,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
        if (of_property_read_bool(dev->of_node, "smbus"))
                priv->flags |= ID_P_HOST_NOTIFY;
 
+       /* R-Car Gen3+ needs a reset before every transfer */
        if (priv->devtype >= I2C_RCAR_GEN3) {
                priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
                if (IS_ERR(priv->rstc))
@@ -1122,6 +1127,9 @@ static int rcar_i2c_probe(struct platform_device *pdev)
                ret = reset_control_status(priv->rstc);
                if (ret < 0)
                        goto out_pm_put;
+
+               /* hard reset disturbs HostNotify local target, so disable it */
+               priv->flags &= ~ID_P_HOST_NOTIFY;
        }
 
        ret = platform_get_irq(pdev, 0);