diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2012-04-11 12:05:50 +0900 | 
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2012-04-11 12:05:50 +0900 | 
| commit | 4d6ddb08acc48368c5b7ac431f9d00db7227d2ed (patch) | |
| tree | 5030162ef3c2f9954e43baf02cff7f8794a8ba74 | |
| parent | a9e1e53bcfb29b3b503a5e75ce498d9a64f32c1e (diff) | |
| download | olio-linux-3.10-4d6ddb08acc48368c5b7ac431f9d00db7227d2ed.tar.xz olio-linux-3.10-4d6ddb08acc48368c5b7ac431f9d00db7227d2ed.zip  | |
sh: clkfwk: Support variable size accesses for MSTP clocks.
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>
| -rw-r--r-- | drivers/sh/clk/cpg.c | 38 | ||||
| -rw-r--r-- | include/linux/sh_clk.h | 34 | 
2 files changed, 58 insertions, 14 deletions
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 91b6d52f74e..6cbda484158 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -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 @@ -13,26 +14,41 @@  #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);  	} diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 0a9d8f2ac51..c513b73cd7c 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -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)	\  {								\  |