public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Biju Das <biju.das.jz@bp.renesas.com>,
	Geert Uytterhoeven <geert+renesas@glider.be>,
	Sasha Levin <sashal@kernel.org>,
	mturquette@baylibre.com, sboyd@kernel.org,
	linux-renesas-soc@vger.kernel.org, linux-clk@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-6.18] clk: renesas: rzg2l: Deassert reset on assert timeout
Date: Mon, 16 Feb 2026 20:01:13 -0500	[thread overview]
Message-ID: <20260217010118.3503621-2-sashal@kernel.org> (raw)
In-Reply-To: <20260217010118.3503621-1-sashal@kernel.org>

From: Biju Das <biju.das.jz@bp.renesas.com>

[ Upstream commit 0b0201f259e1158a875c5fd01adf318ae5d32352 ]

If the assert() fails due to timeout error, set the reset register bit
back to deasserted state. This change is needed especially for handling
assert error in suspend() callback that expect the device to be in
operational state in case of failure.

Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260108123433.104464-2-biju.das.jz@bp.renesas.com
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

The suspend/resume directly in this driver doesn't call assert. The
commit message mentions "suspend() callback" — this likely refers to
peripheral device drivers that use reset_control_assert() during their
own suspend callbacks, which then calls `rzg2l_cpg_assert()` through the
reset_control_ops.

## Summary of Analysis

### What the commit fixes:
1. **Variable shadowing bug**: `readl_poll_timeout_atomic` overwrites
   `value`, which is then needed for the error recovery path. The patch
   introduces a separate `mon` variable for the poll output, keeping
   `value` intact.
2. **Missing error recovery on assert timeout**: The original code only
   rolls back on deassert failure. If assert fails (e.g., during
   suspend), the device is left in an asserted (reset) state with no
   recovery, making the device non-operational even though the suspend
   callback returns an error. The fix uses `value ^= mask` to undo
   either direction of the operation.

### Dependencies:
This commit has **hard dependencies** on two v6.18 commits:
- `341b0f1b6cba5` - introduces `__rzg2l_cpg_assert()` helper
- `f8c5f0dc77d86` - introduces the deassert-only rollback code that this
  commit modifies

Without these two prerequisite commits, the patch cannot apply to any
stable tree older than v6.18.

### Risk Assessment:
- **Scope**: Small, contained change in one function (~10 lines changed)
- **Risk**: Low — only affects error paths in Renesas RZ/G2L clock/reset
  driver
- **Correctness**: The XOR approach is elegant and correct for both
  assert and deassert cases
- **Review**: Has "Reviewed-by: Geert Uytterhoeven" (Renesas clk
  subsystem maintainer)

### Stable Tree Applicability:
The fix only applies to v6.18.y since its prerequisites were merged in
v6.18-rc1. For older stable trees (6.12.y, 6.6.y, etc.), the code
structure is completely different (separate functions, no rollback
logic), so this specific bug doesn't exist there.

## Verification

- **git log master** showed the prerequisite commits 341b0f1b6cba5 and
  f8c5f0dc77d86 are only in v6.18+
- **git tag --contains** confirmed both prerequisites are in v6.18-rc1+,
  not in any earlier release
- **git show v6.12:drivers/clk/renesas/rzg2l-cpg.c** confirmed older
  stable trees have separate assert/deassert functions without the
  `__rzg2l_cpg_assert()` helper and without any error rollback logic
- **Read of current file** confirmed the code matches the "before" state
  of the diff
- **Code analysis** verified the XOR-based rollback logic is correct:
  when asserting, `value = mask << 16` (no lower mask), XOR with mask
  adds it → deasserts; when deasserting, `value = (mask << 16) | mask`,
  XOR with mask removes it → re-asserts
- **Variable shadowing confirmed**: `readl_poll_timeout_atomic` modifies
  the `value` parameter in-place, so using it for both the initial write
  value and poll output is a real bug (though in practice the old code's
  `if (ret && !assert)` branch reassigned `value`, masking the issue for
  deassert)

## Decision

This is a legitimate bug fix that:
1. Fixes a real issue where assert failure during suspend leaves
   hardware in a non-operational state
2. Also fixes a variable shadowing bug (reusing `value` for two
   different purposes)
3. Is small, contained, reviewed by the subsystem maintainer
4. Meets stable kernel criteria

However, it has hard dependencies on two refactoring/feature commits
from v6.18 that are not in any current stable tree. The only applicable
stable tree would be 6.18.y. Given that this is a genuine fix for an
error recovery path that matters during suspend/resume, and it's
applicable to 6.18.y, it should be backported.

**YES**

 drivers/clk/renesas/rzg2l-cpg.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c
index 64d1ef6e4c943..c20ea1212b360 100644
--- a/drivers/clk/renesas/rzg2l-cpg.c
+++ b/drivers/clk/renesas/rzg2l-cpg.c
@@ -1647,6 +1647,7 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
 	u32 mask = BIT(info->resets[id].bit);
 	s8 monbit = info->resets[id].monbit;
 	u32 value = mask << 16;
+	u32 mon;
 	int ret;
 
 	dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n",
@@ -1667,10 +1668,10 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
 		return 0;
 	}
 
-	ret = readl_poll_timeout_atomic(priv->base + reg, value,
-					assert == !!(value & mask), 10, 200);
-	if (ret && !assert) {
-		value = mask << 16;
+	ret = readl_poll_timeout_atomic(priv->base + reg, mon,
+					assert == !!(mon & mask), 10, 200);
+	if (ret) {
+		value ^= mask;
 		writel(value, priv->base + CLK_RST_R(info->resets[id].off));
 	}
 
-- 
2.51.0


  reply	other threads:[~2026-02-17  1:01 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-17  1:01 [PATCH AUTOSEL 6.19-5.10] clk: microchip: core: correct return value on *_get_parent() Sasha Levin
2026-02-17  1:01 ` Sasha Levin [this message]
2026-02-17  1:01 ` [PATCH AUTOSEL 6.19-6.12] 9p/xen: protect xen_9pfs_front_free against concurrent calls Sasha Levin
2026-02-17  1:01 ` [PATCH AUTOSEL 6.19-6.18] clk: amlogic: remove potentially unsafe flags from S4 video clocks Sasha Levin
2026-02-17  1:01 ` [PATCH AUTOSEL 6.19-6.12] HID: i2c-hid: Add FocalTech FT8112 Sasha Levin
2026-02-17  1:01 ` [PATCH AUTOSEL 6.19-5.10] m68k: nommu: fix memmove() with differently aligned src and dest for 68000 Sasha Levin

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=20260217010118.3503621-2-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=biju.das.jz@bp.renesas.com \
    --cc=geert+renesas@glider.be \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=mturquette@baylibre.com \
    --cc=patches@lists.linux.dev \
    --cc=sboyd@kernel.org \
    --cc=stable@vger.kernel.org \
    /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