sh: clkfwk: Support variable size accesses for MSTP clocks.
authorPaul Mundt <lethal@linux-sh.org>
Wed, 11 Apr 2012 03:05:50 +0000 (12:05 +0900)
committerPaul Mundt <lethal@linux-sh.org>
Wed, 11 Apr 2012 03:05:50 +0000 (12:05 +0900)
The bulk of the MSTP users require 32-bit access, but this isn't the case
for some of the SH-2A parts, so add in some basic infrastructure to let
the CPU define its required access size in preparation.

Requested-by: Phil Edworthy <phil.edworthy@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
drivers/sh/clk/cpg.c
include/linux/sh_clk.h

index 91b6d52f74eb76644c0f5ac2d81285a0da7719b3..6cbda4841589e6a9cb53c0185a25c4c1a14a1a37 100644 (file)
@@ -2,6 +2,7 @@
  * Helper routines for SuperH Clock Pulse Generator blocks (CPG).
  *
  *  Copyright (C) 2010  Magnus Damm
+ *  Copyright (C) 2010 - 2012  Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
 #include <linux/io.h>
 #include <linux/sh_clk.h>
 
-static int sh_clk_mstp32_enable(struct clk *clk)
+static int sh_clk_mstp_enable(struct clk *clk)
 {
-       iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
-                 clk->mapped_reg);
+       if (clk->flags & CLK_ENABLE_REG_8BIT)
+               iowrite8(ioread8(clk->mapped_reg) & ~(1 << clk->enable_bit),
+                        clk->mapped_reg);
+       else if (clk->flags & CLK_ENABLE_REG_16BIT)
+               iowrite16(ioread16(clk->mapped_reg) & ~(1 << clk->enable_bit),
+                         clk->mapped_reg);
+       else
+               iowrite32(ioread32(clk->mapped_reg) & ~(1 << clk->enable_bit),
+                         clk->mapped_reg);
+
        return 0;
 }
 
-static void sh_clk_mstp32_disable(struct clk *clk)
+static void sh_clk_mstp_disable(struct clk *clk)
 {
-       iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
-                 clk->mapped_reg);
+       if (clk->flags & CLK_ENABLE_REG_8BIT)
+               iowrite8(ioread8(clk->mapped_reg) | (1 << clk->enable_bit),
+                        clk->mapped_reg);
+       else if (clk->flags & CLK_ENABLE_REG_16BIT)
+               iowrite16(ioread16(clk->mapped_reg) | (1 << clk->enable_bit),
+                         clk->mapped_reg);
+       else
+               iowrite32(ioread32(clk->mapped_reg) | (1 << clk->enable_bit),
+                         clk->mapped_reg);
 }
 
-static struct sh_clk_ops sh_clk_mstp32_clk_ops = {
-       .enable         = sh_clk_mstp32_enable,
-       .disable        = sh_clk_mstp32_disable,
+static struct sh_clk_ops sh_clk_mstp_clk_ops = {
+       .enable         = sh_clk_mstp_enable,
+       .disable        = sh_clk_mstp_disable,
        .recalc         = followparent_recalc,
 };
 
-int __init sh_clk_mstp32_register(struct clk *clks, int nr)
+int __init sh_clk_mstp_register(struct clk *clks, int nr)
 {
        struct clk *clkp;
        int ret = 0;
@@ -40,7 +56,7 @@ int __init sh_clk_mstp32_register(struct clk *clks, int nr)
 
        for (k = 0; !ret && (k < nr); k++) {
                clkp = clks + k;
-               clkp->ops = &sh_clk_mstp32_clk_ops;
+               clkp->ops = &sh_clk_mstp_clk_ops;
                ret |= clk_register(clkp);
        }
 
index 0a9d8f2ac51908958776115b8d1ff5d2cbbc5b6d..c513b73cd7cb8499a7ac61edb3789e7e24a8bfab 100644 (file)
@@ -59,7 +59,15 @@ struct clk {
        unsigned int            nr_freqs;
 };
 
-#define CLK_ENABLE_ON_INIT     (1 << 0)
+#define CLK_ENABLE_ON_INIT     BIT(0)
+
+#define CLK_ENABLE_REG_32BIT   BIT(1)  /* default access size */
+#define CLK_ENABLE_REG_16BIT   BIT(2)
+#define CLK_ENABLE_REG_8BIT    BIT(3)
+
+#define CLK_ENABLE_REG_MASK    (CLK_ENABLE_REG_32BIT | \
+                                CLK_ENABLE_REG_16BIT | \
+                                CLK_ENABLE_REG_8BIT)
 
 /* drivers/sh/clk.c */
 unsigned long followparent_recalc(struct clk *);
@@ -102,7 +110,7 @@ long clk_round_parent(struct clk *clk, unsigned long target,
                      unsigned long *best_freq, unsigned long *parent_freq,
                      unsigned int div_min, unsigned int div_max);
 
-#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags)       \
+#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _flags)         \
 {                                                                      \
        .parent         = _parent,                                      \
        .enable_reg     = (void __iomem *)_enable_reg,                  \
@@ -110,7 +118,27 @@ long clk_round_parent(struct clk *clk, unsigned long target,
        .flags          = _flags,                                       \
 }
 
-int sh_clk_mstp32_register(struct clk *clks, int nr);
+#define SH_CLK_MSTP32(_p, _r, _b, _f)                                  \
+       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_32BIT)
+
+#define SH_CLK_MSTP16(_p, _r, _b, _f)                                  \
+       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_16BIT)
+
+#define SH_CLK_MSTP8(_p, _r, _b, _f)                                   \
+       SH_CLK_MSTP(_p, _r, _b, _f | CLK_ENABLE_REG_8BIT)
+
+int sh_clk_mstp_register(struct clk *clks, int nr);
+
+/*
+ * MSTP registration never really cared about access size, despite the
+ * original enable/disable pairs assuming a 32-bit access. Clocks are
+ * responsible for defining their access sizes either directly or via the
+ * clock definition wrappers.
+ */
+static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr)
+{
+       return sh_clk_mstp_register(clks, nr);
+}
 
 #define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags)        \
 {                                                              \
This page took 0.029196 seconds and 5 git commands to generate.