From: Claudiu Beznea <claudiu.beznea@kernel.org>
To: Frank Li <Frank.li@nxp.com>
Cc: wsa+renesas@sang-engineering.com,
tommaso.merciai.xr@bp.renesas.com, alexandre.belloni@bootlin.com,
p.zabel@pengutronix.de, claudiu.beznea@tuxon.dev,
linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org,
linux-renesas-soc@vger.kernel.org,
Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>,
stable@vger.kernel.org
Subject: Re: [PATCH 06/17] i3c: renesas: Reset the controller on resume
Date: Sat, 23 May 2026 13:24:15 +0300 [thread overview]
Message-ID: <df2d27a3-c349-4aa4-b897-e9dc3418b2c0@kernel.org> (raw)
In-Reply-To: <ahCrOed9QpKR5ZRF@lizhi-Precision-Tower-5810>
On 5/22/26 22:15, Frank Li wrote:
> On Fri, May 22, 2026 at 01:18:04PM +0300, Claudiu Beznea wrote:
>> From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>>
>> Reset the controller on resume after enabling the clocks to follow the
>> same sequence as in probe and avoid potential ordering related failures.
>>
>> Fixes: e7218986319b ("i3c: renesas: Add suspend/resume support")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
>> ---
>
> Can you move these similar stuff to one helper function to avoid duplicate
> efforts later?
If you are talking about moving also the control of the reset signals in the
renesas_i3c_reset() I can do that, but, FMPOV, it will complicate the code,
especially the initialization and failure paths (see the above diff built on top
of this series).
Moving the reset de-assert in the renesas_i3c_reset() will involve calling
functions to assert back the resets in case of failure. FMPOV, that is a bit
unbalanced (wrt the way the code looks) because we are calling deassert in one
function and assert in another function. It is a bit difficult to follow.
Please see the above diff and let me know your thoughts.
diff --git a/drivers/i3c/master/renesas-i3c.c b/drivers/i3c/master/renesas-i3c.c
index 3b9807a89b54..5f45a024aa54 100644
--- a/drivers/i3c/master/renesas-i3c.c
+++ b/drivers/i3c/master/renesas-i3c.c
@@ -255,8 +255,7 @@ struct renesas_i3c_xferqueue {
struct renesas_i3c {
void __iomem *regs;
struct clk *tclk;
- struct reset_control *presetn;
- struct reset_control *tresetn;
+ struct reset_control_bulk_data *resets;
struct device *dev;
int *irqs;
struct renesas_i3c_xferqueue xferqueue;
@@ -264,6 +263,7 @@ struct renesas_i3c {
unsigned long rate;
unsigned int num_irqs;
enum i3c_internal_state internal_state;
+ u32 num_resets;
u32 free_pos;
u32 dyn_addr;
u32 i2c_STDBR;
@@ -492,16 +492,28 @@ static int renesas_i3c_reset(struct renesas_i3c *i3c)
u32 val;
int ret;
+ ret = reset_control_bulk_deassert(i3c->num_resets, i3c->resets);
+ if (ret)
+ return ret;
+
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(i3c->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
if (ret)
- return ret;
+ goto assert;
renesas_writel(i3c->regs, BCTL, 0);
renesas_set_bit(i3c->regs, RSTCTL, RSTCTL_RI3CRST);
- return read_poll_timeout(renesas_readl, val, !(val & RSTCTL_RI3CRST),
- 0, 1000, false, i3c->regs, RSTCTL);
+ ret = read_poll_timeout(renesas_readl, val, !(val & RSTCTL_RI3CRST),
+ 0, 1000, false, i3c->regs, RSTCTL);
+ if (ret)
+ goto assert;
+
+ return 0;
+
+assert:
+ reset_control_bulk_assert(i3c->num_resets, i3c->resets);
+ return ret;
}
static void renesas_i3c_hw_init(struct renesas_i3c *i3c)
@@ -1430,11 +1442,20 @@ static const struct renesas_i3c_irq_desc
renesas_i3c_irqs[] = {
{ .name = "nack", .isr = renesas_i3c_tend_isr, .desc = "i3c-nack" },
};
+static const char * const renesas_i3c_resets[] = { "tresetn", "presetn" };
+
static void renesas_i3c_dont_use_autosuspend(void *data)
{
pm_runtime_dont_use_autosuspend(data);
}
+static void renesas_i3c_resets_assert(void *data)
+{
+ struct renesas_i3c *i3c = data;
+
+ reset_control_bulk_assert(i3c->num_resets, i3c->resets);
+}
+
static int renesas_i3c_probe(struct platform_device *pdev)
{
struct renesas_i3c *i3c;
@@ -1464,15 +1485,20 @@ static int renesas_i3c_probe(struct platform_device *pdev)
if (ret)
return ret;
- i3c->tresetn =
devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "tresetn");
- if (IS_ERR(i3c->tresetn))
- return dev_err_probe(&pdev->dev, PTR_ERR(i3c->tresetn),
- "Error: missing tresetn ctrl\n");
+ i3c->num_resets = ARRAY_SIZE(renesas_i3c_resets);
+ i3c->resets = devm_kmalloc_array(&pdev->dev, i3c->num_resets,
+ sizeof(*i3c->resets), GFP_KERNEL);
+ if (!i3c->resets)
+ return -ENOMEM;
- i3c->presetn =
devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "presetn");
- if (IS_ERR(i3c->presetn))
- return dev_err_probe(&pdev->dev, PTR_ERR(i3c->presetn),
- "Error: missing presetn ctrl\n");
+ for (unsigned int i = 0; i < i3c->num_resets; i++)
+ i3c->resets[i].id = renesas_i3c_resets[i];
+
+ ret = devm_reset_control_bulk_get_optional_exclusive(&pdev->dev,
+ i3c->num_resets,
+ i3c->resets);
+ if (ret)
+ return ret;
spin_lock_init(&i3c->xferqueue.lock);
INIT_LIST_HEAD(&i3c->xferqueue.list);
@@ -1481,6 +1507,11 @@ static int renesas_i3c_probe(struct platform_device *pdev)
if (ret)
return ret;
+ /* Add devm action for resets deasserted in renesas_i3c_reset(). */
+ ret = devm_add_action_or_reset(&pdev->dev, renesas_i3c_resets_assert, NULL);
+ if (ret)
+ return ret;
+
i3c->num_irqs = ARRAY_SIZE(renesas_i3c_irqs);
i3c->irqs = devm_kcalloc(&pdev->dev, i3c->num_irqs, sizeof(*i3c->irqs),
GFP_KERNEL);
if (!i3c->irqs)
@@ -1523,15 +1554,11 @@ static void renesas_i3c_remove(struct platform_device *pdev)
static int renesas_i3c_suspend(struct device *dev)
{
struct renesas_i3c *i3c = dev_get_drvdata(dev);
- struct reset_control_bulk_data resets[] = {
- { .rstc = i3c->presetn },
- { .rstc = i3c->tresetn },
- };
int ret;
i2c_mark_adapter_suspended(&i3c->base.i2c);
- ret = reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+ ret = reset_control_bulk_assert(i3c->num_resets, i3c->resets);
if (ret)
goto err_mark_resumed;
@@ -1542,7 +1569,7 @@ static int renesas_i3c_suspend(struct device *dev)
return 0;
err_resets_deassert:
- reset_control_bulk_deassert(ARRAY_SIZE(resets), resets);
+ reset_control_bulk_deassert(i3c->num_resets, i3c->resets);
err_mark_resumed:
i2c_mark_adapter_resumed(&i3c->base.i2c);
@@ -1552,23 +1579,15 @@ static int renesas_i3c_suspend(struct device *dev)
static int renesas_i3c_resume(struct device *dev)
{
struct renesas_i3c *i3c = dev_get_drvdata(dev);
- struct reset_control_bulk_data resets[] = {
- { .rstc = i3c->presetn },
- { .rstc = i3c->tresetn },
- };
int ret;
ret = pm_runtime_force_resume(dev);
if (ret)
return ret;
- ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets);
- if (ret)
- return ret;
-
ret = renesas_i3c_reset(i3c);
if (ret)
- goto err_resets_asserted;
+ return ret;
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(i3c->dev, pm);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
@@ -1607,7 +1626,7 @@ static int renesas_i3c_resume(struct device *dev)
* if a runtime path is triggered after a failed resume). Checked on
* RZ/G3S.
*/
- reset_control_bulk_assert(ARRAY_SIZE(resets), resets);
+ reset_control_bulk_assert(i3c->num_resets, i3c->resets);
return ret;
}
--
Thank you,
Claudiu
next prev parent reply other threads:[~2026-05-23 10:24 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-22 10:17 [PATCH 00/17] i3c: renesas: Suspend to RAM with power loss and runtime PM Claudiu Beznea
2026-05-22 10:17 ` [PATCH 01/17] i3c: renesas: Check that the transfer is valid before accessing it Claudiu Beznea
2026-05-22 19:02 ` Frank Li
2026-05-22 10:18 ` [PATCH 02/17] i3c: renesas: Use the divider 128 Claudiu Beznea
2026-05-22 19:06 ` Frank Li
2026-05-23 8:14 ` Claudiu Beznea
2026-05-22 10:18 ` [PATCH 03/17] i3c: renesas: Restore STDBR and EXTBR registers on resume Claudiu Beznea
2026-05-22 19:10 ` Frank Li
2026-05-28 8:29 ` Claudiu Beznea
2026-05-28 19:13 ` Frank Li
2026-05-22 10:18 ` [PATCH 04/17] i3c: renesas: Follow the reset deassert order used in probe Claudiu Beznea
2026-05-22 19:11 ` Frank Li
2026-05-22 10:18 ` [PATCH 05/17] i3c: renesas: Fix re-attach Claudiu Beznea
2026-05-22 19:13 ` Frank Li
2026-05-22 10:18 ` [PATCH 06/17] i3c: renesas: Reset the controller on resume Claudiu Beznea
2026-05-22 19:15 ` Frank Li
2026-05-23 10:24 ` Claudiu Beznea [this message]
2026-05-22 10:18 ` [PATCH 07/17] i3c: renesas: Perform Dynamic Address Assignment " Claudiu Beznea
2026-05-22 19:16 ` Frank Li
2026-05-23 10:26 ` Claudiu Beznea
2026-05-22 10:18 ` [PATCH 08/17] i3c: renesas: Clean DATBAS register on detach Claudiu Beznea
2026-05-22 19:17 ` Frank Li
2026-05-22 10:18 ` [PATCH 09/17] i3c: renesas: Use reset_control_bulk_{assert, deassert}() Claudiu Beznea
2026-05-22 19:19 ` Frank Li
2026-05-23 10:26 ` Claudiu Beznea
2026-05-22 10:18 ` [PATCH 10/17] i3c: renesas: Return immediately if there is nothing to transfer Claudiu Beznea
2026-05-22 19:20 ` Frank Li
2026-05-22 10:18 ` [PATCH 11/17] i3c: renesas: Follow a unified pattern for transfer and command initialization Claudiu Beznea
2026-05-22 19:21 ` Frank Li
2026-05-22 10:18 ` [PATCH 12/17] i3c: renesas: Drop the explicit memset() call Claudiu Beznea
2026-05-22 19:43 ` Frank Li
2026-05-22 10:18 ` [PATCH 13/17] i3c: renesas: Update HW registers after SW computations are done Claudiu Beznea
2026-05-22 19:48 ` Frank Li
2026-05-22 10:18 ` [PATCH 14/17] i3c: renesas: Organize structures to avoid unnecessary padding Claudiu Beznea
2026-05-22 19:50 ` Frank Li
2026-05-22 10:18 ` [PATCH 15/17] i3c: renesas: Use the "dev_name:irq_name" format for the interrupt name Claudiu Beznea
2026-05-22 19:51 ` Frank Li
2026-05-22 10:18 ` [PATCH 16/17] i3c: renesas: Drop unnecessary tab Claudiu Beznea
2026-05-22 19:52 ` Frank Li
2026-05-22 10:18 ` [PATCH 17/17] i3c: renesas: Add runtime PM support Claudiu Beznea
2026-05-22 20:01 ` Frank Li
2026-05-23 10:23 ` Claudiu Beznea
2026-06-02 11:49 ` Claudiu Beznea
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=df2d27a3-c349-4aa4-b897-e9dc3418b2c0@kernel.org \
--to=claudiu.beznea@kernel.org \
--cc=Frank.li@nxp.com \
--cc=alexandre.belloni@bootlin.com \
--cc=claudiu.beznea.uj@bp.renesas.com \
--cc=claudiu.beznea@tuxon.dev \
--cc=linux-i3c@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=stable@vger.kernel.org \
--cc=tommaso.merciai.xr@bp.renesas.com \
--cc=wsa+renesas@sang-engineering.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox