Re: [Letux-kernel] [PATCH] i2c: jz4780: Cache clock rate at probe to prevent CCF prepare_lock deadlock

"H. Nikolaus Schaller" <[email protected]> Thu, 16 Jul 2026 17:46:44 +0200
Newsgroups org.kernel.vger.linux-mips,org.kernel.vger.linux-i2c,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
Hi Andi,

> Am 16.07.2026 um 17:08 schrieb Andi Shyti <[email protected]>:
> 
> 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