From: Steven Price <steven.price@arm.com>
To: Philipp Zabel <p.zabel@pengutronix.de>, Heiko Stuebner <heiko@sntech.de>
Cc: linux-kernel@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Subject: Re: [PATCH] reset: use a shared SRCU domain for reset controls
Date: Thu, 14 May 2026 10:07:29 +0100 [thread overview]
Message-ID: <a9b564b3-25ce-4b46-bf3c-bb5f0d2e7fdc@arm.com> (raw)
In-Reply-To: <9d06e549-ad7e-4089-99f1-88eb4b95a329@arm.com>
Gentle ping (see below)
On 24/04/2026 10:04, Steven Price wrote:
> On 23/04/2026 15:15, Philipp Zabel wrote:
>> Hi Steven, Heiko,
>>
>> On Do, 2026-04-23 at 13:45 +0100, Steven Price wrote:
>>> +Heiko for the Rockchip questions.
>>>
>>> On 23/04/2026 11:27, Philipp Zabel wrote:
>>>> Hi Steven,
>>>>
>>>> On Fr, 2026-04-17 at 16:48 +0100, Steven Price wrote:
>>>>> Commit 78ebbff6d1a0 ("reset: handle removing supplier before consumers")
>>>>> added a dynamically initialized srcu_struct to every reset_control and
>>>>> cleaned it up again when the handle was dropped.
>>>>>
>>>>> That breaks early boot users which acquire and release reset handles
>>>>> before workqueues are online. On rk3288 this shows up during
>>>>> rockchip_smp_prepare_cpus(), where pmu_set_power_domain() gets a reset
>>>>> control for a CPU core and then drops it again before SMP bring-up has
>>>>> finished.
>>>>
>>>> Can the reset_control_put() call be dropped from pmu_set_power_domain()
>>>> to fix the problem?
>>>
>>> I'm not that familiar with the code, so I'm not sure.
>>>
>>> Just dropping that call causes a WARN_ON() bringing the secondary CPUs
>>> on (because the call to rockchip_get_core_reset() expects to have
>>> exclusive access to the reset).
>>
>> Yes, caused by re-requesting the same reset again. I was thinking of
>> storing the controls in an array in rockchip_smp_prepare_cpus() and
>> reusing them in pmu_set_power_domain(), see the patch below.
>>
>>> Switching to a shared reset then his a
>>> WARN_ON() in reset_control_assert because deassert_count == 0. I could
>>> keep digging blindly but I'm not really sure how this code is meant to work.
>>
>> Shared reset is not the right mechanism here, that would be for
>> multiple drivers/devices sharing the same reset line.
>
> That makes sense - I hadn't really looked into whether this was a single
> reset for all CPUs or somehow one shared between them all. Thinking
> about it more I can't see how a shared reset would have worked ;)
>
>>> Hopefully Heiko might be able to shed some more light on this?
>>>
>>>> Putting the reset control should mean that the driver doesn't care
>>>> about the state of the reset line anymore, but the platsmp code very
>>>> much expects the reset line to stay deasserted after enabling a CPU.
>>>> Acquiring reset controls in rockchip_smp_prepare_cpus() once and never
>>>> giving them up via reset_control_put() seems like a correct fix,
>>>> regardless of whether this patch is applied or not.
>>>>
>>>> It looks like the meson platsmp suffers from the same issue.
>>>
>>> This is why I did the fix in the reset code -
>>
>> And I'm grateful, because that made sashiko.dev point out an ABBA
>> deadlock opportunity in the existing code.
>
> Cool.
>
>>> how many other platforms
>>> might have similar issues? But obviously if these platforms are buggy
>>> then they should be fixed.
>>
>> Agreed.
>>
>>> My interest is keeping the devboard working so I can keep testing
>>> Panfrost on it.
>>
>> Does this patch work?
>
> Indeed it does - thanks. Feel free to add my T-b when posting:
>
> Tested-by: Steven Price <steven.price@arm.com>
Can we pick the below patch up please? Let me know if there's anything I
can do to move this along.
Thanks,
Steve
>
> Thanks,
> Steve
>
>>
>> ----------8<----------
>> From: Philipp Zabel <p.zabel@pengutronix.de>
>> Subject: [PATCH] ARM: rockchip: keep reset control around
>>
>> Do not put the reset control, retain exclusive control over it.
>> After turning on a CPU, the corresponding reset line must stay
>> deasserted.
>>
>> This also avoids calling reset_control_put() before workqueues
>> are operational.
>>
>> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
>> ---
>> arch/arm/mach-rockchip/platsmp.c | 15 +++++++++------
>> 1 file changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c
>> index f432d22bfed8..c28816fffce8 100644
>> --- a/arch/arm/mach-rockchip/platsmp.c
>> +++ b/arch/arm/mach-rockchip/platsmp.c
>> @@ -34,6 +34,7 @@ static int ncores;
>>
>> static struct regmap *pmu;
>> static int has_pmu = true;
>> +static struct reset_control *cpu_rstc[4];
>>
>> static int pmu_power_domain_is_on(int pd)
>> {
>> @@ -64,9 +65,11 @@ static struct reset_control *rockchip_get_core_reset(int cpu)
>> static int pmu_set_power_domain(int pd, bool on)
>> {
>> u32 val = (on) ? 0 : BIT(pd);
>> - struct reset_control *rstc = rockchip_get_core_reset(pd);
>> + struct reset_control *rstc;
>> int ret;
>>
>> + rstc = pd < ARRAY_SIZE(cpu_rstc) ? cpu_rstc[pd] : ERR_PTR(-EINVAL);
>> +
>> if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) {
>> pr_err("%s: could not get reset control for core %d\n",
>> __func__, pd);
>> @@ -100,11 +103,8 @@ static int pmu_set_power_domain(int pd, bool on)
>> }
>> }
>>
>> - if (!IS_ERR(rstc)) {
>> - if (on)
>> - reset_control_deassert(rstc);
>> - reset_control_put(rstc);
>> - }
>> + if (!IS_ERR(rstc) && on)
>> + reset_control_deassert(rstc);
>>
>> return 0;
>> }
>> @@ -312,6 +312,9 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus)
>> ncores = ((l2ctlr >> 24) & 0x3) + 1;
>> }
>>
>> + for (i = 0; i < ncores; i++)
>> + cpu_rstc[i] = rockchip_get_core_reset(i);
>> +
>> /* Make sure that all cores except the first are really off */
>> for (i = 1; i < ncores; i++)
>> pmu_set_power_domain(0 + i, false);
>
parent reply other threads:[~2026-05-14 9:07 UTC|newest]
Thread overview: expand[flat|nested] mbox.gz Atom feed
[parent not found: <9d06e549-ad7e-4089-99f1-88eb4b95a329@arm.com>]
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=a9b564b3-25ce-4b46-bf3c-bb5f0d2e7fdc@arm.com \
--to=steven.price@arm.com \
--cc=bartosz.golaszewski@oss.qualcomm.com \
--cc=heiko@sntech.de \
--cc=linux-kernel@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
/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