]> Pileus Git - ~andy/linux/commitdiff
Merge tag 'sunxi-clk-for-3.12' of https://github.com/mripard/linux into clk-next...
authorMike Turquette <mturquette@linaro.org>
Wed, 28 Aug 2013 01:07:46 +0000 (18:07 -0700)
committerMike Turquette <mturquette@linaro.org>
Wed, 28 Aug 2013 01:07:46 +0000 (18:07 -0700)
Allwinner clock changes for 3.12

These patches mostly do some cleanup to introduce the basic gated clocks for
the Allwinner A10s, A20 and A31 SoCs.

Conflicts:
drivers/clk/sunxi/clk-sunxi.c

drivers/clk/clk-divider.c
drivers/clk/clk-gate.c
drivers/clk/clk-mux.c
drivers/clk/clk.c
drivers/clk/mvebu/clk-cpu.c
drivers/clk/mvebu/common.c
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-pll.h
include/linux/clk-provider.h

index 749372f87ec41bc09b35d81aadced94f8e06844c..8d3009e44fba40d4fba82825bd59d98febf53984 100644 (file)
@@ -104,7 +104,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
        struct clk_divider *divider = to_clk_divider(hw);
        unsigned int div, val;
 
-       val = readl(divider->reg) >> divider->shift;
+       val = clk_readl(divider->reg) >> divider->shift;
        val &= div_mask(divider);
 
        div = _get_div(divider, val);
@@ -230,11 +230,11 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
                val = div_mask(divider) << (divider->shift + 16);
        } else {
-               val = readl(divider->reg);
+               val = clk_readl(divider->reg);
                val &= ~(div_mask(divider) << divider->shift);
        }
        val |= value << divider->shift;
-       writel(val, divider->reg);
+       clk_writel(val, divider->reg);
 
        if (divider->lock)
                spin_unlock_irqrestore(divider->lock, flags);
index 2b28a004c19eee1e3ba408b85a04d9d237fb3e19..4a58c55255bd884f3f1e7deea52048712b297729 100644 (file)
@@ -58,7 +58,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
                if (set)
                        reg |= BIT(gate->bit_idx);
        } else {
-               reg = readl(gate->reg);
+               reg = clk_readl(gate->reg);
 
                if (set)
                        reg |= BIT(gate->bit_idx);
@@ -66,7 +66,7 @@ static void clk_gate_endisable(struct clk_hw *hw, int enable)
                        reg &= ~BIT(gate->bit_idx);
        }
 
-       writel(reg, gate->reg);
+       clk_writel(reg, gate->reg);
 
        if (gate->lock)
                spin_unlock_irqrestore(gate->lock, flags);
@@ -89,7 +89,7 @@ static int clk_gate_is_enabled(struct clk_hw *hw)
        u32 reg;
        struct clk_gate *gate = to_clk_gate(hw);
 
-       reg = readl(gate->reg);
+       reg = clk_readl(gate->reg);
 
        /* if a set bit disables this clk, flip it before masking */
        if (gate->flags & CLK_GATE_SET_TO_DISABLE)
index 0811633fcc4d98df022a7d4d22ac15951c8910df..4f96ff3ba728321563cbdc6b728f9a25c65d74c6 100644 (file)
@@ -42,7 +42,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
         * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
         * val = 0x4 really means "bit 2, index starts at bit 0"
         */
