Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: rockchip: support clocks registered late

When some clocks are registered late and some clocks are registered
early we need to make sure the late registered clocks report probe defer
until the final registration has happened.

But we do not want to keep reporting probe defer after the late
registration has happened. Also not all Rockchip SoCs have late
registered clocks and may not need to report probe defer at all.

This restructures code a bit, so that there is a new function
rockchip_clk_init_early(), which should be used for initializing the CRU
structure on SoCs making use of late initialization in addition to the
early init. These platforms should call rockchip_clk_finalize()
once all clocks have been registered.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
[added EXPORT_SYMBOL_GPL(rockchip_clk_finalize) to match the early function]
Link: https://lore.kernel.org/r/20241211165957.94922-2-sebastian.reichel@collabora.com
Signed-off-by: Heiko Stuebner <heiko@sntech.de>

authored by

Sebastian Reichel and committed by
Heiko Stuebner
9e89f02d 40384c84

+35 -4
+32 -4
drivers/clk/rockchip/clk.c
··· 359 359 return hw->clk; 360 360 } 361 361 362 - struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 363 - void __iomem *base, 364 - unsigned long nr_clks) 362 + static struct rockchip_clk_provider *rockchip_clk_init_base( 363 + struct device_node *np, void __iomem *base, 364 + unsigned long nr_clks, bool has_late_clocks) 365 365 { 366 366 struct rockchip_clk_provider *ctx; 367 367 struct clk **clk_table; 368 + struct clk *default_clk_val; 368 369 int i; 370 + 371 + default_clk_val = ERR_PTR(has_late_clocks ? -EPROBE_DEFER : -ENOENT); 369 372 370 373 ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); 371 374 if (!ctx) ··· 379 376 goto err_free; 380 377 381 378 for (i = 0; i < nr_clks; ++i) 382 - clk_table[i] = ERR_PTR(-ENOENT); 379 + clk_table[i] = default_clk_val; 383 380 384 381 ctx->reg_base = base; 385 382 ctx->clk_data.clks = clk_table; ··· 396 393 kfree(ctx); 397 394 return ERR_PTR(-ENOMEM); 398 395 } 396 + 397 + struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 398 + void __iomem *base, 399 + unsigned long nr_clks) 400 + { 401 + return rockchip_clk_init_base(np, base, nr_clks, false); 402 + } 399 403 EXPORT_SYMBOL_GPL(rockchip_clk_init); 404 + 405 + struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, 406 + void __iomem *base, 407 + unsigned long nr_clks) 408 + { 409 + return rockchip_clk_init_base(np, base, nr_clks, true); 410 + } 411 + EXPORT_SYMBOL_GPL(rockchip_clk_init_early); 412 + 413 + void rockchip_clk_finalize(struct rockchip_clk_provider *ctx) 414 + { 415 + int i; 416 + 417 + for (i = 0; i < ctx->clk_data.clk_num; ++i) 418 + if (ctx->clk_data.clks[i] == ERR_PTR(-EPROBE_DEFER)) 419 + ctx->clk_data.clks[i] = ERR_PTR(-ENOENT); 420 + } 421 + EXPORT_SYMBOL_GPL(rockchip_clk_finalize); 400 422 401 423 void rockchip_clk_of_add_provider(struct device_node *np, 402 424 struct rockchip_clk_provider *ctx)
+3
drivers/clk/rockchip/clk.h
··· 1024 1024 1025 1025 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 1026 1026 void __iomem *base, unsigned long nr_clks); 1027 + struct rockchip_clk_provider *rockchip_clk_init_early(struct device_node *np, 1028 + void __iomem *base, unsigned long nr_clks); 1029 + void rockchip_clk_finalize(struct rockchip_clk_provider *ctx); 1027 1030 void rockchip_clk_of_add_provider(struct device_node *np, 1028 1031 struct rockchip_clk_provider *ctx); 1029 1032 unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list,