From 47311aafb92e00c79de28a0bd44fc9bd58d59fee Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Tue, 12 Oct 2021 21:01:32 +0400 Subject: [PATCH 1/4] clk-baikal: initialize/register early enough Currently clk-baikal gets initialized very late (after staring secondary CPUs, PCI-e init, etc). This is wrong: the clock driver should be initialized very early. Use CLK_OF_DECLARE_DRIVER to ensure clk-baikal initializes early enough (like a clock driver should). --- drivers/clk/baikal/clk-baikal.c | 41 ++++++++------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c index 5a109e5cdd07..126e7a6319ef 100644 --- a/drivers/clk/baikal/clk-baikal.c +++ b/drivers/clk/baikal/clk-baikal.c @@ -223,13 +223,12 @@ const struct clk_ops be_clk_pll_ops = { .round_rate = baikal_clk_round_rate, }; -static int baikal_clk_probe(struct platform_device *pdev) +static int __init baikal_clk_probe(struct device_node *node) { struct clk_init_data init; struct clk_init_data *init_ch; struct baikal_clk_cmu *cmu; struct baikal_clk_cmu **cmu_ch; - struct device_node *node = pdev->dev.of_node; struct clk *clk; struct clk_onecell_data *clk_ch; @@ -357,38 +356,16 @@ static int baikal_clk_probe(struct platform_device *pdev) clk_prepare_enable(clk_ch->clks[index]); i++; } - return of_clk_add_provider(pdev->dev.of_node, - of_clk_src_onecell_get, clk_ch); + return of_clk_add_provider(node, of_clk_src_onecell_get, clk_ch); } - return of_clk_add_provider(pdev->dev.of_node, - of_clk_src_simple_get, clk); + return of_clk_add_provider(node, of_clk_src_simple_get, clk); } -static int baikal_clk_remove(struct platform_device *pdev) -{ - of_clk_del_provider(pdev->dev.of_node); - - return 0; +static void __init baikal_clk_init(struct device_node *np) { + int err = baikal_clk_probe(np); + if (err) { + panic("%s: failed to initialize clock: %d\n", __func__, err); + } } - -static const struct of_device_id baikal_clk_of_match[] = { - {.compatible = "baikal,cmu"}, - { /* sentinel */ } -}; - -static struct platform_driver baikal_cmu_driver = { - .probe = baikal_clk_probe, - .remove = baikal_clk_remove, - .driver = { - .name = "baikal-cmu", - .of_match_table = baikal_clk_of_match, - }, -}; - -module_platform_driver(baikal_cmu_driver); - -MODULE_DESCRIPTION("Baikal-M clock driver"); -MODULE_AUTHOR("Ekaterina Skachko "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:baikal-cmu"); +CLK_OF_DECLARE_DRIVER(baikal_cmu, "baikal,cmu", baikal_clk_init); From 1dca8033aaee97c309dc71921983378b293ea312 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Tue, 12 Oct 2021 21:02:06 +0400 Subject: [PATCH 2/4] clk-baikal: made be_clk_pll_ops static --- drivers/clk/baikal/clk-baikal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c index 126e7a6319ef..93660765d6d7 100644 --- a/drivers/clk/baikal/clk-baikal.c +++ b/drivers/clk/baikal/clk-baikal.c @@ -214,7 +214,7 @@ static long baikal_clk_round_rate(struct clk_hw *hw, unsigned long rate, return res.a0; } -const struct clk_ops be_clk_pll_ops = { +static const struct clk_ops be_clk_pll_ops = { .enable = baikal_clk_enable, .disable = baikal_clk_disable, .is_enabled = baikal_clk_is_enabled, From 2183e57ace1fd6c2ccce5388559b82f318c74558 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Wed, 13 Oct 2021 13:16:04 +0400 Subject: [PATCH 3/4] clk-baikal: fixed memory allocation in _probe Allocate (and zero initialize) memory for baikal_clk_cmu structure (instead of a *pointer* to that structure). --- drivers/clk/baikal/clk-baikal.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c index 93660765d6d7..8ed9cac6ed7d 100644 --- a/drivers/clk/baikal/clk-baikal.c +++ b/drivers/clk/baikal/clk-baikal.c @@ -240,10 +240,9 @@ static int __init baikal_clk_probe(struct device_node *node) const char *clk_ch_name; const char *parent_name; - cmu = kmalloc(sizeof(struct baikal_clk_cmu *), GFP_KERNEL); + cmu = kzalloc(sizeof(*cmu), GFP_KERNEL); if (!cmu) { pr_err("%s: could not allocate CMU clk\n", __func__); - kfree(cmu); return -ENOMEM; } From efcaedf6324bc413d5e8cda0248f14ef6530b883 Mon Sep 17 00:00:00 2001 From: Alexey Sheplyakov Date: Wed, 13 Oct 2021 13:19:40 +0400 Subject: [PATCH 4/4] clk-baikal: check for memory allocation result Avoid NULL dereference on (very unlikely) memory allocation failure. Note: this patch misses proper cleanup, however the thing is going to panic() on clock initialization failure anyway. --- drivers/clk/baikal/clk-baikal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/clk/baikal/clk-baikal.c b/drivers/clk/baikal/clk-baikal.c index 8ed9cac6ed7d..8ee6e859233f 100644 --- a/drivers/clk/baikal/clk-baikal.c +++ b/drivers/clk/baikal/clk-baikal.c @@ -329,8 +329,12 @@ static int __init baikal_clk_probe(struct device_node *node) init_ch[i].ops = &be_clk_pll_ops; init_ch[i].flags = CLK_IGNORE_UNUSED; - cmu_ch[index] = kmalloc(sizeof(struct baikal_clk_cmu), + cmu_ch[index] = kzalloc(sizeof(struct baikal_clk_cmu), GFP_KERNEL); + if (!cmu_ch[index]) { + pr_err("%s: could not allocate baikal_clk_cmu structure\n", __func__); + return -ENOMEM; + } cmu_ch[index]->name = clk_ch_name; cmu_ch[index]->cmu_id = index; cmu_ch[index]->parent = cmu->cmu_id;