aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartosz Golaszewski <bgolaszewski@baylibre.com>2016-12-07 10:22:18 -0500
committerSekhar Nori <nsekhar@ti.com>2017-01-02 04:32:51 -0500
commitb40881738f098e1be5c32e89c2691b688fc00875 (patch)
treec69b1eda11d056fe71cea569a95ba0c132cd12fd
parent0a5011673af0fe995a3e448d3479a027a4082ddf (diff)
ARM: davinci: da850: fix da850_set_pll0rate()
This function is confusing - its second argument is an index to the freq table, not the requested clock rate in Hz, but it's used as the set_rate callback for the pll0 clock. It leads to an oops when the caller doesn't know the internals and passes the rate in Hz as argument instead of the cpufreq index since this argument isn't bounds checked either. Fix it by iterating over the array of supported frequencies and selecting a one that matches or returning -EINVAL for unsupported rates. Also: update the davinci cpufreq driver. It's the only user of this clock and currently it passes the cpufreq table index to clk_set_rate(), which is confusing. Make it pass the requested clock rate in Hz. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> [nsekhar@ti.com: commit headline update] Signed-off-by: Sekhar Nori <nsekhar@ti.com>
-rw-r--r--arch/arm/mach-davinci/da850.c22
-rw-r--r--drivers/cpufreq/davinci-cpufreq.c2
2 files changed, 19 insertions, 5 deletions
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 063560d75b22..07d36fc1e33c 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1174,14 +1174,28 @@ static int da850_set_armrate(struct clk *clk, unsigned long index)
1174 return clk_set_rate(pllclk, index); 1174 return clk_set_rate(pllclk, index);
1175} 1175}
1176 1176
1177static int da850_set_pll0rate(struct clk *clk, unsigned long index) 1177static int da850_set_pll0rate(struct clk *clk, unsigned long rate)
1178{ 1178{
1179 unsigned int prediv, mult, postdiv;
1180 struct da850_opp *opp;
1181 struct pll_data *pll = clk->pll_data; 1179 struct pll_data *pll = clk->pll_data;
1180 struct cpufreq_frequency_table *freq;
1181 unsigned int prediv, mult, postdiv;
1182 struct da850_opp *opp = NULL;
1182 int ret; 1183 int ret;
1183 1184
1184 opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data; 1185 rate /= 1000;
1186
1187 for (freq = da850_freq_table;
1188 freq->frequency != CPUFREQ_TABLE_END; freq++) {
1189 /* rate is in Hz, freq->frequency is in KHz */
1190 if (freq->frequency == rate) {
1191 opp = (struct da850_opp *)freq->driver_data;
1192 break;
1193 }
1194 }
1195
1196 if (!opp)
1197 return -EINVAL;
1198
1185 prediv = opp->prediv; 1199 prediv = opp->prediv;
1186 mult = opp->mult; 1200 mult = opp->mult;
1187 postdiv = opp->postdiv; 1201 postdiv = opp->postdiv;
diff --git a/drivers/cpufreq/davinci-cpufreq.c b/drivers/cpufreq/davinci-cpufreq.c
index b95a872800ec..d54a27c99121 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -55,7 +55,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
55 return ret; 55 return ret;
56 } 56 }
57 57
58 ret = clk_set_rate(armclk, idx); 58 ret = clk_set_rate(armclk, new_freq * 1000);
59 if (ret) 59 if (ret)
60 return ret; 60 return ret;
61 61