aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorMarcin Wojtas <mw@semihalf.com>2016-09-21 05:05:58 -0400
committerStephen Boyd <sboyd@codeaurora.org>2016-09-22 19:05:07 -0400
commita0245eb76ad0f652f1eb14f48ca2d3c4391aef66 (patch)
tree6b271a6619b76230cc6c5e1de5eb167173e059b0 /drivers/clk
parentad715b268a501533ecb2e891a624841d1bb5137c (diff)
clk: mvebu: dynamically allocate resources in Armada CP110 system controller
Original commit, which added support for Armada CP110 system controller used global variables for storing all clock information. It worked fine for Armada 7k SoC, with single CP110 block. After dual-CP110 Armada 8k was introduced, the data got overwritten and corrupted. This patch fixes the issue by allocating resources dynamically in the driver probe and storing it as platform drvdata. Fixes: d3da3eaef7f4 ("clk: mvebu: new driver for Armada CP110 system ...") Signed-off-by: Marcin Wojtas <mw@semihalf.com> Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> CC: <stable@vger.kernel.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/mvebu/cp110-system-controller.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
index 59fe76e47275..f2303da7fda7 100644
--- a/drivers/clk/mvebu/cp110-system-controller.c
+++ b/drivers/clk/mvebu/cp110-system-controller.c
@@ -81,13 +81,6 @@ enum {
81#define CP110_GATE_EIP150 25 81#define CP110_GATE_EIP150 25
82#define CP110_GATE_EIP197 26 82#define CP110_GATE_EIP197 26
83 83
84static struct clk *cp110_clks[CP110_CLK_NUM];
85
86static struct clk_onecell_data cp110_clk_data = {
87 .clks = cp110_clks,
88 .clk_num = CP110_CLK_NUM,
89};
90
91struct cp110_gate_clk { 84struct cp110_gate_clk {
92 struct clk_hw hw; 85 struct clk_hw hw;
93 struct regmap *regmap; 86 struct regmap *regmap;
@@ -196,7 +189,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
196 struct regmap *regmap; 189 struct regmap *regmap;
197 struct device_node *np = pdev->dev.of_node; 190 struct device_node *np = pdev->dev.of_node;
198 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name; 191 const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
199 struct clk *clk; 192 struct clk_onecell_data *cp110_clk_data;
193 struct clk *clk, **cp110_clks;
200 u32 nand_clk_ctrl; 194 u32 nand_clk_ctrl;
201 int i, ret; 195 int i, ret;
202 196
@@ -209,6 +203,20 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
209 if (ret) 203 if (ret)
210 return ret; 204 return ret;
211 205
206 cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *),
207 CP110_CLK_NUM, GFP_KERNEL);
208 if (!cp110_clks)
209 return -ENOMEM;
210
211 cp110_clk_data = devm_kzalloc(&pdev->dev,
212 sizeof(*cp110_clk_data),
213 GFP_KERNEL);
214 if (!cp110_clk_data)
215 return -ENOMEM;
216
217 cp110_clk_data->clks = cp110_clks;
218 cp110_clk_data->clk_num = CP110_CLK_NUM;
219
212 /* Register the APLL which is the root of the clk tree */ 220 /* Register the APLL which is the root of the clk tree */
213 of_property_read_string_index(np, "core-clock-output-names", 221 of_property_read_string_index(np, "core-clock-output-names",
214 CP110_CORE_APLL, &apll_name); 222 CP110_CORE_APLL, &apll_name);
@@ -336,10 +344,12 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
336 cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk; 344 cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
337 } 345 }
338 346
339 ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data); 347 ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data);
340 if (ret) 348 if (ret)
341 goto fail_clk_add; 349 goto fail_clk_add;
342 350
351 platform_set_drvdata(pdev, cp110_clks);
352
343 return 0; 353 return 0;
344 354
345fail_clk_add: 355fail_clk_add:
@@ -366,6 +376,7 @@ fail0:
366 376
367static int cp110_syscon_clk_remove(struct platform_device *pdev) 377static int cp110_syscon_clk_remove(struct platform_device *pdev)
368{ 378{
379 struct clk **cp110_clks = platform_get_drvdata(pdev);
369 int i; 380 int i;
370 381
371 of_clk_del_provider(pdev->dev.of_node); 382 of_clk_del_provider(pdev->dev.of_node);