These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / clk / at91 / clk-plldiv.c
index ea22656..2bed264 100644 (file)
@@ -12,8 +12,8 @@
 #include <linux/clkdev.h>
 #include <linux/clk/at91_pmc.h>
 #include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
 
 #include "pmc.h"
 
 
 struct clk_plldiv {
        struct clk_hw hw;
-       struct at91_pmc *pmc;
+       struct regmap *regmap;
 };
 
 static unsigned long clk_plldiv_recalc_rate(struct clk_hw *hw,
                                            unsigned long parent_rate)
 {
        struct clk_plldiv *plldiv = to_clk_plldiv(hw);
-       struct at91_pmc *pmc = plldiv->pmc;
+       unsigned int mckr;
 
-       if (pmc_read(pmc, AT91_PMC_MCKR) & AT91_PMC_PLLADIV2)
+       regmap_read(plldiv->regmap, AT91_PMC_MCKR, &mckr);
+
+       if (mckr & AT91_PMC_PLLADIV2)
                return parent_rate / 2;
 
        return parent_rate;
@@ -57,18 +59,12 @@ static int clk_plldiv_set_rate(struct clk_hw *hw, unsigned long rate,
                               unsigned long parent_rate)
 {
        struct clk_plldiv *plldiv = to_clk_plldiv(hw);
-       struct at91_pmc *pmc = plldiv->pmc;
-       u32 tmp;
 
-       if (parent_rate != rate && (parent_rate / 2) != rate)
+       if ((parent_rate != rate) && (parent_rate / 2 != rate))
                return -EINVAL;
 
-       pmc_lock(pmc);
-       tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_PLLADIV2;
-       if ((parent_rate / 2) == rate)
-               tmp |= AT91_PMC_PLLADIV2;
-       pmc_write(pmc, AT91_PMC_MCKR, tmp);
-       pmc_unlock(pmc);
+       regmap_update_bits(plldiv->regmap, AT91_PMC_MCKR, AT91_PMC_PLLADIV2,
+                          parent_rate != rate ? AT91_PMC_PLLADIV2 : 0);
 
        return 0;
 }
@@ -80,7 +76,7 @@ static const struct clk_ops plldiv_ops = {
 };
 
 static struct clk * __init
-at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name,
+at91_clk_register_plldiv(struct regmap *regmap, const char *name,
                         const char *parent_name)
 {
        struct clk_plldiv *plldiv;
@@ -98,7 +94,7 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name,
        init.flags = CLK_SET_RATE_GATE;
 
        plldiv->hw.init = &init;
-       plldiv->pmc = pmc;
+       plldiv->regmap = regmap;
 
        clk = clk_register(NULL, &plldiv->hw);
 
@@ -109,27 +105,27 @@ at91_clk_register_plldiv(struct at91_pmc *pmc, const char *name,
 }
 
 static void __init
-of_at91_clk_plldiv_setup(struct device_node *np, struct at91_pmc *pmc)
+of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
 {
        struct clk *clk;
        const char *parent_name;
        const char *name = np->name;
+       struct regmap *regmap;
 
        parent_name = of_clk_get_parent_name(np, 0);
 
        of_property_read_string(np, "clock-output-names", &name);
 
-       clk = at91_clk_register_plldiv(pmc, name, parent_name);
+       regmap = syscon_node_to_regmap(of_get_parent(np));
+       if (IS_ERR(regmap))
+               return;
 
+       clk = at91_clk_register_plldiv(regmap, name, parent_name);
        if (IS_ERR(clk))
                return;
 
        of_clk_add_provider(np, of_clk_src_simple_get, clk);
        return;
 }
-
-void __init of_at91sam9x5_clk_plldiv_setup(struct device_node *np,
-                                          struct at91_pmc *pmc)
-{
-       of_at91_clk_plldiv_setup(np, pmc);
-}
+CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
+              of_at91sam9x5_clk_plldiv_setup);