Re: [Letux-kernel] [PATCH] i2c: jz4780: Cache clock rate at probe to prevent CCF prepare_lock deadlock
From: H. Nikolaus Schaller
Date: Thu Jul 16 2026 - 12:37:57 EST
Hi Andi,
> Am 16.07.2026 um 17:08 schrieb Andi Shyti <andi.shyti@xxxxxxxxxx>:
>
> Nikolaus,
>
>> Therefore I consider this as a fundamental design flaw which is solved
>> by this patch.
>
> I'm not arguing the patch here. I haven't even mentioned a single
> line from the code. I made a simple question and you keep
Sorry, but I did not read this as a question but an argument against the patch itself:
"I don't think caching the clock rate once at probe is safe."
This can be read as a "nack" and request to fundamentally change the code. Therefore,
I asked for suggestions how to solve differently.
> If the commit message is leaving room for questions then you need
> to make your commit message clearer.
It took me long to understand your misunderstanding, and now I believe I have found it.
It is because there are two clocks involved which can be mixed up.
So would you be more happy with:
[PATCH v2] i2c: jz4780: Cache host clock rate at probe to prevent CCF prepare_lock deadlock
Fix a severe AB/BA deadlock between the Common Clock Framework (CCF)
and the I2C adapter lock, which triggers when an I2C-controlled clock
generator client (like the Si5351) is registered or modified under the CCF.
During an i2c client clock (generator) frequency change, the CCF acquires its global
'prepare_lock' mutex and calls i2c_transfer() to update the client's chip registers,
stalling for the adapter's I2C bus lock.
Concurrently, an independent, parallel transfer on the same bus (e.g., a GPIO
expander handling LEDs) can hold the I2C adapter lock. Inside this parallel
transfer path, jz4780_i2c_set_speed() calls clk_get_rate() on the host
controller's input clock to calculate bus timings. This call attempts to acquire
the blocked CCF 'prepare_lock', creating a circular dependency that freezes
the system.
The jz4780 host controller clock itself is static and never changes at runtime.
However, calling clk_get_rate() inside the active transfer path introduces
an unnecessary dependency on the CCF internal locks.
Eliminate the synchronous clk_get_rate() call from the active transfer
path by caching the static host peripheral clock rate once - inside the private
jz4780_i2c structure during jz4780_i2c_probe(). Update jz4780_i2c_set_speed()
to use this cached value, safely decoupling active I2C transactions from the
CCF internal locks without any risk of stale timings.
BR and thanks,
Nikolaus