clk_hw.init and -EPROBE_DEFER / driver re-load
From: Martin Blumenstingl
Date: Mon Apr 27 2020 - 15:57:48 EST
Hello Stephen et al.
I am working on a driver for the "SDHC" controller on older Amlogic Meson SoCs.
This has some clock controller bits built into.
Using CCF for the whole rate management makes things a lot easier, so
I decided to use that instead of poking register bits manually.
The code can be seen here: [0] - but don't take it too seriously
because I have to move some of that in the next patch revision.
I solved an "interesting" problem where I'm not sure if it works as
intended (which is what I assumed) or if there's an actual problem (as
suggested by Jerome).
The flow in the driver is basically:
(the clk_hws are defined as "static" variables inside the driver)
1) fetch related OF properties
2) initialize and register the built-in (into the MMC controller
driver) clock controller part
3) initialize the MMC controller
Step 3) can fail for example because one of the regulators is not ready.
In this case I'm de-registering the clock controller part again.
Finally the driver returns -EPROBE_DEFER
(so far everything is working fine)
However, once the regulator (in this example) becomes ready the the
same flow as above is being executed.
Only this time the clock controller registration fails because
hw->init is NULL (before it had the values which I defined in the
driver).
This is due to the following line in __clk_register():
hw->init = NULL;
My way to "solve" this is to clone the clk_hws while registering the
clock controller.
Unfortunately this means that I can't easily use clk_hw references to
describe the parent/child relation between these clocks.
I'm not sure if my way of defining the clk_hws is wrong, there's a bug
in CCF, this is a new feature request or something completely
different :-)
My motivation is to understand how I should to consider this behavior
for my next version of the MMC controller patches.
Any feedback is welcome!
Thank you,
Martin
[0] https://patchwork.kernel.org/patch/11463357/