This is a note to let you know that I've just added the patch titled i2c: rcar: reset controller is mandatory for Gen3+ to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: i2c-rcar-reset-controller-is-mandatory-for-gen3.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit d8f3831ba37d73e305b9b9272210a46aa6269049 Author: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> Date: Thu Sep 21 14:53:49 2023 +0200 i2c: rcar: reset controller is mandatory for Gen3+ [ Upstream commit 0e864b552b2302e40b2277629ebac79544a5c433 ] Initially, we only needed a reset controller to make sure RXDMA works at least once per transfer. Meanwhile, documentation has been updated. It now says that a reset has to be performed prior every transaction, even if it is non-DMA. So, make the reset controller a requirement instead of being optional. And bail out if resetting fails. Signed-off-by: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> Reviewed-by: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> Signed-off-by: Wolfram Sang <wsa@xxxxxxxxxx> Stable-dep-of: ea5ea84c9d35 ("i2c: rcar: ensure Gen3+ reset does not disturb local targets") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c index 2fec6cb09757a..3fda82159e54d 100644 --- a/drivers/i2c/busses/i2c-rcar.c +++ b/drivers/i2c/busses/i2c-rcar.c @@ -851,12 +851,10 @@ static int rcar_i2c_master_xfer(struct i2c_adapter *adap, /* Gen3 needs a reset before allowing RXDMA once */ if (priv->devtype == I2C_RCAR_GEN3) { - priv->flags |= ID_P_NO_RXDMA; - if (!IS_ERR(priv->rstc)) { - ret = rcar_i2c_do_reset(priv); - if (ret == 0) - priv->flags &= ~ID_P_NO_RXDMA; - } + priv->flags &= ~ID_P_NO_RXDMA; + ret = rcar_i2c_do_reset(priv); + if (ret) + goto out; } rcar_i2c_init(priv); @@ -1106,15 +1104,6 @@ static int rcar_i2c_probe(struct platform_device *pdev) irqhandler = rcar_i2c_gen2_irq; } - if (priv->devtype == I2C_RCAR_GEN3) { - priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (!IS_ERR(priv->rstc)) { - ret = reset_control_status(priv->rstc); - if (ret < 0) - priv->rstc = ERR_PTR(-ENOTSUPP); - } - } - /* Stay always active when multi-master to keep arbitration working */ if (of_property_read_bool(dev->of_node, "multi-master")) priv->flags |= ID_P_PM_BLOCKED; @@ -1124,6 +1113,16 @@ static int rcar_i2c_probe(struct platform_device *pdev) if (of_property_read_bool(dev->of_node, "smbus")) priv->flags |= ID_P_HOST_NOTIFY; + if (priv->devtype == I2C_RCAR_GEN3) { + priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(priv->rstc)) + goto out_pm_put; + + ret = reset_control_status(priv->rstc); + if (ret < 0) + goto out_pm_put; + } + ret = platform_get_irq(pdev, 0); if (ret < 0) goto out_pm_put;