summaryrefslogtreecommitdiff
path: root/drivers/clk/rockchip/clk-half-divider.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/rockchip/clk-half-divider.c')
-rw-r--r--drivers/clk/rockchip/clk-half-divider.c44
1 files changed, 24 insertions, 20 deletions
diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c
index b8da6e799423..fbc018e8afa4 100644
--- a/drivers/clk/rockchip/clk-half-divider.c
+++ b/drivers/clk/rockchip/clk-half-divider.c
@@ -3,8 +3,9 @@
* Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
*/
-#include <linux/slab.h>
#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/slab.h>
#include "clk.h"
#define div_mask(width) ((1 << (width)) - 1)
@@ -24,7 +25,7 @@ static unsigned long clk_half_divider_recalc_rate(struct clk_hw *hw,
struct clk_divider *divider = to_clk_divider(hw);
unsigned int val;
- val = clk_readl(divider->reg) >> divider->shift;
+ val = readl(divider->reg) >> divider->shift;
val &= div_mask(divider->width);
val = val * 2 + 3;
@@ -91,17 +92,19 @@ static int clk_half_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
return bestdiv;
}
-static long clk_half_divider_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *prate)
+static int clk_half_divider_determine_rate(struct clk_hw *hw,
+ struct clk_rate_request *req)
{
struct clk_divider *divider = to_clk_divider(hw);
int div;
- div = clk_half_divider_bestdiv(hw, rate, prate,
+ div = clk_half_divider_bestdiv(hw, req->rate, &req->best_parent_rate,
divider->width,
divider->flags);
- return DIV_ROUND_UP_ULL(((u64)*prate * 2), div * 2 + 3);
+ req->rate = DIV_ROUND_UP_ULL(((u64)req->best_parent_rate * 2), div * 2 + 3);
+
+ return 0;
}
static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -124,11 +127,11 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
val = div_mask(divider->width) << (divider->shift + 16);
} else {
- val = clk_readl(divider->reg);
+ val = readl(divider->reg);
val &= ~(div_mask(divider->width) << divider->shift);
}
val |= value << divider->shift;
- clk_writel(val, divider->reg);
+ writel(val, divider->reg);
if (divider->lock)
spin_unlock_irqrestore(divider->lock, flags);
@@ -138,14 +141,13 @@ static int clk_half_divider_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
-const struct clk_ops clk_half_divider_ops = {
+static const struct clk_ops clk_half_divider_ops = {
.recalc_rate = clk_half_divider_recalc_rate,
- .round_rate = clk_half_divider_round_rate,
+ .determine_rate = clk_half_divider_determine_rate,
.set_rate = clk_half_divider_set_rate,
};
-EXPORT_SYMBOL_GPL(clk_half_divider_ops);
-/**
+/*
* Register a clock branch.
* Most clock branches have a form like
*
@@ -166,7 +168,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
unsigned long flags,
spinlock_t *lock)
{
- struct clk *clk;
+ struct clk_hw *hw = ERR_PTR(-ENOMEM);
struct clk_mux *mux = NULL;
struct clk_gate *gate = NULL;
struct clk_divider *div = NULL;
@@ -212,16 +214,18 @@ struct clk *rockchip_clk_register_halfdiv(const char *name,
div_ops = &clk_half_divider_ops;
}
- clk = clk_register_composite(NULL, name, parent_names, num_parents,
- mux ? &mux->hw : NULL, mux_ops,
- div ? &div->hw : NULL, div_ops,
- gate ? &gate->hw : NULL, gate_ops,
- flags);
+ hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
+ mux ? &mux->hw : NULL, mux_ops,
+ div ? &div->hw : NULL, div_ops,
+ gate ? &gate->hw : NULL, gate_ops,
+ flags);
+ if (IS_ERR(hw))
+ goto err_div;
- return clk;
+ return hw->clk;
err_div:
kfree(gate);
err_gate:
kfree(mux);
- return ERR_PTR(-ENOMEM);
+ return ERR_CAST(hw);
}