-       val = readl(mux->reg) >> mux->shift;
+       val = clk_readl(mux->reg) >> mux->shift;
        val &= mux->mask;
 
        if (mux->table) {
@@ -89,11 +89,11 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
        if (mux->flags & CLK_MUX_HIWORD_MASK) {
                val = mux->mask << (mux->shift + 16);
        } else {
-               val = readl(mux->reg);
+               val = clk_readl(mux->reg);
                val &= ~(mux->mask << mux->shift);
        }
        val |= index << mux->shift;
-       writel(val, mux->reg);
+       clk_writel(val, mux->reg);
 
        if (mux->lock)
                spin_unlock_irqrestore(mux->lock, flags);
index bc020372106ba939191f3c4e0130e81df650b3bf..2db08c01ef51d9de9b618282ba55134d97dfabe4 100644 (file)
@@ -1428,6 +1428,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        struct clk *top, *fail_clk;
        int ret = 0;
 
+       if (!clk)
+               return 0;
+
        /* prevent racing with updates to the clock topology */
        clk_prepare_lock();
 
@@ -1567,7 +1570,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
        u8 p_index = 0;
        unsigned long p_rate = 0;
 
-       if (!clk || !clk->ops)
+       if (!clk)
+               return 0;
+
+       if (!clk->ops)
                return -EINVAL;
 
        /* verify ops for for multi-parent clks */
@@ -2222,13 +2228,13 @@ EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
  */
 void __init of_clk_init(const struct of_device_id *matches)
 {
+       const struct of_device_id *match;
        struct device_node *np;
 
        if (!matches)
                matches = __clk_of_table;
 
-       for_each_matching_node(np, matches) {
-               const struct of_device_id *match = of_match_node(matches, np);
+       for_each_matching_node_and_match(np, matches, &match) {
                of_clk_init_cb_t clk_init_cb = match->data;
                clk_init_cb(np);
        }
index b0fbc07154912072bce34e4684e0a0fb57d2cf52..1466865b0743bf2110b74a6832acbef832743b77 100644 (file)
@@ -119,7 +119,7 @@ void __init of_cpu_clk_setup(struct device_node *node)
 
        cpuclk = kzalloc(ncpus * sizeof(*cpuclk), GFP_KERNEL);
        if (WARN_ON(!cpuclk))
-               return;
+               goto cpuclk_out;
 
        clks = kzalloc(ncpus * sizeof(*clks), GFP_KERNEL);
        if (WARN_ON(!clks))
@@ -170,6 +170,8 @@ bail_out:
                kfree(cpuclk[ncpus].clk_name);
 clks_out:
        kfree(cpuclk);
+cpuclk_out:
+       iounmap(clock_complex_base);
 }
 
 CLK_OF_DECLARE(armada_xp_cpu_clock, "marvell,armada-xp-cpu-clock",
index adaa4a1821b843a3f63a883e0e4f082d6a8e3c41..25ceccf939ad2f33cdc71907d91e68b8e69a64be 100644 (file)
@@ -45,8 +45,10 @@ void __init mvebu_coreclk_setup(struct device_node *np,
        clk_data.clk_num = 2 + desc->num_ratios;
        clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
                                GFP_KERNEL);
-       if (WARN_ON(!clk_data.clks))
+       if (WARN_ON(!clk_data.clks)) {
+               iounmap(base);
                return;
+       }
 
        /* Register TCLK */
        of_property_read_string_index(np, "clock-output-names", 0,
@@ -134,7 +136,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
 
        ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
        if (WARN_ON(!ctrl))
-               return;
+               goto ctrl_out;
 
        spin_lock_init(&ctrl->lock);
 
@@ -145,10 +147,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
        ctrl->num_gates = n;
        ctrl->gates = kzalloc(ctrl->num_gates * sizeof(struct clk *),
                              GFP_KERNEL);
-       if (WARN_ON(!ctrl->gates)) {
-               kfree(ctrl);
-               return;
-       }
+       if (WARN_ON(!ctrl->gates))
+               goto gates_out;
 
        for (n = 0; n < ctrl->num_gates; n++) {
                const char *parent =
@@ -160,4 +160,10 @@ void __init mvebu_clk_gating_setup(struct device_node *np,
        }
 
        of_clk_add_provider(np, clk_gating_get_src, ctrl);
+
+       return;
+gates_out:
+       kfree(ctrl);
+ctrl_out:
+       iounmap(base);
 }
index 077555416ce16f036764825f1580bf4ed78ffd7c..7572d1d4fac139662e48bb29f0c1a65bd54946d1 100644 (file)
@@ -441,9 +441,6 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
  * PLL6552 Clock Type
  */
 
-#define PLL6552_LOCK_REG       0x00
-#define PLL6552_CON_REG                0x0c
-
 #define PLL6552_MDIV_MASK      0x3ff
 #define PLL6552_PDIV_MASK      0x3f
 #define PLL6552_SDIV_MASK      0x7
@@ -451,21 +448,14 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
 #define PLL6552_PDIV_SHIFT     8
 #define PLL6552_SDIV_SHIFT     0
 
-struct samsung_clk_pll6552 {
-       struct clk_hw hw;
-       void __iomem *reg_base;
-};
-
-#define to_clk_pll6552(_hw) container_of(_hw, struct samsung_clk_pll6552, hw)
-
 static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
                                                unsigned long parent_rate)
 {
-       struct samsung_clk_pll6552 *pll = to_clk_pll6552(hw);
+       struct samsung_clk_pll *pll = to_clk_pll(hw);
        u32 mdiv, pdiv, sdiv, pll_con;
        u64 fvco = parent_rate;
 
-       pll_con = __raw_readl(pll->reg_base + PLL6552_CON_REG);
+       pll_con = __raw_readl(pll->con_reg);
        mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
        pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
        sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
@@ -480,48 +470,10 @@ static const struct clk_ops samsung_pll6552_clk_ops = {
        .recalc_rate = samsung_pll6552_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll6552(const char *name,
-                                       const char *pname, void __iomem *base)
-{
-       struct samsung_clk_pll6552 *pll;
-       struct clk *clk;
-       struct clk_init_data init;
-
-       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-       if (!pll) {
-               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-               return NULL;
-       }
-
-       init.name = name;
-       init.ops = &samsung_pll6552_clk_ops;
-       init.parent_names = &pname;
-       init.num_parents = 1;
-
-       pll->hw.init = &init;
-       pll->reg_base = base;
-
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register pll clock %s\n", __func__,
-                               name);
-               kfree(pll);
-       }
-
-       if (clk_register_clkdev(clk, name, NULL))
-               pr_err("%s: failed to register lookup for %s", __func__, name);
-
-       return clk;
-}
-
 /*
  * PLL6553 Clock Type
  */
 
-#define PLL6553_LOCK_REG       0x00
-#define PLL6553_CON0_REG       0x0c
-#define PLL6553_CON1_REG       0x10
-
 #define PLL6553_MDIV_MASK      0xff
 #define PLL6553_PDIV_MASK      0x3f
 #define PLL6553_SDIV_MASK      0x7
@@ -531,22 +483,15 @@ struct clk * __init samsung_clk_register_pll6552(const char *name,
 #define PLL6553_SDIV_SHIFT     0
 #define PLL6553_KDIV_SHIFT     0
 
-struct samsung_clk_pll6553 {
-       struct clk_hw hw;
-       void __iomem *reg_base;
-};
-
-#define to_clk_pll6553(_hw) container_of(_hw, struct samsung_clk_pll6553, hw)
-
 static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
                                                unsigned long parent_rate)
 {
-       struct samsung_clk_pll6553 *pll = to_clk_pll6553(hw);
+       struct samsung_clk_pll *pll = to_clk_pll(hw);
        u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
        u64 fvco = parent_rate;
 
-       pll_con0 = __raw_readl(pll->reg_base + PLL6553_CON0_REG);
-       pll_con1 = __raw_readl(pll->reg_base + PLL6553_CON1_REG);
+       pll_con0 = __raw_readl(pll->con_reg);
+       pll_con1 = __raw_readl(pll->con_reg + 0x4);
        mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
        pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
        sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
@@ -563,40 +508,6 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
        .recalc_rate = samsung_pll6553_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll6553(const char *name,
-                                       const char *pname, void __iomem *base)
-{
-       struct samsung_clk_pll6553 *pll;
-       struct clk *clk;
-       struct clk_init_data init;
-
-       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-       if (!pll) {
-               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-               return NULL;
-       }
-
-       init.name = name;
-       init.ops = &samsung_pll6553_clk_ops;
-       init.parent_names = &pname;
-       init.num_parents = 1;
-
-       pll->hw.init = &init;
-       pll->reg_base = base;
-
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register pll clock %s\n", __func__,
-                               name);
-               kfree(pll);
-       }
-
-       if (clk_register_clkdev(clk, name, NULL))
-               pr_err("%s: failed to register lookup for %s", __func__, name);
-
-       return clk;
-}
-
 /*
  * PLL2550x Clock Type
  */
@@ -732,6 +643,12 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
                else
                        init.ops = &samsung_pll36xx_clk_ops;
                break;
+       case pll_6552:
+               init.ops = &samsung_pll6552_clk_ops;
+               break;
+       case pll_6553:
+               init.ops = &samsung_pll6553_clk_ops;
+               break;
        default:
                pr_warn("%s: Unknown pll type for pll clk %s\n",
                        __func__, pll_clk->name);
index 2f70e88d61047eb2983af8ecd8856da37eb7c350..cd1103784f712eb137af282c7a41c0356707ff87 100644 (file)
@@ -17,6 +17,8 @@ enum samsung_pll_type {
        pll_36xx,
        pll_2550,
        pll_2650,
+       pll_6552,
+       pll_6553,
 };
 
 #define PLL_35XX_RATE(_rate, _m, _p, _s)                       \
@@ -64,10 +66,6 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
 extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
                        const char *pname, const void __iomem *con_reg,
                        enum pll46xx_type type);
-extern struct clk *samsung_clk_register_pll6552(const char *name,
-                       const char *pname, void __iomem *base);
-extern struct clk *samsung_clk_register_pll6553(const char *name,
-                       const char *pname, void __iomem *base);
 extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
                        const char *pname, const void __iomem *reg_base,
                        const unsigned long offset);
index 1f0285b2f422c25812245410318e1a584d72cd8d..73bdb69f0c08150a64ac2cd4cd5bf1cca3c3ac6a 100644 (file)
@@ -12,6 +12,7 @@
 #define __LINUX_CLK_PROVIDER_H
 
 #include <linux/clk.h>
+#include <linux/io.h>
 
 #ifdef CONFIG_COMMON_CLK
 
@@ -504,5 +505,21 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,
 #define of_clk_init(matches) \
        { while (0); }
 #endif /* CONFIG_OF */
+
+/*
+ * wrap access to peripherals in accessor routines
+ * for improved portability across platforms
+ */
+
+static inline u32 clk_readl(u32 __iomem *reg)
+{
+       return readl(reg);
+}
+
+static inline void clk_writel(u32 val, u32 __iomem *reg)
+{
+       writel(val, reg);
+}
+
 #endif /* CONFIG_COMMON_CLK */
 #endif /* CLK_PROVIDER_H */