Re: [PATCH] clk: qcom: gcc-ipq5018: mark 'gpll0_main' clock as critical
From: Gabor Juhos
Date: Thu Sep 24 2026 - 07:40:33 EST
Hi Konrad,
2026. 09. 23. 15:32 keltezéssel, Konrad Dybcio írta:
> On 9/18/26 11:27 AM, Gabor Juhos wrote:
>> On IPQ5018, the APCS core clock feeds the CPUs. It can use
>> different clocks as its parent, but during system boot it
>> utilizes GPLL0.
>>
>> Under some cicumstances, the 'gpll0_main' clock is getting
>> disabled during kernel start which results in a system hang
>> then the hardware watchdog restarts the board after a while.
>>
>> This can happen when a driver gets a clock in its probe function,
>> then releases it either directly or by devres cleanup on probe
>> failure.
>>
>> For example, since v6.18 the kernel often fails to boot on the
>> TP-Link Archer AX55 v1 board by using the in-tree dts. In the
>> failing configuration, the 'ipq-cmn-pll' driver is built into
>> the kernel and the problem is caused by the pm_runtim_put()
>> call in the ipq_cmn_pll_clk_probe() function. Due to this call,
>> runtime pm disables the 'gcc_cmn_blk_ahb_clk' clock asynchronously
>> which results in disabling 'gpll0_main' as well.
>>
>> Mark the clock as critical in order to avoid such hangs.
>>
>> Cc: stable@xxxxxxxxxxxxxxx
>> Fixes: e3fdbef1bab8 ("clk: qcom: Add Global Clock controller (GCC) driver for IPQ5018")
>> Signed-off-by: Gabor Juhos <j4g8y7@xxxxxxxxx>
>> ---
>> Note:
>> There is a patch [1] awaiting upstream which intends to solve the
>> problem in the case of the 'ipq-cmn-pll' driver. However the same
>> hang can be reproduced with several other drivers by triggering a
>> probe failure in them.
>>
>> The actual patch aims to solve the root cause.
>
> This is a good workaround. Ideally, we would resolve why this
> happens in the first place.
>
> At a glance, we have the CPUs consuming
> &apcs_glb APCS_ALIAS0_CORE_CLK
>
> which takes XO/GPLL0/A53PLL as parents.
>
> GPLL0 is a child of GPLL0_MAIN, so this should never be gated in
> practice. devlink and probe deferrals should make sure you always
> get a valid clock handle for the cpufreq driver..
Yes, the cpufreq driver gets a valid clock handle. However the hang happens
early, when the 'apcs_alias0_core' clock is not registered yet. So CCF does not
know that the clock (hence the CPU) is a consumer of GPLL0.
The reason behind the late registration of the 'apcs_alias0_core' clock is that
probing of the 'mailbox@b111000' device is deferred probably because it requires
the '&a53pll' and the '&gcc GPLL0' clocks. This can be easily seen by enabling
debug in 'drivers/base/dd.c':
...[ 0.627289] platform b111000.mailbox: bus: 'platform':
__driver_probe_device: matched device with driver qcom_apcs_ipc
[ 0.627535] platform b111000.mailbox: Added to deferred list
...
[ 0.967199] platform 9b000.clock-controller: bus: 'platform':
__driver_probe_device: matched device with driver ipq_cmn_pll
[ 0.974373] platform 9b000.clock-controller: bus: 'platform': really_probe:
probing driver ipq_cmn_pll with device
...
### without the patch, the hang happens here ###...
[ 2.272775] platform b111000.mailbox: Retrying from deferred list
[ 2.280683] platform b111000.mailbox: bus: 'platform': __driver_probe_device:
matched device with driver qcom_apcs_ipc
[ 2.286054] platform b111000.mailbox: bus: 'platform': really_probe: probing
driver qcom_apcs_ipc with device
[ 2.301354] platform qcom,apss-ipq6018-clk.0.auto: bus: 'platform':
__driver_probe_device: matched device with driver qcom,apss-ipq6018-clk
[ 2.306621] platform qcom,apss-ipq6018-clk.0.auto: bus: 'platform':
really_probe: probing driver qcom,apss-ipq6018-clk with device
[ 2.323267] qcom,apss-ipq6018-clk qcom,apss-ipq6018-clk.0.auto: driver:
'qcom,apss-ipq6018-clk': driver_bound: bound to device
[ 2.332307] qcom,apss-ipq6018-clk qcom,apss-ipq6018-clk.0.auto: bus:
'platform': really_probe: bound device to driver qcom,apss-ipq6018-clk
[ 2.342573] qcom_apcs_ipc b111000.mailbox: driver: 'qcom_apcs_ipc':
driver_bound: bound to device
[ 2.355998] qcom_apcs_ipc b111000.mailbox: bus: 'platform': really_probe:
bound device to driver qcom_apcs_ipc
Now that the 'apcs_alias0_core' clock is registered, the cpufreq driver can
switch the clock's parent from GPLL0 to A53PLL:
[ 2.427166] platform cpufreq-dt: Retrying from deferred list
[ 2.437131] platform cpufreq-dt: bus: 'platform': __driver_probe_device:
matched device with driver cpufreq-dt
[ 2.442776] platform cpufreq-dt: bus: 'platform': really_probe: probing
driver cpufreq-dt with device
[ 2.461285] cpufreq: cpufreq_policy_online: CPU0: Running at unlisted initial
frequency: 799999 kHz, changing to: 800000 kHz
[ 2.479751] cpufreq-dt cpufreq-dt: driver: 'cpufreq-dt': driver_bound: bound
to device
[ 2.481435] cpufreq-dt cpufreq-dt: bus: 'platform': really_probe: bound
device to driver cpufreq-dt
I have not found a better solution which prevents 'gpll0_main' from being
disabled until the 'apcs_alias0_core' clock gets registered.
On the vast majority of the boards, one or more consumers of the PLL are always
active during runtime, so in practice it always runs anyway.
Regards,
Gabor