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