Re: [PATCH v5 2/2] i2c: imx-lpi2c: reset controller in probe stage
From: Frank Li
Date: Tue Jul 14 2026 - 09:50:25 EST
On Tue, Jun 30, 2026 at 06:52:23PM +0800, carlos.song@xxxxxxxxxxx wrote:
> From: Carlos Song <carlos.song@xxxxxxx>
>
> Reset I2C controller in probe stage to avoid unexpected LPI2C controller
> state left from previous stages and hang system boot.
>
> Per the LPI2C reference manual, section 7.1.4 "Controller Control (MCR)"
> and 7.1.20 Target Control (SCR), the RST bit (bit 1) description states:
>
> "The reset takes effect immediately and remains asserted until negated
> by software. There is no minimum delay required before clearing the
> software reset."
>
> Therefore, it is safe to write 0 to MCR and SCR immediately after
> asserting the RST bit without any additional delay.
>
> Signed-off-by: Carlos Song <carlos.song@xxxxxxx>
> ---
Reviewed-by: Frank Li <Frank.Li@xxxxxxx>
> drivers/i2c/busses/i2c-imx-lpi2c.c | 21 ++++++++++++++++-----
> 1 file changed, 16 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c
> index 2dc4331ed796..9fbdce85d7ca 100644
> --- a/drivers/i2c/busses/i2c-imx-lpi2c.c
> +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
> @@ -1510,11 +1510,6 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
> if (ret)
> lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ;
>
> - ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
> - pdev->name, lpi2c_imx);
> - if (ret)
> - return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq);
> -
> i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx);
> platform_set_drvdata(pdev, lpi2c_imx);
>
> @@ -1551,6 +1546,22 @@ static int lpi2c_imx_probe(struct platform_device *pdev)
> pm_runtime_set_active(&pdev->dev);
> pm_runtime_enable(&pdev->dev);
>
> + /*
> + * Reset all internal controller registers of both Master and Target
> + * to avoid effects of previous status.
> + */
> + writel(MCR_RST, lpi2c_imx->base + LPI2C_MCR);
> + writel(SCR_RST, lpi2c_imx->base + LPI2C_SCR);
> + writel(0, lpi2c_imx->base + LPI2C_MCR);
> + writel(0, lpi2c_imx->base + LPI2C_SCR);
> +
> + ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND,
> + pdev->name, lpi2c_imx);
> + if (ret) {
> + dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq);
> + goto rpm_disable;
> + }
> +
> temp = readl(lpi2c_imx->base + LPI2C_PARAM);
> lpi2c_imx->txfifosize = 1 << (temp & 0x0f);
> lpi2c_imx->rxfifosize = 1 << ((temp >> 8) & 0x0f);
> --
> 2.43.0
>