mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-05 03:35:52 -04:00
Merge tag 'clk-divider-round-rate-v6.20-v2' of https://github.com/masneyb/linux into clk-divider
Pull divider_round_rate() and friends removal series from Brian Masney:
Here's a series that lays the groundwork to rid of the deprecated APIs
divider_round_rate(), divider_round_rate_parent(), and
divider_ro_round_rate_parent() since these functions are just wrappers
for the determine_rate variant.
We need to wait for some other changes to land in Linus's tree via the
phy tree before we can actually remove these functions. We should be
able to do that during the next development cycle.
Note that when I converted some of these drivers from round_rate to
determine_rate, this was mistakenly converted to the following in some
cases:
req->rate = divider_round_rate(...)
This is invalid in the case when an error occurs since it can set the
rate to a negative value. So this series fixes those bugs and removes
the deprecated APIs all in one go.
Note that this also contains a clk-specific change to
drivers/rtc/rtc-ac100.c, and that patch carrys an Acked-by from
Alexandre.
* tag 'clk-divider-round-rate-v6.20-v2' of https://github.com/masneyb/linux:
rtc: ac100: convert from divider_round_rate() to divider_determine_rate()
clk: zynqmp: divider: convert from divider_round_rate() to divider_determine_rate()
clk: x86: cgu: convert from divider_round_rate() to divider_determine_rate()
clk: versaclock3: convert from divider_round_rate() to divider_determine_rate()
clk: stm32: stm32-core: convert from divider_round_rate_parent() to divider_determine_rate()
clk: stm32: stm32-core: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: sprd: div: convert from divider_round_rate() to divider_determine_rate()
clk: sophgo: sg2042-clkgen: convert from divider_round_rate() to divider_determine_rate()
clk: nxp: lpc32xx: convert from divider_round_rate() to divider_determine_rate()
clk: nuvoton: ma35d1-divider: convert from divider_round_rate() to divider_determine_rate()
clk: milbeaut: convert from divider_round_rate() to divider_determine_rate()
clk: milbeaut: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: loongson1: convert from divider_round_rate() to divider_determine_rate()
clk: hisilicon: clkdivider-hi6220: convert from divider_round_rate() to divider_determine_rate()
clk: bm1880: convert from divider_round_rate() to divider_determine_rate()
clk: bm1880: convert from divider_ro_round_rate() to divider_ro_determine_rate()
clk: actions: owl-divider: convert from divider_round_rate() to divider_determine_rate()
clk: actions: owl-composite: convert from owl_divider_helper_round_rate() to divider_determine_rate()
clk: sunxi-ng: convert from divider_round_rate_parent() to divider_determine_rate()
clk: sophgo: cv18xx-ip: convert from divider_round_rate() to divider_determine_rate()
This commit is contained in:
@@ -57,15 +57,10 @@ static int owl_comp_div_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct owl_composite *comp = hw_to_owl_comp(hw);
|
||||
long rate;
|
||||
struct owl_divider_hw *div = &comp->rate.div_hw;
|
||||
|
||||
rate = owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw,
|
||||
req->rate, &req->best_parent_rate);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
|
||||
req->rate = rate;
|
||||
return 0;
|
||||
return divider_determine_rate(&comp->common.hw, req, div->table,
|
||||
div->width, div->div_flags);
|
||||
}
|
||||
|
||||
static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw,
|
||||
|
||||
@@ -13,26 +13,13 @@
|
||||
|
||||
#include "owl-divider.h"
|
||||
|
||||
long owl_divider_helper_round_rate(struct owl_clk_common *common,
|
||||
const struct owl_divider_hw *div_hw,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
return divider_round_rate(&common->hw, rate, parent_rate,
|
||||
div_hw->table, div_hw->width,
|
||||
div_hw->div_flags);
|
||||
}
|
||||
|
||||
static int owl_divider_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct owl_divider *div = hw_to_owl_divider(hw);
|
||||
|
||||
req->rate = owl_divider_helper_round_rate(&div->common, &div->div_hw,
|
||||
req->rate,
|
||||
&req->best_parent_rate);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, div->div_hw.table,
|
||||
div->div_hw.width, div->div_hw.div_flags);
|
||||
}
|
||||
|
||||
unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common,
|
||||
|
||||
@@ -56,11 +56,6 @@ static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw)
|
||||
return container_of(common, struct owl_divider, common);
|
||||
}
|
||||
|
||||
long owl_divider_helper_round_rate(struct owl_clk_common *common,
|
||||
const struct owl_divider_hw *div_hw,
|
||||
unsigned long rate,
|
||||
unsigned long *parent_rate);
|
||||
|
||||
unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common,
|
||||
const struct owl_divider_hw *div_hw,
|
||||
unsigned long parent_rate);
|
||||
|
||||
@@ -621,18 +621,11 @@ static int bm1880_clk_div_determine_rate(struct clk_hw *hw,
|
||||
val = readl(reg_addr) >> div->shift;
|
||||
val &= clk_div_mask(div->width);
|
||||
|
||||
req->rate = divider_ro_round_rate(hw, req->rate,
|
||||
&req->best_parent_rate,
|
||||
div->table,
|
||||
div->width, div->flags, val);
|
||||
|
||||
return 0;
|
||||
return divider_ro_determine_rate(hw, req, div->table,
|
||||
div->width, div->flags, val);
|
||||
}
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
div->table, div->width, div->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, div->table, div->width, div->flags);
|
||||
}
|
||||
|
||||
static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -99,10 +99,7 @@ static int ls1x_divider_determine_rate(struct clk_hw *hw,
|
||||
struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw);
|
||||
const struct ls1x_clk_div_data *d = ls1x_clk->data;
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
d->table, d->width, d->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, d->table, d->width, d->flags);
|
||||
}
|
||||
|
||||
static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -398,19 +398,12 @@ static int m10v_clk_divider_determine_rate(struct clk_hw *hw,
|
||||
val = readl(divider->reg) >> divider->shift;
|
||||
val &= clk_div_mask(divider->width);
|
||||
|
||||
req->rate = divider_ro_round_rate(hw, req->rate,
|
||||
&req->best_parent_rate,
|
||||
divider->table,
|
||||
divider->width,
|
||||
divider->flags, val);
|
||||
|
||||
return 0;
|
||||
return divider_ro_determine_rate(hw, req, divider->table,
|
||||
divider->width, divider->flags,
|
||||
val);
|
||||
}
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
divider->table, divider->width, divider->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, divider->table, divider->width, divider->flags);
|
||||
}
|
||||
|
||||
static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -523,11 +523,8 @@ static int vc3_div_determine_rate(struct clk_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
div_data->table,
|
||||
div_data->width, div_data->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, div_data->table, div_data->width,
|
||||
div_data->flags);
|
||||
}
|
||||
|
||||
static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -60,10 +60,8 @@ static int hi6220_clkdiv_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw);
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, dclk->table,
|
||||
dclk->width, CLK_DIVIDER_ROUND_CLOSEST);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, dclk->table, dclk->width,
|
||||
CLK_DIVIDER_ROUND_CLOSEST);
|
||||
}
|
||||
|
||||
static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -44,11 +44,8 @@ static int ma35d1_clkdiv_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw);
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
dclk->table, dclk->width,
|
||||
CLK_DIVIDER_ROUND_CLOSEST);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, dclk->table, dclk->width,
|
||||
CLK_DIVIDER_ROUND_CLOSEST);
|
||||
}
|
||||
|
||||
static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
|
||||
|
||||
@@ -975,10 +975,8 @@ static int clk_divider_determine_rate(struct clk_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
divider->table, divider->width, divider->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, divider->table, divider->width,
|
||||
divider->flags);
|
||||
}
|
||||
|
||||
static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -152,28 +152,27 @@ static u32 div_helper_get_clockdiv(struct cv1800_clk_common *common,
|
||||
return clockdiv;
|
||||
}
|
||||
|
||||
static u32 div_helper_round_rate(struct cv1800_clk_regfield *div,
|
||||
struct clk_hw *hw, struct clk_hw *parent,
|
||||
unsigned long rate, unsigned long *prate)
|
||||
static int div_helper_determine_rate(struct cv1800_clk_regfield *div,
|
||||
struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
if (div->width == 0) {
|
||||
if (div->initval <= 0)
|
||||
return DIV_ROUND_UP_ULL(*prate, 1);
|
||||
req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, 1);
|
||||
else
|
||||
return DIV_ROUND_UP_ULL(*prate, div->initval);
|
||||
req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div->initval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return divider_round_rate_parent(hw, parent, rate, prate, NULL,
|
||||
div->width, div->flags);
|
||||
return divider_determine_rate(hw, req, NULL, div->width, div->flags);
|
||||
}
|
||||
|
||||
static long div_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
|
||||
unsigned long rate, int id, void *data)
|
||||
static int do_div_determine_rate(struct clk_rate_request *req, int id, void *data)
|
||||
{
|
||||
struct cv1800_clk_div *div = data;
|
||||
|
||||
return div_helper_round_rate(&div->div, &div->common.hw, parent,
|
||||
rate, parent_rate);
|
||||
return div_helper_determine_rate(&div->div, &div->common.hw, req);
|
||||
}
|
||||
|
||||
static bool div_is_better_rate(struct cv1800_clk_common *common,
|
||||
@@ -188,53 +187,60 @@ static bool div_is_better_rate(struct cv1800_clk_common *common,
|
||||
|
||||
static int mux_helper_determine_rate(struct cv1800_clk_common *common,
|
||||
struct clk_rate_request *req,
|
||||
long (*round)(struct clk_hw *,
|
||||
unsigned long *,
|
||||
unsigned long,
|
||||
int,
|
||||
void *),
|
||||
int (*round)(struct clk_rate_request *,
|
||||
int,
|
||||
void *),
|
||||
void *data)
|
||||
{
|
||||
unsigned long best_parent_rate = 0, best_rate = 0;
|
||||
struct clk_hw *best_parent, *hw = &common->hw;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
|
||||
unsigned long adj_parent_rate;
|
||||
struct clk_rate_request tmp_req = *req;
|
||||
|
||||
best_parent = clk_hw_get_parent(hw);
|
||||
best_parent_rate = clk_hw_get_rate(best_parent);
|
||||
tmp_req.best_parent_hw = best_parent;
|
||||
tmp_req.best_parent_rate = clk_hw_get_rate(best_parent);
|
||||
|
||||
best_rate = round(best_parent, &adj_parent_rate,
|
||||
req->rate, -1, data);
|
||||
ret = round(&tmp_req, -1, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
best_parent_rate = tmp_req.best_parent_rate;
|
||||
best_rate = tmp_req.rate;
|
||||
|
||||
goto find;
|
||||
}
|
||||
|
||||
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
|
||||
unsigned long tmp_rate, parent_rate;
|
||||
struct clk_rate_request tmp_req = *req;
|
||||
struct clk_hw *parent;
|
||||
|
||||
parent = clk_hw_get_parent_by_index(hw, i);
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
parent_rate = clk_hw_get_rate(parent);
|
||||
tmp_req.best_parent_hw = parent;
|
||||
tmp_req.best_parent_rate = clk_hw_get_rate(parent);
|
||||
|
||||
tmp_rate = round(parent, &parent_rate, req->rate, i, data);
|
||||
ret = round(&tmp_req, i, data);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
if (tmp_rate == req->rate) {
|
||||
if (tmp_req.rate == req->rate) {
|
||||
best_parent = parent;
|
||||
best_parent_rate = parent_rate;
|
||||
best_rate = tmp_rate;
|
||||
best_parent_rate = tmp_req.best_parent_rate;
|
||||
best_rate = tmp_req.rate;
|
||||
goto find;
|
||||
}
|
||||
|
||||
if (div_is_better_rate(common, req->rate,
|
||||
tmp_rate, best_rate)) {
|
||||
tmp_req.rate, best_rate)) {
|
||||
best_parent = parent;
|
||||
best_parent_rate = parent_rate;
|
||||
best_rate = tmp_rate;
|
||||
best_parent_rate = tmp_req.best_parent_rate;
|
||||
best_rate = tmp_req.rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +260,7 @@ static int div_determine_rate(struct clk_hw *hw,
|
||||
struct cv1800_clk_div *div = hw_to_cv1800_clk_div(hw);
|
||||
|
||||
return mux_helper_determine_rate(&div->common, req,
|
||||
div_round_rate, div);
|
||||
do_div_determine_rate, div);
|
||||
}
|
||||
|
||||
static unsigned long div_recalc_rate(struct clk_hw *hw,
|
||||
@@ -301,24 +307,28 @@ hw_to_cv1800_clk_bypass_div(struct clk_hw *hw)
|
||||
return container_of(div, struct cv1800_clk_bypass_div, div);
|
||||
}
|
||||
|
||||
static long bypass_div_round_rate(struct clk_hw *parent,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate, int id, void *data)
|
||||
static int do_bypass_div_determine_rate(struct clk_rate_request *req, int id,
|
||||
void *data)
|
||||
{
|
||||
struct cv1800_clk_bypass_div *div = data;
|
||||
|
||||
if (id == -1) {
|
||||
if (cv1800_clk_checkbit(&div->div.common, &div->bypass))
|
||||
return *parent_rate;
|
||||
else
|
||||
return div_round_rate(parent, parent_rate, rate,
|
||||
-1, &div->div);
|
||||
if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_div_determine_rate(req, -1, &div->div);
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
return *parent_rate;
|
||||
if (id == 0) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return div_round_rate(parent, parent_rate, rate, id - 1, &div->div);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_div_determine_rate(req, id - 1, &div->div);
|
||||
}
|
||||
|
||||
static int bypass_div_determine_rate(struct clk_hw *hw,
|
||||
@@ -327,7 +337,7 @@ static int bypass_div_determine_rate(struct clk_hw *hw,
|
||||
struct cv1800_clk_bypass_div *div = hw_to_cv1800_clk_bypass_div(hw);
|
||||
|
||||
return mux_helper_determine_rate(&div->div.common, req,
|
||||
bypass_div_round_rate, div);
|
||||
do_bypass_div_determine_rate, div);
|
||||
}
|
||||
|
||||
static unsigned long bypass_div_recalc_rate(struct clk_hw *hw,
|
||||
@@ -414,13 +424,11 @@ static int mux_is_enabled(struct clk_hw *hw)
|
||||
return cv1800_clk_checkbit(&mux->common, &mux->gate);
|
||||
}
|
||||
|
||||
static long mux_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
|
||||
unsigned long rate, int id, void *data)
|
||||
static int do_mux_determine_rate(struct clk_rate_request *req, int id, void *data)
|
||||
{
|
||||
struct cv1800_clk_mux *mux = data;
|
||||
|
||||
return div_helper_round_rate(&mux->div, &mux->common.hw, parent,
|
||||
rate, parent_rate);
|
||||
return div_helper_determine_rate(&mux->div, &mux->common.hw, req);
|
||||
}
|
||||
|
||||
static int mux_determine_rate(struct clk_hw *hw,
|
||||
@@ -429,7 +437,7 @@ static int mux_determine_rate(struct clk_hw *hw,
|
||||
struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw);
|
||||
|
||||
return mux_helper_determine_rate(&mux->common, req,
|
||||
mux_round_rate, mux);
|
||||
do_mux_determine_rate, mux);
|
||||
}
|
||||
|
||||
static unsigned long mux_recalc_rate(struct clk_hw *hw,
|
||||
@@ -512,24 +520,28 @@ hw_to_cv1800_clk_bypass_mux(struct clk_hw *hw)
|
||||
return container_of(mux, struct cv1800_clk_bypass_mux, mux);
|
||||
}
|
||||
|
||||
static long bypass_mux_round_rate(struct clk_hw *parent,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate, int id, void *data)
|
||||
static int do_bypass_mux_determine_rate(struct clk_rate_request *req, int id,
|
||||
void *data)
|
||||
{
|
||||
struct cv1800_clk_bypass_mux *mux = data;
|
||||
|
||||
if (id == -1) {
|
||||
if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass))
|
||||
return *parent_rate;
|
||||
else
|
||||
return mux_round_rate(parent, parent_rate, rate,
|
||||
-1, &mux->mux);
|
||||
if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_mux_determine_rate(req, -1, &mux->mux);
|
||||
}
|
||||
|
||||
if (id == 0)
|
||||
return *parent_rate;
|
||||
if (id == 0) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return do_mux_determine_rate(req, id - 1, &mux->mux);
|
||||
}
|
||||
|
||||
static int bypass_mux_determine_rate(struct clk_hw *hw,
|
||||
@@ -538,7 +550,7 @@ static int bypass_mux_determine_rate(struct clk_hw *hw,
|
||||
struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw);
|
||||
|
||||
return mux_helper_determine_rate(&mux->mux.common, req,
|
||||
bypass_mux_round_rate, mux);
|
||||
do_bypass_mux_determine_rate, mux);
|
||||
}
|
||||
|
||||
static unsigned long bypass_mux_recalc_rate(struct clk_hw *hw,
|
||||
@@ -639,27 +651,31 @@ static int mmux_is_enabled(struct clk_hw *hw)
|
||||
return cv1800_clk_checkbit(&mmux->common, &mmux->gate);
|
||||
}
|
||||
|
||||
static long mmux_round_rate(struct clk_hw *parent, unsigned long *parent_rate,
|
||||
unsigned long rate, int id, void *data)
|
||||
static int do_mmux_determine_rate(struct clk_rate_request *req, int id, void *data)
|
||||
{
|
||||
struct cv1800_clk_mmux *mmux = data;
|
||||
s8 div_id;
|
||||
|
||||
if (id == -1) {
|
||||
if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass))
|
||||
return *parent_rate;
|
||||
if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
id = mmux_get_parent_id(mmux);
|
||||
}
|
||||
|
||||
div_id = mmux->parent2sel[id];
|
||||
|
||||
if (div_id < 0)
|
||||
return *parent_rate;
|
||||
if (div_id < 0) {
|
||||
req->rate = req->best_parent_rate;
|
||||
|
||||
return div_helper_round_rate(&mmux->div[div_id],
|
||||
&mmux->common.hw, parent,
|
||||
rate, parent_rate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return div_helper_determine_rate(&mmux->div[div_id], &mmux->common.hw,
|
||||
req);
|
||||
}
|
||||
|
||||
static int mmux_determine_rate(struct clk_hw *hw,
|
||||
@@ -668,7 +684,7 @@ static int mmux_determine_rate(struct clk_hw *hw,
|
||||
struct cv1800_clk_mmux *mmux = hw_to_cv1800_clk_mmux(hw);
|
||||
|
||||
return mux_helper_determine_rate(&mmux->common, req,
|
||||
mmux_round_rate, mmux);
|
||||
do_mmux_determine_rate, mmux);
|
||||
}
|
||||
|
||||
static unsigned long mmux_recalc_rate(struct clk_hw *hw,
|
||||
|
||||
@@ -180,7 +180,6 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw);
|
||||
unsigned long ret_rate;
|
||||
u32 bestdiv;
|
||||
|
||||
/* if read only, just return current value */
|
||||
@@ -191,17 +190,13 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw,
|
||||
bestdiv = readl(divider->reg) >> divider->shift;
|
||||
bestdiv &= clk_div_mask(divider->width);
|
||||
}
|
||||
ret_rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv);
|
||||
} else {
|
||||
ret_rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, NULL,
|
||||
divider->width, divider->div_flags);
|
||||
req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("--> %s: divider_round_rate: val = %ld\n",
|
||||
clk_hw_get_name(hw), ret_rate);
|
||||
req->rate = ret_rate;
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, NULL, divider->width,
|
||||
divider->div_flags);
|
||||
}
|
||||
|
||||
static int sg2042_clk_divider_set_rate(struct clk_hw *hw,
|
||||
|
||||
@@ -14,11 +14,7 @@ static int sprd_div_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct sprd_div *cd = hw_to_sprd_div(hw);
|
||||
|
||||
req->rate = divider_round_rate(&cd->common.hw, req->rate,
|
||||
&req->best_parent_rate,
|
||||
NULL, cd->div.width, 0);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(&cd->common.hw, req, NULL, cd->div.width, 0);
|
||||
}
|
||||
|
||||
unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
|
||||
|
||||
@@ -369,22 +369,14 @@ static int clk_stm32_divider_determine_rate(struct clk_hw *hw,
|
||||
val = readl(div->base + divider->offset) >> divider->shift;
|
||||
val &= clk_div_mask(divider->width);
|
||||
|
||||
req->rate = divider_ro_round_rate(hw, req->rate,
|
||||
&req->best_parent_rate,
|
||||
divider->table,
|
||||
divider->width,
|
||||
divider->flags, val);
|
||||
|
||||
return 0;
|
||||
return divider_ro_determine_rate(hw, req,
|
||||
divider->table,
|
||||
divider->width,
|
||||
divider->flags, val);
|
||||
}
|
||||
|
||||
req->rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw),
|
||||
req->rate,
|
||||
&req->best_parent_rate,
|
||||
divider->table,
|
||||
divider->width, divider->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, divider->table, divider->width,
|
||||
divider->flags);
|
||||
}
|
||||
|
||||
static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw,
|
||||
@@ -441,7 +433,6 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct clk_stm32_composite *composite = to_clk_stm32_composite(hw);
|
||||
const struct stm32_div_cfg *divider;
|
||||
long rate;
|
||||
|
||||
if (composite->div_id == NO_STM32_DIV)
|
||||
return 0;
|
||||
@@ -455,24 +446,13 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw,
|
||||
val = readl(composite->base + divider->offset) >> divider->shift;
|
||||
val &= clk_div_mask(divider->width);
|
||||
|
||||
rate = divider_ro_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
divider->table, divider->width, divider->flags,
|
||||
val);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
|
||||
req->rate = rate;
|
||||
return 0;
|
||||
return divider_ro_determine_rate(hw, req, divider->table,
|
||||
divider->width, divider->flags,
|
||||
val);
|
||||
}
|
||||
|
||||
rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw),
|
||||
req->rate, &req->best_parent_rate,
|
||||
divider->table, divider->width, divider->flags);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
|
||||
req->rate = rate;
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, divider->table, divider->width,
|
||||
divider->flags);
|
||||
}
|
||||
|
||||
static u8 clk_stm32_composite_get_parent(struct clk_hw *hw)
|
||||
|
||||
@@ -10,26 +10,25 @@
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_div.h"
|
||||
|
||||
static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
|
||||
struct clk_hw *parent,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate,
|
||||
void *data)
|
||||
static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux,
|
||||
struct clk_rate_request *req,
|
||||
void *data)
|
||||
{
|
||||
struct ccu_div *cd = data;
|
||||
int ret;
|
||||
|
||||
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate *= cd->fixed_post_div;
|
||||
req->rate *= cd->fixed_post_div;
|
||||
|
||||
rate = divider_round_rate_parent(&cd->common.hw, parent,
|
||||
rate, parent_rate,
|
||||
cd->div.table, cd->div.width,
|
||||
cd->div.flags);
|
||||
ret = divider_determine_rate(&cd->common.hw, req, cd->div.table,
|
||||
cd->div.width, cd->div.flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= cd->fixed_post_div;
|
||||
req->rate /= cd->fixed_post_div;
|
||||
|
||||
return rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccu_div_disable(struct clk_hw *hw)
|
||||
@@ -82,7 +81,7 @@ static int ccu_div_determine_rate(struct clk_hw *hw,
|
||||
struct ccu_div *cd = hw_to_ccu_div(hw);
|
||||
|
||||
return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
|
||||
req, ccu_div_round_rate, cd);
|
||||
req, ccu_div_determine_rate_helper, cd);
|
||||
}
|
||||
|
||||
static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -103,11 +103,9 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw,
|
||||
return best_rate;
|
||||
}
|
||||
|
||||
static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
|
||||
struct clk_hw *hw,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate,
|
||||
void *data)
|
||||
static int ccu_mp_determine_rate_helper(struct ccu_mux_internal *mux,
|
||||
struct clk_rate_request *req,
|
||||
void *data)
|
||||
{
|
||||
struct ccu_mp *cmp = data;
|
||||
unsigned int max_m, max_p;
|
||||
@@ -115,7 +113,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
|
||||
bool shift = true;
|
||||
|
||||
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate *= cmp->fixed_post_div;
|
||||
req->rate *= cmp->fixed_post_div;
|
||||
|
||||
if (cmp->common.features & CCU_FEATURE_DUAL_DIV)
|
||||
shift = false;
|
||||
@@ -127,17 +125,19 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
|
||||
max_p = cmp->p.max ?: 1 << cmp->p.width;
|
||||
|
||||
if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) {
|
||||
rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, shift,
|
||||
&m, &p);
|
||||
req->rate = ccu_mp_find_best(req->best_parent_rate, req->rate,
|
||||
max_m, max_p, shift, &m, &p);
|
||||
} else {
|
||||
rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate,
|
||||
max_m, max_p, shift);
|
||||
req->rate = ccu_mp_find_best_with_parent_adj(req->best_parent_hw,
|
||||
&req->best_parent_rate,
|
||||
req->rate, max_m, max_p,
|
||||
shift);
|
||||
}
|
||||
|
||||
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= cmp->fixed_post_div;
|
||||
req->rate /= cmp->fixed_post_div;
|
||||
|
||||
return rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccu_mp_disable(struct clk_hw *hw)
|
||||
@@ -201,7 +201,7 @@ static int ccu_mp_determine_rate(struct clk_hw *hw,
|
||||
struct ccu_mp *cmp = hw_to_ccu_mp(hw);
|
||||
|
||||
return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux,
|
||||
req, ccu_mp_round_rate, cmp);
|
||||
req, ccu_mp_determine_rate_helper, cmp);
|
||||
}
|
||||
|
||||
static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -29,11 +29,9 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate,
|
||||
mult->mult = _mult;
|
||||
}
|
||||
|
||||
static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
|
||||
struct clk_hw *parent,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate,
|
||||
void *data)
|
||||
static int ccu_mult_determine_rate_helper(struct ccu_mux_internal *mux,
|
||||
struct clk_rate_request *req,
|
||||
void *data)
|
||||
{
|
||||
struct ccu_mult *cm = data;
|
||||
struct _ccu_mult _cm;
|
||||
@@ -45,9 +43,11 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
|
||||
else
|
||||
_cm.max = (1 << cm->mult.width) + cm->mult.offset - 1;
|
||||
|
||||
ccu_mult_find_best(*parent_rate, rate, &_cm);
|
||||
ccu_mult_find_best(req->best_parent_rate, req->rate, &_cm);
|
||||
|
||||
return *parent_rate * _cm.mult;
|
||||
req->rate = req->best_parent_rate * _cm.mult;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccu_mult_disable(struct clk_hw *hw)
|
||||
@@ -97,7 +97,7 @@ static int ccu_mult_determine_rate(struct clk_hw *hw,
|
||||
struct ccu_mult *cm = hw_to_ccu_mult(hw);
|
||||
|
||||
return ccu_mux_helper_determine_rate(&cm->common, &cm->mux,
|
||||
req, ccu_mult_round_rate, cm);
|
||||
req, ccu_mult_determine_rate_helper, cm);
|
||||
}
|
||||
|
||||
static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -79,41 +79,46 @@ static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
|
||||
int ccu_mux_helper_determine_rate(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm,
|
||||
struct clk_rate_request *req,
|
||||
unsigned long (*round)(struct ccu_mux_internal *,
|
||||
struct clk_hw *,
|
||||
unsigned long *,
|
||||
unsigned long,
|
||||
void *),
|
||||
int (*round)(struct ccu_mux_internal *,
|
||||
struct clk_rate_request *,
|
||||
void *),
|
||||
void *data)
|
||||
{
|
||||
unsigned long best_parent_rate = 0, best_rate = 0;
|
||||
struct clk_hw *best_parent, *hw = &common->hw;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
|
||||
unsigned long adj_parent_rate;
|
||||
struct clk_rate_request adj_req = *req;
|
||||
|
||||
best_parent = clk_hw_get_parent(hw);
|
||||
best_parent_rate = clk_hw_get_rate(best_parent);
|
||||
adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
|
||||
best_parent_rate);
|
||||
|
||||
best_rate = round(cm, best_parent, &adj_parent_rate,
|
||||
req->rate, data);
|
||||
adj_req.best_parent_hw = best_parent;
|
||||
adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1,
|
||||
best_parent_rate);
|
||||
|
||||
ret = round(cm, &adj_req, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
best_rate = adj_req.rate;
|
||||
|
||||
/*
|
||||
* adj_parent_rate might have been modified by our clock.
|
||||
* best_parent_rate might have been modified by our clock.
|
||||
* Unapply the pre-divider if there's one, and give
|
||||
* the actual frequency the parent needs to run at.
|
||||
*/
|
||||
best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1,
|
||||
adj_parent_rate);
|
||||
adj_req.best_parent_rate);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
|
||||
unsigned long tmp_rate, parent_rate;
|
||||
struct clk_rate_request tmp_req = *req;
|
||||
unsigned long parent_rate;
|
||||
struct clk_hw *parent;
|
||||
|
||||
parent = clk_hw_get_parent_by_index(hw, i);
|
||||
@@ -123,7 +128,12 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
|
||||
parent_rate = ccu_mux_helper_apply_prediv(common, cm, i,
|
||||
clk_hw_get_rate(parent));
|
||||
|
||||
tmp_rate = round(cm, parent, &parent_rate, req->rate, data);
|
||||
tmp_req.best_parent_hw = parent;
|
||||
tmp_req.best_parent_rate = parent_rate;
|
||||
|
||||
ret = round(cm, &tmp_req, data);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* parent_rate might have been modified by our clock.
|
||||
@@ -131,16 +141,17 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common,
|
||||
* the actual frequency the parent needs to run at.
|
||||
*/
|
||||
parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i,
|
||||
parent_rate);
|
||||
if (tmp_rate == req->rate) {
|
||||
tmp_req.best_parent_rate);
|
||||
|
||||
if (tmp_req.rate == req->rate) {
|
||||
best_parent = parent;
|
||||
best_parent_rate = parent_rate;
|
||||
best_rate = tmp_rate;
|
||||
best_rate = tmp_req.rate;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ccu_is_better_rate(common, req->rate, tmp_rate, best_rate)) {
|
||||
best_rate = tmp_rate;
|
||||
if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) {
|
||||
best_rate = tmp_req.rate;
|
||||
best_parent_rate = parent_rate;
|
||||
best_parent = parent;
|
||||
}
|
||||
|
||||
@@ -137,11 +137,9 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
|
||||
int ccu_mux_helper_determine_rate(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm,
|
||||
struct clk_rate_request *req,
|
||||
unsigned long (*round)(struct ccu_mux_internal *,
|
||||
struct clk_hw *,
|
||||
unsigned long *,
|
||||
unsigned long,
|
||||
void *),
|
||||
int (*round)(struct ccu_mux_internal *,
|
||||
struct clk_rate_request *,
|
||||
void *),
|
||||
void *data);
|
||||
u8 ccu_mux_helper_get_parent(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm);
|
||||
|
||||
@@ -162,11 +162,9 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
|
||||
return rate;
|
||||
}
|
||||
|
||||
static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
||||
struct clk_hw *parent_hw,
|
||||
unsigned long *parent_rate,
|
||||
unsigned long rate,
|
||||
void *data)
|
||||
static int ccu_nkm_determine_rate_helper(struct ccu_mux_internal *mux,
|
||||
struct clk_rate_request *req,
|
||||
void *data)
|
||||
{
|
||||
struct ccu_nkm *nkm = data;
|
||||
struct _ccu_nkm _nkm;
|
||||
@@ -179,18 +177,21 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
||||
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
|
||||
|
||||
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate *= nkm->fixed_post_div;
|
||||
req->rate *= nkm->fixed_post_div;
|
||||
|
||||
if (!clk_hw_can_set_rate_parent(&nkm->common.hw))
|
||||
rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common);
|
||||
req->rate = ccu_nkm_find_best(req->best_parent_rate, req->rate,
|
||||
&_nkm, &nkm->common);
|
||||
else
|
||||
rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, parent_hw, parent_rate, rate,
|
||||
&_nkm);
|
||||
req->rate = ccu_nkm_find_best_with_parent_adj(&nkm->common,
|
||||
req->best_parent_hw,
|
||||
&req->best_parent_rate,
|
||||
req->rate, &_nkm);
|
||||
|
||||
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||
rate /= nkm->fixed_post_div;
|
||||
req->rate /= nkm->fixed_post_div;
|
||||
|
||||
return rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccu_nkm_determine_rate(struct clk_hw *hw,
|
||||
@@ -199,7 +200,7 @@ static int ccu_nkm_determine_rate(struct clk_hw *hw,
|
||||
struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
|
||||
|
||||
return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux,
|
||||
req, ccu_nkm_round_rate, nkm);
|
||||
req, ccu_nkm_determine_rate_helper, nkm);
|
||||
}
|
||||
|
||||
static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
||||
@@ -137,10 +137,8 @@ static int lgm_clk_divider_determine_rate(struct clk_hw *hw,
|
||||
{
|
||||
struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, divider->table,
|
||||
divider->width, divider->flags);
|
||||
|
||||
return 0;
|
||||
return divider_determine_rate(hw, req, divider->table, divider->width,
|
||||
divider->flags);
|
||||
}
|
||||
|
||||
static int
|
||||
|
||||
@@ -151,8 +151,9 @@ static int zynqmp_clk_divider_determine_rate(struct clk_hw *hw,
|
||||
|
||||
width = fls(divider->max_div);
|
||||
|
||||
req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate,
|
||||
NULL, width, divider->flags);
|
||||
ret = divider_determine_rate(hw, req, NULL, width, divider->flags);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) &&
|
||||
(req->rate % req->best_parent_rate))
|
||||
|
||||
@@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw,
|
||||
AC100_CLKOUT_DIV_WIDTH);
|
||||
}
|
||||
|
||||
static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
unsigned long best_rate = 0, tmp_rate, tmp_prate;
|
||||
int i;
|
||||
|
||||
if (prate == AC100_RTC_32K_RATE)
|
||||
return divider_round_rate(hw, rate, &prate, NULL,
|
||||
AC100_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_POWER_OF_TWO);
|
||||
|
||||
for (i = 0; ac100_clkout_prediv[i].div; i++) {
|
||||
tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val);
|
||||
tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL,
|
||||
AC100_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_POWER_OF_TWO);
|
||||
|
||||
if (tmp_rate > rate)
|
||||
continue;
|
||||
if (rate - tmp_rate < best_rate - tmp_rate)
|
||||
best_rate = tmp_rate;
|
||||
}
|
||||
|
||||
return best_rate;
|
||||
}
|
||||
|
||||
static int ac100_clkout_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_hw *best_parent;
|
||||
int i, ret, num_parents = clk_hw_get_num_parents(hw);
|
||||
struct clk_hw *best_parent = NULL;
|
||||
unsigned long best = 0;
|
||||
int i, num_parents = clk_hw_get_num_parents(hw);
|
||||
|
||||
for (i = 0; i < num_parents; i++) {
|
||||
struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
|
||||
unsigned long tmp, prate;
|
||||
unsigned long prate;
|
||||
|
||||
/*
|
||||
* The clock has two parents, one is a fixed clock which is
|
||||
@@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
|
||||
|
||||
prate = clk_hw_get_rate(parent);
|
||||
|
||||
tmp = ac100_clkout_round_rate(hw, req->rate, prate);
|
||||
if (prate == AC100_RTC_32K_RATE) {
|
||||
struct clk_rate_request div_req = *req;
|
||||
|
||||
if (tmp > req->rate)
|
||||
continue;
|
||||
if (req->rate - tmp < req->rate - best) {
|
||||
best = tmp;
|
||||
best_parent = parent;
|
||||
div_req.best_parent_rate = prate;
|
||||
|
||||
ret = divider_determine_rate(hw, &div_req, NULL,
|
||||
AC100_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_POWER_OF_TWO);
|
||||
if (ret != 0 || div_req.rate > req->rate) {
|
||||
continue;
|
||||
} else if (req->rate - div_req.rate < req->rate - best) {
|
||||
best = div_req.rate;
|
||||
best_parent = parent;
|
||||
}
|
||||
} else {
|
||||
int j;
|
||||
|
||||
for (j = 0; ac100_clkout_prediv[j].div; j++) {
|
||||
struct clk_rate_request div_req = *req;
|
||||
unsigned long tmp_prate;
|
||||
|
||||
tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[j].div);
|
||||
div_req.best_parent_rate = tmp_prate;
|
||||
|
||||
ret = divider_determine_rate(hw, &div_req, NULL,
|
||||
AC100_CLKOUT_DIV_WIDTH,
|
||||
CLK_DIVIDER_POWER_OF_TWO);
|
||||
if (ret != 0 || div_req.rate > req->rate) {
|
||||
continue;
|
||||
} else if (req->rate - div_req.rate < req->rate - best) {
|
||||
best = div_req.rate;
|
||||
best_parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +214,7 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw,
|
||||
return -EINVAL;
|
||||
|
||||
req->best_parent_hw = best_parent;
|
||||
req->best_parent_rate = best;
|
||||
req->best_parent_rate = clk_hw_get_rate(best_parent);
|
||||
req->rate = best;
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user