clk: qcom: osm: Add determine_rate ops for OSM CPU clock driver

Clock rates are stored in unsigned long field, but round_rate
ops returns a long value which is causing to long overflow if
the CPU clock rate exceeds 2GHz, so define the determine_rate ops.

Change-Id: I2c48dc51bdf6be260fb4697012d08237cbba3f21
Signed-off-by: Odelu Kukatla <okukatla@codeaurora.org>
This commit is contained in:
Odelu Kukatla 2017-08-03 12:20:52 +05:30
parent 560d31410c
commit e4cd5227f0

View file

@ -622,18 +622,21 @@ static inline bool is_better_rate(unsigned long req, unsigned long best,
return (req <= new && new < best) || (best < req && best < new); return (req <= new && new < best) || (best < req && best < new);
} }
static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate, static int clk_osm_determine_rate(struct clk_hw *hw,
unsigned long *parent_rate) struct clk_rate_request *req)
{ {
int i; int i;
unsigned long rrate = 0; unsigned long rrate = 0;
unsigned long rate = req->rate;
/* /*
* If the rate passed in is 0, return the first frequency in the * If the rate passed in is 0, return the first frequency in the
* FMAX table. * FMAX table.
*/ */
if (!rate) if (!rate) {
return hw->init->rate_max[0]; req->rate = hw->init->rate_max[0];
return 0;
}
for (i = 0; i < hw->init->num_rate_max; i++) { for (i = 0; i < hw->init->num_rate_max; i++) {
if (is_better_rate(rate, rrate, hw->init->rate_max[i])) { if (is_better_rate(rate, rrate, hw->init->rate_max[i])) {
@ -643,10 +646,12 @@ static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate,
} }
} }
req->rate = rrate;
pr_debug("%s: rate %lu, rrate %ld, Rate max %ld\n", __func__, rate, pr_debug("%s: rate %lu, rrate %ld, Rate max %ld\n", __func__, rate,
rrate, hw->init->rate_max[i]); rrate, hw->init->rate_max[i]);
return rrate; return 0;
} }
static int clk_osm_search_table(struct osm_entry *table, int entries, long rate) static int clk_osm_search_table(struct osm_entry *table, int entries, long rate)
@ -677,18 +682,19 @@ static int clk_osm_set_rate(struct clk_hw *hw, unsigned long rate,
{ {
struct clk_osm *cpuclk = to_clk_osm(hw); struct clk_osm *cpuclk = to_clk_osm(hw);
int index = 0; int index = 0;
unsigned long r_rate; struct clk_rate_request req;
r_rate = clk_osm_round_rate(hw, rate, NULL); req.rate = rate;
clk_osm_determine_rate(hw, &req);
if (rate != r_rate) { if (rate != req.rate) {
pr_err("invalid rate requested rate=%ld\n", rate); pr_err("invalid rate requested rate=%ld\n", rate);
return -EINVAL; return -EINVAL;
} }
/* Convert rate to table index */ /* Convert rate to table index */
index = clk_osm_search_table(cpuclk->osm_table, index = clk_osm_search_table(cpuclk->osm_table,
cpuclk->num_entries, r_rate); cpuclk->num_entries, req.rate);
if (index < 0) { if (index < 0) {
pr_err("cannot set cluster %u to %lu\n", pr_err("cannot set cluster %u to %lu\n",
cpuclk->cluster_num, rate); cpuclk->cluster_num, rate);
@ -772,7 +778,7 @@ static unsigned long clk_osm_recalc_rate(struct clk_hw *hw,
static struct clk_ops clk_ops_cpu_osm = { static struct clk_ops clk_ops_cpu_osm = {
.enable = clk_osm_enable, .enable = clk_osm_enable,
.set_rate = clk_osm_set_rate, .set_rate = clk_osm_set_rate,
.round_rate = clk_osm_round_rate, .determine_rate = clk_osm_determine_rate,
.list_rate = clk_osm_list_rate, .list_rate = clk_osm_list_rate,
.recalc_rate = clk_osm_recalc_rate, .recalc_rate = clk_osm_recalc_rate,
.debug_init = clk_debug_measure_add, .debug_init = clk_debug_measure_add,