From 3f0655b51eb01dad30d61ced0a81718211f2776e Mon Sep 17 00:00:00 2001 From: Anirudh Srinivasan Date: Thu, 24 Sep 2026 10:31:51 -0500 Subject: [PATCH] clk: tenstorrent: Fix refcount leak on shared gate clk enable failure atlantis_clk_gate_shared_enable() increments the refcount for the number of clks requesting the shared gate clk to be enabled always. It should only do this when the enable for the gate took effect in hardware. It's possible to end up in a situation where the gate enable failed, but the refcount is incremented anyway, so subsequent requests by other clks that share the same refcount get ignored and the gate enable is never retried. Update this function so that the refcount is not incremented when the gate clk enable fails in hardware. Fixes: 23c8ebc95284 ("clk: tenstorrent: Add Atlantis clock controller driver") Cc: stable@vger.kernel.org Reported-by: Sashiko Link: https://sashiko.dev/#/patchset/AS8P251MB00013BD9A093C06D2D60E10EC8B42%40AS8P251MB0001.EURP251.PROD.OUTLOOK.COM Signed-off-by: Anirudh Srinivasan Reviewed-by: Drew Fustini (Tenstorrent) Link: https://patch.msgid.link/20260924-atlantis_gate_shared_enable_fix-v1-1-303f925b8a3d@oss.tenstorrent.com Signed-off-by: Drew Fustini (Tenstorrent) --- drivers/clk/tenstorrent/atlantis-prcm.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/drivers/clk/tenstorrent/atlantis-prcm.c b/drivers/clk/tenstorrent/atlantis-prcm.c index 6772035ec872..bf244b1fbfc1 100644 --- a/drivers/clk/tenstorrent/atlantis-prcm.c +++ b/drivers/clk/tenstorrent/atlantis-prcm.c @@ -397,22 +397,21 @@ static int atlantis_clk_gate_shared_enable(struct clk_hw *hw) scoped_guard(spinlock_irqsave, gate->config.refcount_lock) { - need_enable = (*gate->config.share_count)++ == 0; + need_enable = (*gate->config.share_count) == 0; if (need_enable) { regmap_set_bits(gate->common.regmap, gate->config.reg_offset, gate->config.enable); - } - } - if (need_enable) { - if (!regmap_test_bits(gate->common.regmap, - gate->config.reg_offset, - gate->config.enable)) { - pr_warn("%s: gate enable %d failed to enable\n", - clk_hw_get_name(hw), gate->config.enable); - return -EIO; + if (!regmap_test_bits(gate->common.regmap, + gate->config.reg_offset, + gate->config.enable)) { + pr_warn("%s: gate enable %d failed to enable\n", + clk_hw_get_name(hw), gate->config.enable); + return -EIO; + } } + (*gate->config.share_count)++; } return 0;