mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 06:24:53 +08:00
8cd9c39dce
The clk_rate_request structure is used internally as an argument for the clk_core_determine_round_nolock() and clk_core_round_rate_nolock(). In both cases, the clk_core_init_rate_req() function is used to initialize the clk_rate_request structure. However, the expectation on who gets to call that function is inconsistent between those two functions. Indeed, clk_core_determine_round_nolock() will assume the structure is properly initialized and will just use it. On the other hand, clk_core_round_rate_nolock() will call clk_core_init_rate_req() itself, expecting the caller to have filled only a minimal set of parameters (rate, min_rate and max_rate). If we ignore the calling convention inconsistency, this leads to a second inconsistency for drivers: * If they get called by the framework through clk_core_round_rate_nolock(), the rate, min_rate and max_rate fields will be filled by the caller, and the best_parent_rate and best_parent_hw fields will get filled by clk_core_init_rate_req(). * If they get called by a driver through __clk_determine_rate (and thus clk_core_round_rate_nolock), only best_parent_rate and best_parent_hw are being explicitly set by the framework. Even though we can reasonably expect rate to be set, only one of the 6 in-tree users explicitly set min_rate and max_rate. * If they get called by the framework through clk_core_determine_round_nolock(), then we have two callpaths. Either it will be called by clk_core_round_rate_nolock() itself, or it will be called by clk_calc_new_rates(), which will properly initialize rate, min_rate, max_rate itself, and best_parent_rate and best_parent_hw through clk_core_init_rate_req(). Even though the first and third case seems equivalent, they aren't when the clock has CLK_SET_RATE_PARENT. Indeed, in such a case clk_core_round_rate_nolock() will call itself on the current parent clock with the same clk_rate_request structure. The clk_core_init_rate_req() function will then be called on the parent clock, with the child clk_rate_request pointer and will fill the best_parent_rate and best_parent_hw fields with the parent context. When the whole recursion stops and the call returns, the initial caller will end up with a clk_rate_request structure with some information of the child clock (rate, min_rate, max_rate) and some others of the last clock up the tree whose child had CLK_SET_RATE_PARENT (best_parent_hw, best_parent_rate). In the most common case, best_parent_rate is going to be equal on all the parent clocks so it's not a big deal. However, best_parent_hw is going to point to a clock that never has been a valid parent for that clock which is definitely confusing. In order to fix the calling inconsistency, let's move the clk_core_init_rate_req() calls to the callers, which will also help a bit with the clk_core_round_rate_nolock() recursion. Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com> # imx8mp Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> # exynos4210, meson g12b Signed-off-by: Maxime Ripard <maxime@cerno.tech> Link: https://lore.kernel.org/r/20220816112530.1837489-16-maxime@cerno.tech Tested-by: Linux Kernel Functional Testing <lkft@linaro.org> Tested-by: Naresh Kamboju <naresh.kamboju@linaro.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org> |
||
---|---|---|
.. | ||
actions | ||
analogbits | ||
at91 | ||
axis | ||
axs10x | ||
baikal-t1 | ||
bcm | ||
berlin | ||
davinci | ||
hisilicon | ||
imgtec | ||
imx | ||
ingenic | ||
keystone | ||
loongson1 | ||
mediatek | ||
meson | ||
microchip | ||
mmp | ||
mstar | ||
mvebu | ||
mxs | ||
nxp | ||
pistachio | ||
pxa | ||
qcom | ||
ralink | ||
renesas | ||
rockchip | ||
samsung | ||
sifive | ||
socfpga | ||
spear | ||
sprd | ||
st | ||
starfive | ||
stm32 | ||
sunxi | ||
sunxi-ng | ||
tegra | ||
ti | ||
uniphier | ||
ux500 | ||
versatile | ||
visconti | ||
x86 | ||
xilinx | ||
zynq | ||
zynqmp | ||
.kunitconfig | ||
clk_test.c | ||
clk-apple-nco.c | ||
clk-asm9260.c | ||
clk-aspeed.c | ||
clk-aspeed.h | ||
clk-ast2600.c | ||
clk-axi-clkgen.c | ||
clk-axm5516.c | ||
clk-bd718x7.c | ||
clk-bm1880.c | ||
clk-bulk.c | ||
clk-cdce706.c | ||
clk-cdce925.c | ||
clk-clps711x.c | ||
clk-composite.c | ||
clk-conf.c | ||
clk-cs2000-cp.c | ||
clk-devres.c | ||
clk-divider.c | ||
clk-en7523.c | ||
clk-fixed-factor.c | ||
clk-fixed-mmio.c | ||
clk-fixed-rate.c | ||
clk-fractional-divider.c | ||
clk-fractional-divider.h | ||
clk-fsl-flexspi.c | ||
clk-fsl-sai.c | ||
clk-gate_test.c | ||
clk-gate.c | ||
clk-gemini.c | ||
clk-gpio.c | ||
clk-hi655x.c | ||
clk-highbank.c | ||
clk-hsdk-pll.c | ||
clk-k210.c | ||
clk-lan966x.c | ||
clk-lmk04832.c | ||
clk-lochnagar.c | ||
clk-max9485.c | ||
clk-max77686.c | ||
clk-milbeaut.c | ||
clk-moxart.c | ||
clk-multiplier.c | ||
clk-mux.c | ||
clk-nomadik.c | ||
clk-npcm7xx.c | ||
clk-nspire.c | ||
clk-oxnas.c | ||
clk-palmas.c | ||
clk-plldig.c | ||
clk-pwm.c | ||
clk-qoriq.c | ||
clk-renesas-pcie.c | ||
clk-rk808.c | ||
clk-s2mps11.c | ||
clk-scmi.c | ||
clk-scpi.c | ||
clk-si514.c | ||
clk-si544.c | ||
clk-si570.c | ||
clk-si5341.c | ||
clk-si5351.c | ||
clk-si5351.h | ||
clk-sparx5.c | ||
clk-stm32f4.c | ||
clk-stm32h7.c | ||
clk-stm32mp1.c | ||
clk-tps68470.c | ||
clk-twl6040.c | ||
clk-versaclock5.c | ||
clk-vt8500.c | ||
clk-wm831x.c | ||
clk-xgene.c | ||
clk.c | ||
clk.h | ||
clkdev.c | ||
Kconfig | ||
Makefile |