mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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: 23c8ebc952 ("clk: tenstorrent: Add Atlantis clock controller driver")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/AS8P251MB00013BD9A093C06D2D60E10EC8B42%40AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
Reviewed-by: Drew Fustini (Tenstorrent) <fustini@kernel.org>
Link: https://patch.msgid.link/20260924-atlantis_gate_shared_enable_fix-v1-1-303f925b8a3d@oss.tenstorrent.com
Signed-off-by: Drew Fustini (Tenstorrent) <fustini@kernel.org>
This commit is contained in:
parent
da9f1312b0
commit
3f0655b51e
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user