aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk
diff options
context:
space:
mode:
authorValentine Barshak <valentine.barshak@cogentembedded.com>2013-12-28 07:09:09 -0500
committerMike Turquette <mturquette@linaro.org>2014-01-14 14:35:57 -0500
commit209f4fedcfdeeecfc9e87c045990230cc2162169 (patch)
treead19af7b435d79c4983522fb6a5c7c3079ce54e2 /drivers/clk
parent6413b090dedd8da4753453d25668098e5bc1f4e4 (diff)
clk: shmobile: Fix MSTP clock array initialization
The clks member of the clk_onecell_data structure should point to a valid clk array (no NULL entries allowed), and the clk_num should be equal to the number of elements in the clks array. The MSTP driver fails to satisfy the above conditions. The clks array may contain NULL entries if not all clock-indices are initialized in the device tree. Thus, if the clock indices are interleaved we end up with NULL pointers in-between. The other problem is the driver uses maximum clock index as the number of clocks, which is incorrect (less than the actual number of clocks by 1). Fix the first issue by pre-setting the whole clks array with ERR_PTR(-ENOENT) pointers instead of zeros; and use maximum clkidx + 1 as the number of clocks to fix the other one. This should make of_clk_src_onecell_get() return the following: * valid clk pointers for all clocks registered; * ERR_PTR(-EINVAL) if (idx >= clk_data->clk_num); * ERR_PTR(-ENOENT) if the clock at the selected index was not initialized in the device tree (and was not registered). Changes in V2: * removed brackets from the one-line for loop Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com> Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Ben Dooks <ben.dooks@codethink.co.uk> Signed-off-by: Mike Turquette <mturquette@linaro.org>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/shmobile/clk-mstp.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/clk/shmobile/clk-mstp.c b/drivers/clk/shmobile/clk-mstp.c
index be7d0174cbfc..42d5912b1d25 100644
--- a/drivers/clk/shmobile/clk-mstp.c
+++ b/drivers/clk/shmobile/clk-mstp.c
@@ -160,7 +160,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
160 unsigned int i; 160 unsigned int i;
161 161
162 group = kzalloc(sizeof(*group), GFP_KERNEL); 162 group = kzalloc(sizeof(*group), GFP_KERNEL);
163 clks = kzalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL); 163 clks = kmalloc(MSTP_MAX_CLOCKS * sizeof(*clks), GFP_KERNEL);
164 if (group == NULL || clks == NULL) { 164 if (group == NULL || clks == NULL) {
165 kfree(group); 165 kfree(group);
166 kfree(clks); 166 kfree(clks);
@@ -181,6 +181,9 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
181 return; 181 return;
182 } 182 }
183 183
184 for (i = 0; i < MSTP_MAX_CLOCKS; ++i)
185 clks[i] = ERR_PTR(-ENOENT);
186
184 for (i = 0; i < MSTP_MAX_CLOCKS; ++i) { 187 for (i = 0; i < MSTP_MAX_CLOCKS; ++i) {
185 const char *parent_name; 188 const char *parent_name;
186 const char *name; 189 const char *name;
@@ -208,7 +211,8 @@ static void __init cpg_mstp_clocks_init(struct device_node *np)
208 clks[clkidx] = cpg_mstp_clock_register(name, parent_name, 211 clks[clkidx] = cpg_mstp_clock_register(name, parent_name,
209 clkidx, group); 212 clkidx, group);
210 if (!IS_ERR(clks[clkidx])) { 213 if (!IS_ERR(clks[clkidx])) {
211 group->data.clk_num = max(group->data.clk_num, clkidx); 214 group->data.clk_num = max(group->data.clk_num,
215 clkidx + 1);
212 /* 216 /*
213 * Register a clkdev to let board code retrieve the 217 * Register a clkdev to let board code retrieve the
214 * clock by name and register aliases for non-DT 218 * clock by name and register aliases for non-DT