aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/clk/sunxi-ng/ccu_nm.c
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@free-electrons.com>2016-09-06 12:29:04 +0200
committerMaxime Ripard <maxime.ripard@free-electrons.com>2016-09-10 11:41:18 +0200
commit87ba9e5962f3f6e9a9a44cc332d1ad222d1c0302 (patch)
treec56ffb140f8b9f7604e431369852c5732fa72f4c /drivers/clk/sunxi-ng/ccu_nm.c
parentclk: sunxi-ng: div: Add kerneldoc for the _ccu_div structure (diff)
downloadwireguard-linux-87ba9e5962f3f6e9a9a44cc332d1ad222d1c0302.tar.xz
wireguard-linux-87ba9e5962f3f6e9a9a44cc332d1ad222d1c0302.zip
clk: sunxi-ng: div: Allow to set a maximum
Some dividers might have a maximum value that is lower than the width of the register. Add a field to _ccu_div to handle those case properly. If the field is set to 0, the code will assume that the maximum value is the maximum one that can be used with the field register width. Otherwise, we'll use whatever value has been set. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Acked-by: Chen-Yu Tsai <wens@csie.org>
Diffstat (limited to 'drivers/clk/sunxi-ng/ccu_nm.c')
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index e35ddd8eec8b..b61bdd8c7a7f 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -61,11 +61,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct ccu_nm *nm = hw_to_ccu_nm(hw);
+ unsigned long max_n, max_m;
unsigned long n, m;
- rational_best_approximation(rate, *parent_rate,
- 1 << nm->n.width, 1 << nm->m.width,
- &n, &m);
+ max_n = 1 << nm->n.width;
+ max_m = nm->m.max ?: 1 << nm->m.width;
+
+ rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m);
return *parent_rate * n / m;
}
@@ -75,6 +77,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct ccu_nm *nm = hw_to_ccu_nm(hw);
unsigned long flags;
+ unsigned long max_n, max_m;
unsigned long n, m;
u32 reg;
@@ -83,9 +86,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
else
ccu_frac_helper_disable(&nm->common, &nm->frac);
- rational_best_approximation(rate, parent_rate,
- 1 << nm->n.width, 1 << nm->m.width,
- &n, &m);
+ max_n = 1 << nm->n.width;
+ max_m = nm->m.max ?: 1 << nm->m.width;
+
+ rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m);
spin_lock_irqsave(nm->common.lock, flags);