From e4cd5227f0082bf6c1a662fb46febcc23b0f9479 Mon Sep 17 00:00:00 2001 From: Odelu Kukatla Date: Thu, 3 Aug 2017 12:20:52 +0530 Subject: [PATCH] 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 --- drivers/clk/qcom/clk-cpu-osm.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c index d99e13817a29..bc8257b31912 100644 --- a/drivers/clk/qcom/clk-cpu-osm.c +++ b/drivers/clk/qcom/clk-cpu-osm.c @@ -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); } -static long clk_osm_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int clk_osm_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { int i; unsigned long rrate = 0; + unsigned long rate = req->rate; /* * If the rate passed in is 0, return the first frequency in the * FMAX table. */ - if (!rate) - return hw->init->rate_max[0]; + if (!rate) { + req->rate = hw->init->rate_max[0]; + return 0; + } for (i = 0; i < hw->init->num_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, rrate, hw->init->rate_max[i]); - return rrate; + return 0; } 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); 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); return -EINVAL; } /* Convert rate to table index */ index = clk_osm_search_table(cpuclk->osm_table, - cpuclk->num_entries, r_rate); + cpuclk->num_entries, req.rate); if (index < 0) { pr_err("cannot set cluster %u to %lu\n", 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 = { .enable = clk_osm_enable, .set_rate = clk_osm_set_rate, - .round_rate = clk_osm_round_rate, + .determine_rate = clk_osm_determine_rate, .list_rate = clk_osm_list_rate, .recalc_rate = clk_osm_recalc_rate, .debug_init = clk_debug_measure_add,