summaryrefslogtreecommitdiff
path: root/drivers/clk/at91/clk-h32mx.c
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@free-electrons.com>2014-09-07 06:14:29 (GMT)
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2016-02-17 16:52:58 (GMT)
commit1bdf02326b71eae7e9b4b335b881856aaf9d1af6 (patch)
treea11ad267acd940e4e7aff9846d94689158c246b2 /drivers/clk/at91/clk-h32mx.c
parent863a81c3be1d931bdae6426e231add9334311f13 (diff)
downloadlinux-1bdf02326b71eae7e9b4b335b881856aaf9d1af6.tar.xz
clk: at91: make use of syscon/regmap internally
Use the regmap coming from syscon to access the registers instead of using pmc_read/pmc_write. This allows to avoid passing the at91_pmc structure to the child nodes of the PMC. The final benefit is to have each clock register itself instead of having to iterate over the children. Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> Acked-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Diffstat (limited to 'drivers/clk/at91/clk-h32mx.c')
-rw-r--r--drivers/clk/at91/clk-h32mx.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
index 61566bc..3fd59b1 100644
--- a/drivers/clk/at91/clk-h32mx.c
+++ b/drivers/clk/at91/clk-h32mx.c
@@ -24,6 +24,8 @@
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
#include "pmc.h"
@@ -31,7 +33,7 @@
struct clk_sama5d4_h32mx {
struct clk_hw hw;
- struct at91_pmc *pmc;
+ struct regmap *regmap;
};
#define to_clk_sama5d4_h32mx(hw) container_of(hw, struct clk_sama5d4_h32mx, hw)
@@ -40,8 +42,10 @@ static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
+ unsigned int mckr;
- if (pmc_read(h32mxclk->pmc, AT91_PMC_MCKR) & AT91_PMC_H32MXDIV)
+ regmap_read(h32mxclk->regmap, AT91_PMC_MCKR, &mckr);
+ if (mckr & AT91_PMC_H32MXDIV)
return parent_rate / 2;
if (parent_rate > H32MX_MAX_FREQ)
@@ -70,18 +74,16 @@ static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
- struct at91_pmc *pmc = h32mxclk->pmc;
- u32 tmp;
+ u32 mckr = 0;
if (parent_rate != rate && (parent_rate / 2) != rate)
return -EINVAL;
- pmc_lock(pmc);
- tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_H32MXDIV;
if ((parent_rate / 2) == rate)
- tmp |= AT91_PMC_H32MXDIV;
- pmc_write(pmc, AT91_PMC_MCKR, tmp);
- pmc_unlock(pmc);
+ mckr = AT91_PMC_H32MXDIV;
+
+ regmap_update_bits(h32mxclk->regmap, AT91_PMC_MCKR,
+ AT91_PMC_H32MXDIV, mckr);
return 0;
}
@@ -92,14 +94,18 @@ static const struct clk_ops h32mx_ops = {
.set_rate = clk_sama5d4_h32mx_set_rate,
};
-void __init of_sama5d4_clk_h32mx_setup(struct device_node *np,
- struct at91_pmc *pmc)
+static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
{
struct clk_sama5d4_h32mx *h32mxclk;
struct clk_init_data init;
const char *parent_name;
+ struct regmap *regmap;
struct clk *clk;
+ regmap = syscon_node_to_regmap(of_get_parent(np));
+ if (IS_ERR(regmap))
+ return;
+
h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
if (!h32mxclk)
return;
@@ -113,7 +119,7 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np,
init.flags = CLK_SET_RATE_GATE;
h32mxclk->hw.init = &init;
- h32mxclk->pmc = pmc;
+ h32mxclk->regmap = regmap;
clk = clk_register(NULL, &h32mxclk->hw);
if (!clk) {
@@ -123,3 +129,5 @@ void __init of_sama5d4_clk_h32mx_setup(struct device_node *np,
of_clk_add_provider(np, of_clk_src_simple_get, clk);
}
+CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
+ of_sama5d4_clk_h32mx_setup);