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:
parent
560d31410c
commit
e4cd5227f0
1 changed files with 16 additions and 10 deletions
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue