Re: [PATCH 07/17] i3c: renesas: Perform Dynamic Address Assignment on resume

Frank Li <[email protected]>
Newsgroups org.infradead.lists.linux-i3c,org.kernel.vger.linux-kernel,org.kernel.vger.linux-renesas-soc,org.kernel.vger.stable
Message-ID <ahCrpz-J8a5HQSmY@lizhi-Precision-Tower-5810>
On Fri, May 22, 2026 at 01:18:05PM +0300, Claudiu Beznea wrote:
> From: Claudiu Beznea <[email protected]>
>
> The Renesas RZ/G3S SoC supports a power saving mode where power to most
> SoC components, including I3C, is turned off.
>
> On systems where the I3C devices also loses power during suspend (e.g. NXP
> P3T1085UK-ARD connected to the PMOD1_6A connector of the RZ SMARC Carrier
> 2 + Renesas RZ/G3S SMARC SOM), the devices becomes unreachable after
> resume.
>
> Running DAA in the controller resume path restores communication. However,
> DAA relies on interrupts for TX/RX, which are not available in the noirq
> suspend/resume phase (unless they are wakeup interrupts). For this, the
> suspend/resume callbacks were moved out of the noirq phase. Currently,
> there is no identified use case on either the Renesas RZ/G3S or Renesas
> RZ/G3E SoCs that requires the controller suspend/resume hooks to be part of
> the noirq suspend/resume phase.

Can you refer https://lore.kernel.org/linux-i3c/[email protected]/T/#mafdc9631a2a18dfebfa5b5efcb8584d32bceba7f

which defer DAA to workqueue.

Frank

>
> Along with this, struct renesas_i3c::DATBASn and its usage were removed,
> as they are no longer needed.
>
> Fixes: e7218986319b ("i3c: renesas: Add suspend/resume support")
> Cc: [email protected]
> Signed-off-by: Claudiu Beznea <[email protected]>
> ---
>  drivers/i3c/master/renesas-i3c.c | 34 ++++++++++++--------------------
>  1 file changed, 13 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/i3c/master/renesas-i3c.c b/drivers/i3c/master/renesas-i3c.c
> index 2f3c6ddf75c0..c009d0de6a2b 100644
> --- a/drivers/i3c/master/renesas-i3c.c
> +++ b/drivers/i3c/master/renesas-i3c.c
> @@ -265,7 +265,6 @@ struct renesas_i3c {
>  	u8 addrs[RENESAS_I3C_MAX_DEVS];
>  	struct renesas_i3c_xferqueue xferqueue;
>  	void __iomem *regs;
> -	u32 *DATBASn;
>  	struct clk_bulk_data *clks;
>  	struct reset_control *presetn;
>  	struct reset_control *tresetn;
> @@ -1400,12 +1399,6 @@ static int renesas_i3c_probe(struct platform_device *pdev)
>  	i3c->maxdevs = RENESAS_I3C_MAX_DEVS;
>  	i3c->free_pos = GENMASK(i3c->maxdevs - 1, 0);
>
> -	/* Allocate dynamic Device Address Table backup. */
> -	i3c->DATBASn = devm_kzalloc(&pdev->dev, sizeof(u32) * i3c->maxdevs,
> -				    GFP_KERNEL);
> -	if (!i3c->DATBASn)
> -		return -ENOMEM;
> -
>  	return i3c_master_register(&i3c->base, &pdev->dev, &renesas_i3c_ops, false);
>  }
>
> @@ -1416,17 +1409,13 @@ static void renesas_i3c_remove(struct platform_device *pdev)
>  	i3c_master_unregister(&i3c->base);
>  }
>
> -static int renesas_i3c_suspend_noirq(struct device *dev)
> +static int renesas_i3c_suspend(struct device *dev)
>  {
>  	struct renesas_i3c *i3c = dev_get_drvdata(dev);
> -	int i, ret;
> +	int ret;
>
>  	i2c_mark_adapter_suspended(&i3c->base.i2c);
>
> -	/* Store Device Address Table values. */
> -	for (i = 0; i < i3c->maxdevs; i++)
> -		i3c->DATBASn[i] = renesas_readl(i3c->regs, DATBAS(i));
> -
>  	ret = reset_control_assert(i3c->presetn);
>  	if (ret)
>  		goto err_mark_resumed;
> @@ -1447,10 +1436,10 @@ static int renesas_i3c_suspend_noirq(struct device *dev)
>  	return ret;
>  }
>
> -static int renesas_i3c_resume_noirq(struct device *dev)
> +static int renesas_i3c_resume(struct device *dev)
>  {
>  	struct renesas_i3c *i3c = dev_get_drvdata(dev);
> -	int i, ret;
> +	int ret;
>
>  	ret = reset_control_deassert(i3c->tresetn);
>  	if (ret)
> @@ -1476,15 +1465,19 @@ static int renesas_i3c_resume_noirq(struct device *dev)
>  	renesas_writel(i3c->regs, MSDVAD, MSDVAD_MDYADV |
>  		       MSDVAD_MDYAD(i3c->dyn_addr));
>
> -	/* Restore Device Address Table values. */
> -	for (i = 0; i < i3c->maxdevs; i++)
> -		renesas_writel(i3c->regs, DATBAS(i), i3c->DATBASn[i]);
> -
>  	/* I3C hw init. */
>  	renesas_i3c_hw_init(i3c);
>
>  	i2c_mark_adapter_resumed(&i3c->base.i2c);
>
> +	ret = i3c_master_do_daa_ext(&i3c->base, true);
> +	if (ret)
> +		dev_err(dev, "DAA failed on resume, ret=%d", ret);
> +
> +	/*
> +	 * I3C devices may have retained their dynamic address anyway. Do not
> +	 * fail the resume because of DAA error.
> +	 */
>  	return 0;
>
>  err_clks_disable:
> @@ -1497,8 +1490,7 @@ static int renesas_i3c_resume_noirq(struct device *dev)
>  }
>
>  static const struct dev_pm_ops renesas_i3c_pm_ops = {
> -	NOIRQ_SYSTEM_SLEEP_PM_OPS(renesas_i3c_suspend_noirq,
> -				  renesas_i3c_resume_noirq)
> +	SYSTEM_SLEEP_PM_OPS(renesas_i3c_suspend, renesas_i3c_resume)
>  };
>
>  static const struct of_device_id renesas_i3c_of_ids[] = {
> --
> 2.43.0
>

-- 
linux-i3c mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-i3c
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.