linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* Samsung clock updates v2
@ 2009-12-08  2:07 Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Move <plat/clock.h> to plat-samsung Ben Dooks
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Re-based on tree submitted to RMK, so there where some fixups
that had to be done. This has only been compile test and thus
needs testing. If someone else can test and send me a tested-by:
line for any of the patches in this series then please let me know.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: SAMSUNG: Move <plat/clock.h> to plat-samsung
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Cleanup common init code in s3c6400-clock.c Ben Dooks
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Move the <plat/clock.h> header to plat-samsung where it can be used by all
the platforms, and readies it for the next round of clock updates where
the clock code will be amalgamated.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c/include/plat/clock.h     |   89 ----------------------------
 arch/arm/plat-samsung/include/plat/clock.h |   89 ++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 89 deletions(-)
 delete mode 100644 arch/arm/plat-s3c/include/plat/clock.h
 create mode 100644 arch/arm/plat-samsung/include/plat/clock.h

diff --git a/arch/arm/plat-s3c/include/plat/clock.h b/arch/arm/plat-s3c/include/plat/clock.h
deleted file mode 100644
index d86af84..0000000
--- a/arch/arm/plat-s3c/include/plat/clock.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* linux/arch/arm/plat-s3c/include/plat/clock.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://www.simtec.co.uk/products/SWLINUX/
- *	Written by Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/spinlock.h>
-
-struct clk {
-	struct list_head      list;
-	struct module        *owner;
-	struct clk           *parent;
-	const char           *name;
-	int		      id;
-	int		      usage;
-	unsigned long         rate;
-	unsigned long         ctrlbit;
-
-	int		    (*enable)(struct clk *, int enable);
-	int		    (*set_rate)(struct clk *c, unsigned long rate);
-	unsigned long	    (*get_rate)(struct clk *c);
-	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
-	int		    (*set_parent)(struct clk *c, struct clk *parent);
-};
-
-/* other clocks which may be registered by board support */
-
-extern struct clk s3c24xx_dclk0;
-extern struct clk s3c24xx_dclk1;
-extern struct clk s3c24xx_clkout0;
-extern struct clk s3c24xx_clkout1;
-extern struct clk s3c24xx_uclk;
-
-extern struct clk clk_usb_bus;
-
-/* core clock support */
-
-extern struct clk clk_f;
-extern struct clk clk_h;
-extern struct clk clk_p;
-extern struct clk clk_mpll;
-extern struct clk clk_upll;
-extern struct clk clk_epll;
-extern struct clk clk_xtal;
-extern struct clk clk_ext;
-
-/* S3C64XX specific clocks */
-extern struct clk clk_h2;
-extern struct clk clk_27m;
-extern struct clk clk_48m;
-
-/* exports for arch/arm/mach-s3c2410
- *
- * Please DO NOT use these outside of arch/arm/mach-s3c2410
-*/
-
-extern spinlock_t clocks_lock;
-
-extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
-
-extern int s3c24xx_register_clock(struct clk *clk);
-extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
-
-extern int s3c24xx_register_baseclocks(unsigned long xtal);
-
-extern void s3c64xx_register_clocks(void);
-
-extern void s3c24xx_setup_clocks(unsigned long fclk,
-				 unsigned long hclk,
-				 unsigned long pclk);
-
-extern void s3c2410_setup_clocks(void);
-extern void s3c2412_setup_clocks(void);
-extern void s3c244x_setup_clocks(void);
-extern void s3c2443_setup_clocks(void);
-
-/* S3C64XX specific functions and clocks */
-
-extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
-
-/* Init for pwm clock code */
-
-extern void s3c_pwmclk_init(void);
-
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
new file mode 100644
index 0000000..d86af84
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -0,0 +1,89 @@
+/* linux/arch/arm/plat-s3c/include/plat/clock.h
+ *
+ * Copyright (c) 2004-2005 Simtec Electronics
+ *	http://www.simtec.co.uk/products/SWLINUX/
+ *	Written by Ben Dooks, <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/spinlock.h>
+
+struct clk {
+	struct list_head      list;
+	struct module        *owner;
+	struct clk           *parent;
+	const char           *name;
+	int		      id;
+	int		      usage;
+	unsigned long         rate;
+	unsigned long         ctrlbit;
+
+	int		    (*enable)(struct clk *, int enable);
+	int		    (*set_rate)(struct clk *c, unsigned long rate);
+	unsigned long	    (*get_rate)(struct clk *c);
+	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
+	int		    (*set_parent)(struct clk *c, struct clk *parent);
+};
+
+/* other clocks which may be registered by board support */
+
+extern struct clk s3c24xx_dclk0;
+extern struct clk s3c24xx_dclk1;
+extern struct clk s3c24xx_clkout0;
+extern struct clk s3c24xx_clkout1;
+extern struct clk s3c24xx_uclk;
+
+extern struct clk clk_usb_bus;
+
+/* core clock support */
+
+extern struct clk clk_f;
+extern struct clk clk_h;
+extern struct clk clk_p;
+extern struct clk clk_mpll;
+extern struct clk clk_upll;
+extern struct clk clk_epll;
+extern struct clk clk_xtal;
+extern struct clk clk_ext;
+
+/* S3C64XX specific clocks */
+extern struct clk clk_h2;
+extern struct clk clk_27m;
+extern struct clk clk_48m;
+
+/* exports for arch/arm/mach-s3c2410
+ *
+ * Please DO NOT use these outside of arch/arm/mach-s3c2410
+*/
+
+extern spinlock_t clocks_lock;
+
+extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
+
+extern int s3c24xx_register_clock(struct clk *clk);
+extern int s3c24xx_register_clocks(struct clk **clk, int nr_clks);
+
+extern int s3c24xx_register_baseclocks(unsigned long xtal);
+
+extern void s3c64xx_register_clocks(void);
+
+extern void s3c24xx_setup_clocks(unsigned long fclk,
+				 unsigned long hclk,
+				 unsigned long pclk);
+
+extern void s3c2410_setup_clocks(void);
+extern void s3c2412_setup_clocks(void);
+extern void s3c244x_setup_clocks(void);
+extern void s3c2443_setup_clocks(void);
+
+/* S3C64XX specific functions and clocks */
+
+extern int s3c64xx_sclk_ctrl(struct clk *clk, int enable);
+
+/* Init for pwm clock code */
+
+extern void s3c_pwmclk_init(void);
+
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: S3C64XX: Cleanup common init code in s3c6400-clock.c
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Move <plat/clock.h> to plat-samsung Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Compress s3c6400-clock.c code Ben Dooks
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Remove the four fields from clksrc_clk.clk which are always the same
and init them when the clock is registered. This helps remove the amount
of repeated code.

This is a re-work of Harald Welte's clock changes for the latest kernel.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c64xx/s3c6400-clock.c |   49 +++-----------------------------
 1 files changed, 5 insertions(+), 44 deletions(-)

diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index 6ffa21e..5882470 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -364,10 +364,6 @@ static struct clksrc_clk clk_mmc0 = {
 		.id		= 0,
 		.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_MMC0_SHIFT,
 	.mask		= S3C6400_CLKSRC_MMC0_MASK,
@@ -382,10 +378,6 @@ static struct clksrc_clk clk_mmc1 = {
 		.id		= 1,
 		.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
 		.enable		= s3c64xx_sclk_ctrl,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_MMC1_SHIFT,
 	.mask		= S3C6400_CLKSRC_MMC1_MASK,
@@ -400,10 +392,6 @@ static struct clksrc_clk clk_mmc2 = {
 		.id		= 2,
 		.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
 		.enable		= s3c64xx_sclk_ctrl,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_MMC2_SHIFT,
 	.mask		= S3C6400_CLKSRC_MMC2_MASK,
@@ -418,10 +406,6 @@ static struct clksrc_clk clk_usbhost = {
 		.id		= -1,
 		.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_UHOST_SHIFT,
 	.mask		= S3C6400_CLKSRC_UHOST_MASK,
@@ -436,10 +420,6 @@ static struct clksrc_clk clk_uart_uclk1 = {
 		.id		= -1,
 		.ctrlbit        = S3C_CLKCON_SCLK_UART,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_UART_SHIFT,
 	.mask		= S3C6400_CLKSRC_UART_MASK,
@@ -456,10 +436,6 @@ static struct clksrc_clk clk_spi0 = {
 		.id		= 0,
 		.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_SPI0_SHIFT,
 	.mask		= S3C6400_CLKSRC_SPI0_MASK,
@@ -474,10 +450,6 @@ static struct clksrc_clk clk_spi1 = {
 		.id		= 1,
 		.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_SPI1_SHIFT,
 	.mask		= S3C6400_CLKSRC_SPI1_MASK,
@@ -520,10 +492,6 @@ static struct clksrc_clk clk_audio0 = {
 		.id		= 0,
 		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_AUDIO0_SHIFT,
 	.mask		= S3C6400_CLKSRC_AUDIO0_MASK,
@@ -551,10 +519,6 @@ static struct clksrc_clk clk_audio1 = {
 		.id		= 1,
 		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_AUDIO1_SHIFT,
 	.mask		= S3C6400_CLKSRC_AUDIO1_MASK,
@@ -569,10 +533,6 @@ static struct clksrc_clk clk_irda = {
 		.id		= 0,
 		.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= S3C6400_CLKSRC_IRDA_SHIFT,
 	.mask		= S3C6400_CLKSRC_IRDA_MASK,
@@ -596,10 +556,6 @@ static struct clksrc_clk clk_camif = {
 		.id		= -1,
 		.ctrlbit        = S3C_CLKCON_SCLK_CAM,
 		.enable		= s3c64xx_sclk_ctrl,
-		.set_parent	= s3c64xx_setparent_clksrc,
-		.get_rate	= s3c64xx_getrate_clksrc,
-		.set_rate	= s3c64xx_setrate_clksrc,
-		.round_rate	= s3c64xx_roundrate_clksrc,
 	},
 	.shift		= 0,
 	.mask		= 0,
@@ -641,6 +597,11 @@ static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
 		return;
 	}
 
+	clk->clk.get_rate = s3c64xx_getrate_clksrc;
+	clk->clk.set_rate = s3c64xx_setrate_clksrc;
+	clk->clk.set_parent = s3c64xx_setparent_clksrc;
+	clk->clk.round_rate = s3c64xx_roundrate_clksrc;
+
 	clk->clk.parent = srcs->sources[clksrc];
 
 	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: S3C64XX: Compress s3c6400-clock.c code
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Move <plat/clock.h> to plat-samsung Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Cleanup common init code in s3c6400-clock.c Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Add core clock implementation for clksrc based clocks Ben Dooks
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

The individually named clocks are all static to the code
and thus can be compressed into a single array and then
the array can be referenced. This removes the need for
a seperate array of pointers to clocks.

Fix a minor problem of re-initialising the pointers in
s3c6400_set_clksrc() as this is also called by the cpufreq
code. Move these initialisations to the code that does the
registration.

Based on Harald Welte's original clock changes patch.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c64xx/s3c6400-clock.c |  334 +++++++++++++++------------------
 1 files changed, 154 insertions(+), 180 deletions(-)

diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index 5882470..a07e5c9 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -259,7 +259,6 @@ static struct clk_sources clkset_uhost = {
 	.nr_sources	= ARRAY_SIZE(clkset_uhost_list),
 };
 
-
 /* The peripheral clocks are all controlled via clocksource followed
  * by an optional divider and gate stage. We currently roll this into
  * one clock which hides the intermediate clock from the mux.
@@ -358,105 +357,7 @@ static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk,
 	return rate;
 }
 
-static struct clksrc_clk clk_mmc0 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_MMC0_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC0_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc1 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_MMC1_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC1_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_mmc2 = {
-	.clk	= {
-		.name		= "mmc_bus",
-		.id		= 2,
-		.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_MMC2_SHIFT,
-	.mask		= S3C6400_CLKSRC_MMC2_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV1_MMC2_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_usbhost = {
-	.clk	= {
-		.name		= "usb-bus-host",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_UHOST_SHIFT,
-	.mask		= S3C6400_CLKSRC_UHOST_MASK,
-	.sources	= &clkset_uhost,
-	.divider_shift	= S3C6400_CLKDIV1_UHOST_SHIFT,
-	.reg_divider	= S3C_CLK_DIV1,
-};
-
-static struct clksrc_clk clk_uart_uclk1 = {
-	.clk	= {
-		.name		= "uclk1",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_UART,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_UART_SHIFT,
-	.mask		= S3C6400_CLKSRC_UART_MASK,
-	.sources	= &clkset_uart,
-	.divider_shift	= S3C6400_CLKDIV2_UART_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-/* Where does UCLK0 come from? */
-
-static struct clksrc_clk clk_spi0 = {
-	.clk	= {
-		.name		= "spi-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_SPI0_SHIFT,
-	.mask		= S3C6400_CLKSRC_SPI0_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV2_SPI0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_spi1 = {
-	.clk	= {
-		.name		= "spi-bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_SPI1_SHIFT,
-	.mask		= S3C6400_CLKSRC_SPI1_MASK,
-	.sources	= &clkset_spi_mmc,
-	.divider_shift	= S3C6400_CLKDIV2_SPI1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
+/* clocks that feed other parts of the clock source tree */
 
 static struct clk clk_iis_cd0 = {
 	.name		= "iis_cdclk0",
@@ -486,20 +387,6 @@ static struct clk_sources clkset_audio0 = {
 	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
 };
 
-static struct clksrc_clk clk_audio0 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_AUDIO0_SHIFT,
-	.mask		= S3C6400_CLKSRC_AUDIO0_MASK,
-	.sources	= &clkset_audio0,
-	.divider_shift	= S3C6400_CLKDIV2_AUDIO0_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
 static struct clk *clkset_audio1_list[] = {
 	[0] = &clk_mout_epll.clk,
 	[1] = &clk_dout_mpll,
@@ -513,34 +400,6 @@ static struct clk_sources clkset_audio1 = {
 	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
 };
 
-static struct clksrc_clk clk_audio1 = {
-	.clk	= {
-		.name		= "audio-bus",
-		.id		= 1,
-		.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_AUDIO1_SHIFT,
-	.mask		= S3C6400_CLKSRC_AUDIO1_MASK,
-	.sources	= &clkset_audio1,
-	.divider_shift	= S3C6400_CLKDIV2_AUDIO1_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
-static struct clksrc_clk clk_irda = {
-	.clk	= {
-		.name		= "irda-bus",
-		.id		= 0,
-		.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
-		.enable		= s3c64xx_sclk_ctrl,
-	},
-	.shift		= S3C6400_CLKSRC_IRDA_SHIFT,
-	.mask		= S3C6400_CLKSRC_IRDA_MASK,
-	.sources	= &clkset_irda,
-	.divider_shift	= S3C6400_CLKDIV2_IRDA_SHIFT,
-	.reg_divider	= S3C_CLK_DIV2,
-};
-
 static struct clk *clkset_camif_list[] = {
 	&clk_h2,
 };
@@ -550,18 +409,141 @@ static struct clk_sources clkset_camif = {
 	.nr_sources	= ARRAY_SIZE(clkset_camif_list),
 };
 
-static struct clksrc_clk clk_camif = {
-	.clk	= {
-		.name		= "camera",
-		.id		= -1,
-		.ctrlbit        = S3C_CLKCON_SCLK_CAM,
-		.enable		= s3c64xx_sclk_ctrl,
+static struct clksrc_clk clksrcs[] = {
+	{
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_MMC0_SHIFT,
+		.mask		= S3C6400_CLKSRC_MMC0_MASK,
+		.sources	= &clkset_spi_mmc,
+		.divider_shift	= S3C6400_CLKDIV1_MMC0_SHIFT,
+		.reg_divider	= S3C_CLK_DIV1,
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_MMC1_SHIFT,
+		.mask		= S3C6400_CLKSRC_MMC1_MASK,
+		.sources	= &clkset_spi_mmc,
+		.divider_shift	= S3C6400_CLKDIV1_MMC1_SHIFT,
+		.reg_divider	= S3C_CLK_DIV1,
+	}, {
+		.clk	= {
+			.name		= "mmc_bus",
+			.id		= 2,
+			.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_MMC2_SHIFT,
+		.mask		= S3C6400_CLKSRC_MMC2_MASK,
+		.sources	= &clkset_spi_mmc,
+		.divider_shift	= S3C6400_CLKDIV1_MMC2_SHIFT,
+		.reg_divider	= S3C_CLK_DIV1,
+	}, {
+		.clk	= {
+			.name		= "usb-bus-host",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_UHOST_SHIFT,
+		.mask		= S3C6400_CLKSRC_UHOST_MASK,
+		.sources	= &clkset_uhost,
+		.divider_shift	= S3C6400_CLKDIV1_UHOST_SHIFT,
+		.reg_divider	= S3C_CLK_DIV1,
+	}, {
+		.clk	= {
+			.name		= "uclk1",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_UART,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_UART_SHIFT,
+		.mask		= S3C6400_CLKSRC_UART_MASK,
+		.sources	= &clkset_uart,
+		.divider_shift	= S3C6400_CLKDIV2_UART_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+/* Where does UCLK0 come from? */
+		.clk	= {
+			.name		= "spi-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_SPI0_SHIFT,
+		.mask		= S3C6400_CLKSRC_SPI0_MASK,
+		.sources	= &clkset_spi_mmc,
+		.divider_shift	= S3C6400_CLKDIV2_SPI0_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+		.clk	= {
+			.name		= "spi-bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_SPI1_SHIFT,
+		.mask		= S3C6400_CLKSRC_SPI1_MASK,
+		.sources	= &clkset_spi_mmc,
+		.divider_shift	= S3C6400_CLKDIV2_SPI1_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_AUDIO0_SHIFT,
+		.mask		= S3C6400_CLKSRC_AUDIO0_MASK,
+		.sources	= &clkset_audio0,
+		.divider_shift	= S3C6400_CLKDIV2_AUDIO0_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+		.clk	= {
+			.name		= "audio-bus",
+			.id		= 1,
+			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_AUDIO1_SHIFT,
+		.mask		= S3C6400_CLKSRC_AUDIO1_MASK,
+		.sources	= &clkset_audio1,
+		.divider_shift	= S3C6400_CLKDIV2_AUDIO1_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+		.clk	= {
+			.name		= "irda-bus",
+			.id		= 0,
+			.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= S3C6400_CLKSRC_IRDA_SHIFT,
+		.mask		= S3C6400_CLKSRC_IRDA_MASK,
+		.sources	= &clkset_irda,
+		.divider_shift	= S3C6400_CLKDIV2_IRDA_SHIFT,
+		.reg_divider	= S3C_CLK_DIV2,
+	}, {
+		.clk	= {
+			.name		= "camera",
+			.id		= -1,
+			.ctrlbit        = S3C_CLKCON_SCLK_CAM,
+			.enable		= s3c64xx_sclk_ctrl,
+		},
+		.shift		= 0,
+		.mask		= 0,
+		.sources	= &clkset_camif,
+		.divider_shift	= S3C6400_CLKDIV0_CAM_SHIFT,
+		.reg_divider	= S3C_CLK_DIV0,
 	},
-	.shift		= 0,
-	.mask		= 0,
-	.sources	= &clkset_camif,
-	.divider_shift	= S3C6400_CLKDIV0_CAM_SHIFT,
-	.reg_divider	= S3C_CLK_DIV0,
 };
 
 /* Clock initialisation code */
@@ -570,17 +552,6 @@ static struct clksrc_clk *init_parents[] = {
 	&clk_mout_apll,
 	&clk_mout_epll,
 	&clk_mout_mpll,
-	&clk_mmc0,
-	&clk_mmc1,
-	&clk_mmc2,
-	&clk_usbhost,
-	&clk_uart_uclk1,
-	&clk_spi0,
-	&clk_spi1,
-	&clk_audio0,
-	&clk_audio1,
-	&clk_irda,
-	&clk_camif,
 };
 
 static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
@@ -597,11 +568,6 @@ static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
 		return;
 	}
 
-	clk->clk.get_rate = s3c64xx_getrate_clksrc;
-	clk->clk.set_rate = s3c64xx_setrate_clksrc;
-	clk->clk.set_parent = s3c64xx_setparent_clksrc;
-	clk->clk.round_rate = s3c64xx_roundrate_clksrc;
-
 	clk->clk.parent = srcs->sources[clksrc];
 
 	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
@@ -668,6 +634,9 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
 		s3c6400_set_clksrc(init_parents[ptr]);
+
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
+		s3c6400_set_clksrc(&clksrcs[ptr]);
 }
 
 static struct clk *clks[] __initdata = {
@@ -679,17 +648,6 @@ static struct clk *clks[] __initdata = {
 	&clk_fout_epll,
 	&clk_mout_mpll.clk,
 	&clk_dout_mpll,
-	&clk_mmc0.clk,
-	&clk_mmc1.clk,
-	&clk_mmc2.clk,
-	&clk_usbhost.clk,
-	&clk_uart_uclk1.clk,
-	&clk_spi0.clk,
-	&clk_spi1.clk,
-	&clk_audio0.clk,
-	&clk_audio1.clk,
-	&clk_irda.clk,
-	&clk_camif.clk,
 	&clk_arm,
 };
 
@@ -722,6 +680,22 @@ void __init s3c6400_register_clocks(unsigned armclk_divlimit)
 		}
 	}
 
+	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) {
+		clkp = &clksrcs[ptr].clk;
+
+		/* all clksrc clocks have these */
+		clkp->get_rate = s3c64xx_getrate_clksrc;
+		clkp->set_rate = s3c64xx_setrate_clksrc;
+		clkp->set_parent = s3c64xx_setparent_clksrc;
+		clkp->round_rate = s3c64xx_roundrate_clksrc;
+
+		ret = s3c24xx_register_clock(clkp);
+		if (ret < 0) {
+			printk(KERN_ERR "Failed to register clock %s (%d)\n",
+			       clkp->name, ret);
+		}
+	}
+
 	clk_mpll.parent = &clk_mout_mpll.clk;
 	clk_epll.parent = &clk_mout_epll.clk;
 }
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: SAMSUNG: Add core clock implementation for clksrc based clocks
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
                   ` (2 preceding siblings ...)
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Compress s3c6400-clock.c code Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Use new clock-clksrc.c code for clocks Ben Dooks
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

From: Harald Welte <laforge@gnumonks.org>

Add a core for the clksrc clock implementation, which is found in many of
the newer Samsung SoCs into plat-samsung.

Signed-off-by: Harald Welte <laforge@gnumonks.org>
[ben-linux at fluff.org: split from original patch to make change smaller]
[ben-linux at fluff.org: split clk and clksrc changes]
[ben-linux at fluff.org: moved to plat-samsung from plat-s3c]
[ben-linux at fluff.org: re-wrote headers after splits]
[ben-linux at fluff.org: added better documentation to headers]
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-samsung/Kconfig                     |    5 +
 arch/arm/plat-samsung/Makefile                    |    1 +
 arch/arm/plat-samsung/clock-clksrc.c              |  177 +++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/clock-clksrc.h |   75 +++++++++
 4 files changed, 258 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-samsung/clock-clksrc.c
 create mode 100644 arch/arm/plat-samsung/include/plat/clock-clksrc.h

diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 486a0d6..e3ae684 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -13,5 +13,10 @@ config PLAT_SAMSUNG
 
 if PLAT_SAMSUNG
 
+config SAMSUNG_CLKSRC
+	bool
+	help
+	  Select the clock code for the clksrc implementation
+	  used by newer systems such as the S3C64XX.
 
 endif
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 4478b9f..ce736ce 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -9,3 +9,4 @@ obj-m				:=
 obj-n				:= dummy.o
 obj-				:=
 
+obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c
new file mode 100644
index 0000000..5872f0b
--- /dev/null
+++ b/arch/arm/plat-samsung/clock-clksrc.c
@@ -0,0 +1,177 @@
+/* linux/arch/arm/plat-samsung/clock-clksrc.c
+ *
+ * Copyright 2008 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	http://armlinux.simtec.co.uk/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/sysdev.h>
+#include <linux/io.h>
+
+#include <plat/clock.h>
+#include <plat/clock-clksrc.h>
+#include <plat/cpu-freq.h>
+
+static inline struct clksrc_clk *to_clksrc(struct clk *clk)
+{
+	return container_of(clk, struct clksrc_clk, clk);
+}
+
+static inline u32 bit_mask(u32 shift, u32 nr_bits)
+{
+	u32 mask = 0xffffffff >> (32 - nr_bits);
+
+	return mask << shift;
+}
+
+static unsigned long s3c_getrate_clksrc(struct clk *clk)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	unsigned long rate = clk_get_rate(clk->parent);
+	u32 clkdiv = __raw_readl(sclk->reg_div.reg);
+	u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+
+	clkdiv &= mask;
+	clkdiv >>= sclk->reg_div.shift;
+	clkdiv++;
+
+	rate /= clkdiv;
+	return rate;
+}
+
+static int s3c_setrate_clksrc(struct clk *clk, unsigned long rate)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	void __iomem *reg = sclk->reg_div.reg;
+	unsigned int div;
+	u32 mask = bit_mask(sclk->reg_div.shift, sclk->reg_div.size);
+	u32 val;
+
+	rate = clk_round_rate(clk, rate);
+	div = clk_get_rate(clk->parent) / rate;
+	if (div > 16)
+		return -EINVAL;
+
+	val = __raw_readl(reg);
+	val &= ~mask;
+	val |= (div - 1) << sclk->reg_div.shift;
+	__raw_writel(val, reg);
+
+	return 0;
+}
+
+static int s3c_setparent_clksrc(struct clk *clk, struct clk *parent)
+{
+	struct clksrc_clk *sclk = to_clksrc(clk);
+	struct clksrc_sources *srcs = sclk->sources;
+	u32 clksrc = __raw_readl(sclk->reg_src.reg);
+	u32 mask = bit_mask(sclk->reg_src.shift, sclk->reg_src.size);
+	int src_nr = -1;
+	int ptr;
+
+	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
+		if (srcs->sources[ptr] == parent) {
+			src_nr = ptr;
+			break;
+		}
+
+	if (src_nr >= 0 && sclk->reg_src.reg) {
+		clk->parent = parent;
+
+		clksrc &= ~mask;
+		clksrc |= src_nr << sclk->reg_src.shift;
+
+		__raw_writel(clksrc, sclk->reg_src.reg);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static unsigned long s3c_roundrate_clksrc(struct clk *clk,
+					      unsigned long rate)
+{
+	unsigned long parent_rate = clk_get_rate(clk->parent);
+	int div;
+
+	if (rate >= parent_rate)
+		rate = parent_rate;
+	else {
+		div = parent_rate / rate;
+		if (parent_rate % rate)
+			div++;
+
+		if (div == 0)
+			div = 1;
+		if (div > 16)
+			div = 16;
+
+		rate = parent_rate / div;
+	}
+
+	return rate;
+}
+
+/* Clock initialisation code */
+
+void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk)
+{
+	struct clksrc_sources *srcs = clk->sources;
+	u32 mask = bit_mask(clk->reg_src.shift, clk->reg_src.size);
+	u32 clksrc = 0;
+
+	if (clk->reg_src.reg)
+		clksrc = __raw_readl(clk->reg_src.reg);
+
+	clksrc &= mask;
+	clksrc >>= clk->reg_src.shift;
+
+	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
+		printk(KERN_ERR "%s: bad source %d\n",
+		       clk->clk.name, clksrc);
+		return;
+	}
+
+	clk->clk.parent = srcs->sources[clksrc];
+
+	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
+	       clk->clk.name, clk->clk.parent->name, clksrc,
+	       clk_get_rate(&clk->clk));
+}
+
+void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size)
+{
+	int ret;
+
+	for (; size > 0; size--, clksrc++) {
+		/* fill in the default functions */
+		if (!clksrc->clk.set_parent)
+			clksrc->clk.set_parent = s3c_setparent_clksrc;
+		if (!clksrc->clk.get_rate)
+			clksrc->clk.get_rate = s3c_getrate_clksrc;
+		if (!clksrc->clk.set_rate)
+			clksrc->clk.set_rate = s3c_setrate_clksrc;
+		if (!clksrc->clk.round_rate)
+			clksrc->clk.round_rate = s3c_roundrate_clksrc;
+
+		s3c_set_clksrc(clksrc);
+
+		ret = s3c24xx_register_clock(&clksrc->clk);
+
+		if (ret < 0) {
+			printk(KERN_ERR "%s: failed to register %s (%d)\n",
+			       __func__, clksrc->clk.name, ret);
+		}
+	}
+}
diff --git a/arch/arm/plat-samsung/include/plat/clock-clksrc.h b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
new file mode 100644
index 0000000..283dfa0
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/clock-clksrc.h
@@ -0,0 +1,75 @@
+/* linux/arch/arm/plat-samsung/include/plat/clock-clksrc.h
+ *
+ * Parts taken from arch/arm/plat-s3c64xx/clock.c
+ *	Copyright 2008 Openmoko, Inc.
+ *	Copyright 2008 Simtec Electronics
+ *		Ben Dooks <ben@simtec.co.uk>
+ *		http://armlinux.simtec.co.uk/
+ *
+ * Copyright 2009 Ben Dooks <ben-linux@fluff.org>
+ * Copyright 2009 Harald Welte
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/**
+ * struct clksrc_sources - list of sources for a given clock
+ * @sources: array of pointers to clocks
+ * @nr_sources: The size of @sources
+ */
+struct clksrc_sources {
+	unsigned int	nr_sources;
+	struct clk	**sources;
+};
+
+/**
+ * struct clksrc_reg - register definition for clock control bits
+ * @reg: pointer to the register in virtual memory.
+ * @shift: the shift in bits to where the bitfield is.
+ * @size: the size in bits of the bitfield.
+ *
+ * This specifies the size and position of the bits we are interested
+ * in within the register specified by @reg.
+ */
+struct clksrc_reg {
+	void __iomem		*reg;
+	unsigned short		shift;
+	unsigned short		size;
+};
+
+/**
+ * struct clksrc_clk - class of clock for newer style samsung devices.
+ * @clk: the standard clock representation
+ * @sources: the sources for this clock
+ * @reg_src: the register definition for selecting the clock's source
+ * @reg_div: the register definition for the clock's output divisor
+ *
+ * This clock implements the features required by the newer SoCs where
+ * the standard clock block provides an input mux and a post-mux divisor
+ * to provide the periperhal's clock.
+ *
+ * The array of @sources provides the mapping of mux position to the
+ * clock, and @reg_src shows the code where to modify to change the mux
+ * position. The @reg_div defines how to change the divider settings on
+ * the output.
+ */
+struct clksrc_clk {
+	struct clk		clk;
+	struct clksrc_sources	*sources;
+
+	struct clksrc_reg	reg_src;
+	struct clksrc_reg	reg_div;
+};
+
+extern void s3c_set_clksrc(struct clksrc_clk *clk);
+
+/**
+ * s3c_register_clksrc() register clocks from an array of clksrc clocks
+ * @srcs: The array of clocks to register
+ * @size: The size of the @srcs array.
+ *
+ * Initialise and register the array of clocks described by @srcs.
+ */
+extern void s3c_register_clksrc(struct clksrc_clk *srcs, int size);
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: S3C64XX: Use new clock-clksrc.c code for clocks.
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
                   ` (3 preceding siblings ...)
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Add core clock implementation for clksrc based clocks Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Remove unused clock definitions from clock header Ben Dooks
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Move the s3c6400-clock.c implementation over to use the new common
plat-samsung based clock-clksrc.c.

Note, this does not delete the clocks definitions that are now unused
in the regs-clock.h to reduce the quantity of change in this commit.

Based on original patches by Harald Welte.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c64xx/Kconfig         |    1 +
 arch/arm/plat-s3c64xx/s3c6400-clock.c |  241 ++++++---------------------------
 2 files changed, 40 insertions(+), 202 deletions(-)

diff --git a/arch/arm/plat-s3c64xx/Kconfig b/arch/arm/plat-s3c64xx/Kconfig
index bcfa778..f029697 100644
--- a/arch/arm/plat-s3c64xx/Kconfig
+++ b/arch/arm/plat-s3c64xx/Kconfig
@@ -15,6 +15,7 @@ config PLAT_S3C64XX
 	select ARM_VIC
 	select NO_IOPORT
 	select ARCH_REQUIRE_GPIOLIB
+	select SAMSUNG_CLKSRC
 	select S3C_GPIO_TRACK
 	select S3C_GPIO_PULL_UPDOWN
 	select S3C_GPIO_CFG_S3C24XX
diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index a07e5c9..adc2e0a 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -29,6 +29,7 @@
 
 #include <plat/regs-clock.h>
 #include <plat/clock.h>
+#include <plat/clock-clksrc.h>
 #include <plat/cpu.h>
 #include <plat/pll.h>
 
@@ -47,22 +48,6 @@ static struct clk clk_ext_xtal_mux = {
 
 #define clk_fout_mpll	clk_mpll
 
-struct clk_sources {
-	unsigned int	nr_sources;
-	struct clk	**sources;
-};
-
-struct clksrc_clk {
-	struct clk		clk;
-	unsigned int		mask;
-	unsigned int		shift;
-
-	struct clk_sources	*sources;
-
-	unsigned int		divider_shift;
-	void __iomem		*reg_divider;
-};
-
 static struct clk clk_fout_apll = {
 	.name		= "fout_apll",
 	.id		= -1,
@@ -73,7 +58,7 @@ static struct clk *clk_src_apll_list[] = {
 	[1] = &clk_fout_apll,
 };
 
-static struct clk_sources clk_src_apll = {
+static struct clksrc_sources clk_src_apll = {
 	.sources	= clk_src_apll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_apll_list),
 };
@@ -83,8 +68,7 @@ static struct clksrc_clk clk_mout_apll = {
 		.name		= "mout_apll",
 		.id		= -1,
 	},
-	.shift		= S3C6400_CLKSRC_APLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_APLL_MOUT,
+	.reg_src	= { S3C_CLK_SRC, 0, 1 },
 	.sources	= &clk_src_apll,
 };
 
@@ -98,7 +82,7 @@ static struct clk *clk_src_epll_list[] = {
 	[1] = &clk_fout_epll,
 };
 
-static struct clk_sources clk_src_epll = {
+static struct clksrc_sources clk_src_epll = {
 	.sources	= clk_src_epll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_epll_list),
 };
@@ -108,8 +92,7 @@ static struct clksrc_clk clk_mout_epll = {
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.shift		= S3C6400_CLKSRC_EPLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_EPLL_MOUT,
+	.reg_src	= { S3C_CLK_SRC, 2, 1 },
 	.sources	= &clk_src_epll,
 };
 
@@ -118,7 +101,7 @@ static struct clk *clk_src_mpll_list[] = {
 	[1] = &clk_fout_mpll,
 };
 
-static struct clk_sources clk_src_mpll = {
+static struct clksrc_sources clk_src_mpll = {
 	.sources	= clk_src_mpll_list,
 	.nr_sources	= ARRAY_SIZE(clk_src_mpll_list),
 };
@@ -128,8 +111,7 @@ static struct clksrc_clk clk_mout_mpll = {
 		.name		= "mout_mpll",
 		.id		= -1,
 	},
-	.shift		= S3C6400_CLKSRC_MPLL_MOUT_SHIFT,
-	.mask		= S3C6400_CLKSRC_MPLL_MOUT,
+	.reg_src	= { S3C_CLK_SRC, 1, 1 },
 	.sources	= &clk_src_mpll,
 };
 
@@ -218,7 +200,7 @@ static struct clk *clkset_spi_mmc_list[] = {
 	&clk_27m,
 };
 
-static struct clk_sources clkset_spi_mmc = {
+static struct clksrc_sources clkset_spi_mmc = {
 	.sources	= clkset_spi_mmc_list,
 	.nr_sources	= ARRAY_SIZE(clkset_spi_mmc_list),
 };
@@ -230,7 +212,7 @@ static struct clk *clkset_irda_list[] = {
 	&clk_27m,
 };
 
-static struct clk_sources clkset_irda = {
+static struct clksrc_sources clkset_irda = {
 	.sources	= clkset_irda_list,
 	.nr_sources	= ARRAY_SIZE(clkset_irda_list),
 };
@@ -242,7 +224,7 @@ static struct clk *clkset_uart_list[] = {
 	NULL
 };
 
-static struct clk_sources clkset_uart = {
+static struct clksrc_sources clkset_uart = {
 	.sources	= clkset_uart_list,
 	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
 };
@@ -254,7 +236,7 @@ static struct clk *clkset_uhost_list[] = {
 	&clk_fin_epll,
 };
 
-static struct clk_sources clkset_uhost = {
+static struct clksrc_sources clkset_uhost = {
 	.sources	= clkset_uhost_list,
 	.nr_sources	= ARRAY_SIZE(clkset_uhost_list),
 };
@@ -269,94 +251,6 @@ static struct clk_sources clkset_uhost = {
  * have a common parent divisor so are not included here.
  */
 
-static inline struct clksrc_clk *to_clksrc(struct clk *clk)
-{
-	return container_of(clk, struct clksrc_clk, clk);
-}
-
-static unsigned long s3c64xx_getrate_clksrc(struct clk *clk)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	unsigned long rate = clk_get_rate(clk->parent);
-	u32 clkdiv = __raw_readl(sclk->reg_divider);
-
-	clkdiv >>= sclk->divider_shift;
-	clkdiv &= 0xf;
-	clkdiv++;
-
-	rate /= clkdiv;
-	return rate;
-}
-
-static int s3c64xx_setrate_clksrc(struct clk *clk, unsigned long rate)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	void __iomem *reg = sclk->reg_divider;
-	unsigned int div;
-	u32 val;
-
-	rate = clk_round_rate(clk, rate);
-	div = clk_get_rate(clk->parent) / rate;
-	if (div > 16)
-		return -EINVAL;
-
-	val = __raw_readl(reg);
-	val &= ~(0xf << sclk->divider_shift);
-	val |= (div - 1) << sclk->divider_shift;
-	__raw_writel(val, reg);
-
-	return 0;
-}
-
-static int s3c64xx_setparent_clksrc(struct clk *clk, struct clk *parent)
-{
-	struct clksrc_clk *sclk = to_clksrc(clk);
-	struct clk_sources *srcs = sclk->sources;
-	u32 clksrc = __raw_readl(S3C_CLK_SRC);
-	int src_nr = -1;
-	int ptr;
-
-	for (ptr = 0; ptr < srcs->nr_sources; ptr++)
-		if (srcs->sources[ptr] == parent) {
-			src_nr = ptr;
-			break;
-		}
-
-	if (src_nr >= 0) {
-		clksrc &= ~sclk->mask;
-		clksrc |= src_nr << sclk->shift;
-
-		__raw_writel(clksrc, S3C_CLK_SRC);
-
-		clk->parent = parent;
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static unsigned long s3c64xx_roundrate_clksrc(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		rate = parent_rate;
-	else {
-		div = parent_rate / rate;
-
-		if (div == 0)
-			div = 1;
-		if (div > 16)
-			div = 16;
-
-		rate = parent_rate / div;
-	}
-
-	return rate;
-}
-
 /* clocks that feed other parts of the clock source tree */
 
 static struct clk clk_iis_cd0 = {
@@ -382,7 +276,7 @@ static struct clk *clkset_audio0_list[] = {
 	[4] = &clk_pcm_cd,
 };
 
-static struct clk_sources clkset_audio0 = {
+static struct clksrc_sources clkset_audio0 = {
 	.sources	= clkset_audio0_list,
 	.nr_sources	= ARRAY_SIZE(clkset_audio0_list),
 };
@@ -395,7 +289,7 @@ static struct clk *clkset_audio1_list[] = {
 	[4] = &clk_pcm_cd,
 };
 
-static struct clk_sources clkset_audio1 = {
+static struct clksrc_sources clkset_audio1 = {
 	.sources	= clkset_audio1_list,
 	.nr_sources	= ARRAY_SIZE(clkset_audio1_list),
 };
@@ -404,7 +298,7 @@ static struct clk *clkset_camif_list[] = {
 	&clk_h2,
 };
 
-static struct clk_sources clkset_camif = {
+static struct clksrc_sources clkset_camif = {
 	.sources	= clkset_camif_list,
 	.nr_sources	= ARRAY_SIZE(clkset_camif_list),
 };
@@ -417,11 +311,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_MMC0_SHIFT,
-		.mask		= S3C6400_CLKSRC_MMC0_MASK,
+		.reg_src	= { S3C_CLK_SRC, 18, 2 },
+		.reg_div	= { S3C_CLK_DIV1, 0, 4 },
 		.sources	= &clkset_spi_mmc,
-		.divider_shift	= S3C6400_CLKDIV1_MMC0_SHIFT,
-		.reg_divider	= S3C_CLK_DIV1,
 	}, {
 		.clk	= {
 			.name		= "mmc_bus",
@@ -429,11 +321,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_MMC1_SHIFT,
-		.mask		= S3C6400_CLKSRC_MMC1_MASK,
+		.reg_src	= { S3C_CLK_SRC, 20, 2 },
+		.reg_div	= { S3C_CLK_DIV1, 4, 4 },
 		.sources	= &clkset_spi_mmc,
-		.divider_shift	= S3C6400_CLKDIV1_MMC1_SHIFT,
-		.reg_divider	= S3C_CLK_DIV1,
 	}, {
 		.clk	= {
 			.name		= "mmc_bus",
@@ -441,11 +331,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_MMC2_SHIFT,
-		.mask		= S3C6400_CLKSRC_MMC2_MASK,
+		.reg_src	= { S3C_CLK_SRC, 22, 2 },
+		.reg_div 	= { S3C_CLK_DIV1, 8, 4 },
 		.sources	= &clkset_spi_mmc,
-		.divider_shift	= S3C6400_CLKDIV1_MMC2_SHIFT,
-		.reg_divider	= S3C_CLK_DIV1,
 	}, {
 		.clk	= {
 			.name		= "usb-bus-host",
@@ -453,11 +341,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_UHOST_SHIFT,
-		.mask		= S3C6400_CLKSRC_UHOST_MASK,
+		.reg_src 	= { S3C_CLK_SRC, 5, 2 },
+		.reg_div	= { S3C_CLK_DIV1, 20, 4 },
 		.sources	= &clkset_uhost,
-		.divider_shift	= S3C6400_CLKDIV1_UHOST_SHIFT,
-		.reg_divider	= S3C_CLK_DIV1,
 	}, {
 		.clk	= {
 			.name		= "uclk1",
@@ -465,11 +351,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_UART,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_UART_SHIFT,
-		.mask		= S3C6400_CLKSRC_UART_MASK,
+		.reg_src	= { S3C_CLK_SRC, 13, 1 },
+		.reg_div	= { S3C_CLK_DIV2, 16, 4 },
 		.sources	= &clkset_uart,
-		.divider_shift	= S3C6400_CLKDIV2_UART_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 /* Where does UCLK0 come from? */
 		.clk	= {
@@ -478,11 +362,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_SPI0_SHIFT,
-		.mask		= S3C6400_CLKSRC_SPI0_MASK,
+		.reg_src	= { S3C_CLK_SRC, 14, 2 },
+		.reg_div	= { S3C_CLK_DIV2, 0, 4 },
 		.sources	= &clkset_spi_mmc,
-		.divider_shift	= S3C6400_CLKDIV2_SPI0_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 		.clk	= {
 			.name		= "spi-bus",
@@ -490,11 +372,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_SPI1_SHIFT,
-		.mask		= S3C6400_CLKSRC_SPI1_MASK,
+		.reg_src	= { S3C_CLK_SRC, 16, 2 },
+		.reg_div	= { S3C_CLK_DIV2, 4, 4 },
 		.sources	= &clkset_spi_mmc,
-		.divider_shift	= S3C6400_CLKDIV2_SPI1_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 		.clk	= {
 			.name		= "audio-bus",
@@ -502,11 +382,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_AUDIO0_SHIFT,
-		.mask		= S3C6400_CLKSRC_AUDIO0_MASK,
+		.reg_src	= { S3C_CLK_SRC, 7, 3 },
+		.reg_div	= { S3C_CLK_DIV2, 8, 4 },
 		.sources	= &clkset_audio0,
-		.divider_shift	= S3C6400_CLKDIV2_AUDIO0_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 		.clk	= {
 			.name		= "audio-bus",
@@ -514,11 +392,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_AUDIO1_SHIFT,
-		.mask		= S3C6400_CLKSRC_AUDIO1_MASK,
+		.reg_src	= { S3C_CLK_SRC, 10, 3 },
+		.reg_div	= { S3C_CLK_DIV2, 12, 4 },
 		.sources	= &clkset_audio1,
-		.divider_shift	= S3C6400_CLKDIV2_AUDIO1_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 		.clk	= {
 			.name		= "irda-bus",
@@ -526,11 +402,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= S3C6400_CLKSRC_IRDA_SHIFT,
-		.mask		= S3C6400_CLKSRC_IRDA_MASK,
+		.reg_src	= { S3C_CLK_SRC, 24, 2 },
+		.reg_div	= { S3C_CLK_DIV2, 20, 4 },
 		.sources	= &clkset_irda,
-		.divider_shift	= S3C6400_CLKDIV2_IRDA_SHIFT,
-		.reg_divider	= S3C_CLK_DIV2,
 	}, {
 		.clk	= {
 			.name		= "camera",
@@ -538,11 +412,9 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_CAM,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.shift		= 0,
-		.mask		= 0,
+		.reg_div	= { S3C_CLK_DIV0, 20, 4 },
+		.reg_src	= { NULL, 0, 0 },
 		.sources	= &clkset_camif,
-		.divider_shift	= S3C6400_CLKDIV0_CAM_SHIFT,
-		.reg_divider	= S3C_CLK_DIV0,
 	},
 };
 
@@ -554,27 +426,6 @@ static struct clksrc_clk *init_parents[] = {
 	&clk_mout_mpll,
 };
 
-static void __init_or_cpufreq s3c6400_set_clksrc(struct clksrc_clk *clk)
-{
-	struct clk_sources *srcs = clk->sources;
-	u32 clksrc = __raw_readl(S3C_CLK_SRC);
-
-	clksrc &= clk->mask;
-	clksrc >>= clk->shift;
-
-	if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
-		printk(KERN_ERR "%s: bad source %d\n",
-		       clk->clk.name, clksrc);
-		return;
-	}
-
-	clk->clk.parent = srcs->sources[clksrc];
-
-	printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
-	       clk->clk.name, clk->clk.parent->name, clksrc,
-	       clk_get_rate(&clk->clk));
-}
-
 #define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
 
 void __init_or_cpufreq s3c6400_setup_clocks(void)
@@ -633,10 +484,10 @@ void __init_or_cpufreq s3c6400_setup_clocks(void)
 	clk_f.rate = fclk;
 
 	for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
-		s3c6400_set_clksrc(init_parents[ptr]);
+		s3c_set_clksrc(init_parents[ptr]);
 
 	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
-		s3c6400_set_clksrc(&clksrcs[ptr]);
+		s3c_set_clksrc(&clksrcs[ptr]);
 }
 
 static struct clk *clks[] __initdata = {
@@ -680,21 +531,7 @@ void __init s3c6400_register_clocks(unsigned armclk_divlimit)
 		}
 	}
 
-	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) {
-		clkp = &clksrcs[ptr].clk;
-
-		/* all clksrc clocks have these */
-		clkp->get_rate = s3c64xx_getrate_clksrc;
-		clkp->set_rate = s3c64xx_setrate_clksrc;
-		clkp->set_parent = s3c64xx_setparent_clksrc;
-		clkp->round_rate = s3c64xx_roundrate_clksrc;
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
+	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
 
 	clk_mpll.parent = &clk_mout_mpll.clk;
 	clk_epll.parent = &clk_mout_epll.clk;
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: S3C64XX: Remove unused clock definitions from clock header
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
                   ` (4 preceding siblings ...)
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Use new clock-clksrc.c code for clocks Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Reduce size of struct clk Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Fixup .reg_src and .reg_div with named initialisers Ben Dooks
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

From: Harald Welte <laforge@gnumonks.org>

Clean out the definitions we are no longer using after the new clock
code updates.

Signed-off-by: Harald Welte <laforge@gnumonks.org>
[ben-linux at fluff.org: split from initial patch provided]
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c64xx/include/plat/regs-clock.h |   71 +----------------------
 1 files changed, 1 insertions(+), 70 deletions(-)

diff --git a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
index ff46e7f..3ef6274 100644
--- a/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
+++ b/arch/arm/plat-s3c64xx/include/plat/regs-clock.h
@@ -35,14 +35,6 @@
 #define S3C_MEM0_GATE		S3C_CLKREG(0x3C)
 
 /* CLKDIV0 */
-#define S3C6400_CLKDIV0_MFC_MASK	(0xf << 28)
-#define S3C6400_CLKDIV0_MFC_SHIFT	(28)
-#define S3C6400_CLKDIV0_JPEG_MASK	(0xf << 24)
-#define S3C6400_CLKDIV0_JPEG_SHIFT	(24)
-#define S3C6400_CLKDIV0_CAM_MASK	(0xf << 20)
-#define S3C6400_CLKDIV0_CAM_SHIFT	(20)
-#define S3C6400_CLKDIV0_SECURITY_MASK	(0x3 << 18)
-#define S3C6400_CLKDIV0_SECURITY_SHIFT	(18)
 #define S3C6400_CLKDIV0_PCLK_MASK	(0xf << 12)
 #define S3C6400_CLKDIV0_PCLK_SHIFT	(12)
 #define S3C6400_CLKDIV0_HCLK2_MASK	(0x7 << 9)
@@ -51,42 +43,11 @@
 #define S3C6400_CLKDIV0_HCLK_SHIFT	(8)
 #define S3C6400_CLKDIV0_MPLL_MASK	(0x1 << 4)
 #define S3C6400_CLKDIV0_MPLL_SHIFT	(4)
+
 #define S3C6400_CLKDIV0_ARM_MASK	(0x7 << 0)
 #define S3C6410_CLKDIV0_ARM_MASK	(0xf << 0)
 #define S3C6400_CLKDIV0_ARM_SHIFT	(0)
 
-/* CLKDIV1 */
-#define S3C6410_CLKDIV1_FIMC_MASK	(0xf << 24)
-#define S3C6410_CLKDIV1_FIMC_SHIFT	(24)
-#define S3C6400_CLKDIV1_UHOST_MASK	(0xf << 20)
-#define S3C6400_CLKDIV1_UHOST_SHIFT	(20)
-#define S3C6400_CLKDIV1_SCALER_MASK	(0xf << 16)
-#define S3C6400_CLKDIV1_SCALER_SHIFT	(16)
-#define S3C6400_CLKDIV1_LCD_MASK	(0xf << 12)
-#define S3C6400_CLKDIV1_LCD_SHIFT	(12)
-#define S3C6400_CLKDIV1_MMC2_MASK	(0xf << 8)
-#define S3C6400_CLKDIV1_MMC2_SHIFT	(8)
-#define S3C6400_CLKDIV1_MMC1_MASK	(0xf << 4)
-#define S3C6400_CLKDIV1_MMC1_SHIFT	(4)
-#define S3C6400_CLKDIV1_MMC0_MASK	(0xf << 0)
-#define S3C6400_CLKDIV1_MMC0_SHIFT	(0)
-
-/* CLKDIV2 */
-#define S3C6410_CLKDIV2_AUDIO2_MASK	(0xf << 24)
-#define S3C6410_CLKDIV2_AUDIO2_SHIFT	(24)
-#define S3C6400_CLKDIV2_IRDA_MASK	(0xf << 20)
-#define S3C6400_CLKDIV2_IRDA_SHIFT	(20)
-#define S3C6400_CLKDIV2_UART_MASK	(0xf << 16)
-#define S3C6400_CLKDIV2_UART_SHIFT	(16)
-#define S3C6400_CLKDIV2_AUDIO1_MASK	(0xf << 12)
-#define S3C6400_CLKDIV2_AUDIO1_SHIFT	(12)
-#define S3C6400_CLKDIV2_AUDIO0_MASK	(0xf << 8)
-#define S3C6400_CLKDIV2_AUDIO0_SHIFT	(8)
-#define S3C6400_CLKDIV2_SPI1_MASK	(0xf << 4)
-#define S3C6400_CLKDIV2_SPI1_SHIFT	(4)
-#define S3C6400_CLKDIV2_SPI0_MASK	(0xf << 0)
-#define S3C6400_CLKDIV2_SPI0_SHIFT	(0)
-
 /* HCLK GATE Registers */
 #define S3C_CLKCON_HCLK_3DSE	(1<<31)
 #define S3C_CLKCON_HCLK_UHOST	(1<<29)
@@ -192,34 +153,4 @@
 #define S3C6400_CLKSRC_EPLL_MOUT_SHIFT	(2)
 #define S3C6400_CLKSRC_MFC		(1 << 4)
 
-#define S3C6410_CLKSRC_TV27_MASK	(0x1 << 31)
-#define S3C6410_CLKSRC_TV27_SHIFT	(31)
-#define S3C6410_CLKSRC_DAC27_MASK	(0x1 << 30)
-#define S3C6410_CLKSRC_DAC27_SHIFT	(30)
-#define S3C6400_CLKSRC_SCALER_MASK	(0x3 << 28)
-#define S3C6400_CLKSRC_SCALER_SHIFT	(28)
-#define S3C6400_CLKSRC_LCD_MASK		(0x3 << 26)
-#define S3C6400_CLKSRC_LCD_SHIFT	(26)
-#define S3C6400_CLKSRC_IRDA_MASK	(0x3 << 24)
-#define S3C6400_CLKSRC_IRDA_SHIFT	(24)
-#define S3C6400_CLKSRC_MMC2_MASK	(0x3 << 22)
-#define S3C6400_CLKSRC_MMC2_SHIFT	(22)
-#define S3C6400_CLKSRC_MMC1_MASK	(0x3 << 20)
-#define S3C6400_CLKSRC_MMC1_SHIFT	(20)
-#define S3C6400_CLKSRC_MMC0_MASK	(0x3 << 18)
-#define S3C6400_CLKSRC_MMC0_SHIFT	(18)
-#define S3C6400_CLKSRC_SPI1_MASK	(0x3 << 16)
-#define S3C6400_CLKSRC_SPI1_SHIFT	(16)
-#define S3C6400_CLKSRC_SPI0_MASK	(0x3 << 14)
-#define S3C6400_CLKSRC_SPI0_SHIFT	(14)
-#define S3C6400_CLKSRC_UART_MASK	(0x1 << 13)
-#define S3C6400_CLKSRC_UART_SHIFT	(13)
-#define S3C6400_CLKSRC_AUDIO1_MASK	(0x7 << 10)
-#define S3C6400_CLKSRC_AUDIO1_SHIFT	(10)
-#define S3C6400_CLKSRC_AUDIO0_MASK	(0x7 << 7)
-#define S3C6400_CLKSRC_AUDIO0_SHIFT	(7)
-#define S3C6400_CLKSRC_UHOST_MASK	(0x3 << 5)
-#define S3C6400_CLKSRC_UHOST_SHIFT	(5)
-
-
 #endif /* _PLAT_REGS_CLOCK_H */
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: SAMSUNG: Reduce size of struct clk.
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
                   ` (5 preceding siblings ...)
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Remove unused clock definitions from clock header Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Fixup .reg_src and .reg_div with named initialisers Ben Dooks
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Reduce the size of struct clk by 12 bytes and make defining clocks with
common implementation functions easier by moving the set_rate, get_rate,
round_rate and set_parent calls into a new structure called 'struct clk_ops'
and using that instead.

This change does make a few clocks larger as they need their own clk_ops,
but this is outweighed by the number of clocks with either no ops or having
a common set of ops.

Update all the users of this.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/mach-s3c2412/clock.c              |   52 +++++++----
 arch/arm/mach-s3c2440/clock.c              |    6 +-
 arch/arm/mach-s3c2442/clock.c              |    6 +-
 arch/arm/mach-s3c2443/clock.c              |   88 +++++++++++++-------
 arch/arm/plat-s3c/clock.c                  |   31 ++++---
 arch/arm/plat-s3c/pwm-clock.c              |   94 +++++++++++----------
 arch/arm/plat-s3c24xx/clock-dclk.c         |   22 +++--
 arch/arm/plat-s3c24xx/s3c244x-clock.c      |    4 +-
 arch/arm/plat-s3c64xx/s3c6400-clock.c      |   14 ++-
 arch/arm/plat-s5pc1xx/clock.c              |    8 ++-
 arch/arm/plat-s5pc1xx/s5pc100-clock.c      |  126 ++++++++++++----------------
 arch/arm/plat-samsung/clock-clksrc.c       |   17 ++--
 arch/arm/plat-samsung/include/plat/clock.h |   29 ++++++-
 13 files changed, 286 insertions(+), 211 deletions(-)

diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index a037df5..0c0505b 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -124,7 +124,9 @@ static struct clk clk_usysclk = {
 	.name		= "usysclk",
 	.id		= -1,
 	.parent		= &clk_xtal,
-	.set_parent	= s3c2412_setparent_usysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_usysclk,
+	},
 };
 
 static struct clk clk_mrefclk = {
@@ -199,10 +201,12 @@ static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
 static struct clk clk_usbsrc = {
 	.name		= "usbsrc",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_usbsrc,
-	.set_rate	= s3c2412_setrate_usbsrc,
-	.round_rate	= s3c2412_roundrate_usbsrc,
-	.set_parent	= s3c2412_setparent_usbsrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_usbsrc,
+		.set_rate	= s3c2412_setrate_usbsrc,
+		.round_rate	= s3c2412_roundrate_usbsrc,
+		.set_parent	= s3c2412_setparent_usbsrc,
+	},
 };
 
 static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
@@ -225,7 +229,9 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
 static struct clk clk_msysclk = {
 	.name		= "msysclk",
 	.id		= -1,
-	.set_parent	= s3c2412_setparent_msysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_msysclk,
+	},
 };
 
 static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent)
@@ -264,7 +270,9 @@ static struct clk clk_armclk = {
 	.name		= "armclk",
 	.id		= -1,
 	.parent		= &clk_msysclk,
-	.set_parent	= s3c2412_setparent_armclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2412_setparent_armclk,
+	},
 };
 
 /* these next clocks have an divider immediately after them,
@@ -337,10 +345,12 @@ static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
 static struct clk clk_uart = {
 	.name		= "uartclk",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_uart,
-	.set_rate	= s3c2412_setrate_uart,
-	.set_parent	= s3c2412_setparent_uart,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_uart,
+		.set_rate	= s3c2412_setrate_uart,
+		.set_parent	= s3c2412_setparent_uart,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
@@ -388,10 +398,12 @@ static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
 static struct clk clk_i2s = {
 	.name		= "i2sclk",
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_i2s,
-	.set_rate	= s3c2412_setrate_i2s,
-	.set_parent	= s3c2412_setparent_i2s,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_i2s,
+		.set_rate	= s3c2412_setrate_i2s,
+		.set_parent	= s3c2412_setparent_i2s,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
@@ -438,10 +450,12 @@ static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
 static struct clk clk_cam = {
 	.name		= "camif-upll",	/* same as 2440 name */
 	.id		= -1,
-	.get_rate	= s3c2412_getrate_cam,
-	.set_rate	= s3c2412_setrate_cam,
-	.set_parent	= s3c2412_setparent_cam,
-	.round_rate	= s3c2412_roundrate_clksrc,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2412_getrate_cam,
+		.set_rate	= s3c2412_setrate_cam,
+		.set_parent	= s3c2412_setparent_cam,
+		.round_rate	= s3c2412_roundrate_clksrc,
+	},
 };
 
 /* standard clock definitions */
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index d1c29b2..3dc2426 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -98,8 +98,10 @@ static struct clk s3c2440_clk_cam = {
 static struct clk s3c2440_clk_cam_upll = {
 	.name		= "camif-upll",
 	.id		= -1,
-	.set_rate	= s3c2440_camif_upll_setrate,
-	.round_rate	= s3c2440_camif_upll_round,
+	.ops		= &(struct clk_ops) {
+		.set_rate	= s3c2440_camif_upll_setrate,
+		.round_rate	= s3c2440_camif_upll_round,
+	},
 };
 
 static struct clk s3c2440_clk_ac97 = {
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
index ea1aa1f..d9b692a 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -109,8 +109,10 @@ static struct clk s3c2442_clk_cam = {
 static struct clk s3c2442_clk_cam_upll = {
 	.name		= "camif-upll",
 	.id		= -1,
-	.set_rate	= s3c2442_camif_upll_setrate,
-	.round_rate	= s3c2442_camif_upll_round,
+	.ops		= &(struct clk_ops) {
+		.set_rate	= s3c2442_camif_upll_setrate,
+		.round_rate	= s3c2442_camif_upll_round,
+	},
 };
 
 static int s3c2442_clk_add(struct sys_device *sysdev)
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 2785d69..91db4f5 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -187,7 +187,9 @@ static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
 static struct clk clk_epllref = {
 	.name		= "epllref",
 	.id		= -1,
-	.set_parent	= s3c2443_setparent_epllref,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_epllref,
+	},
 };
 
 static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
@@ -205,7 +207,9 @@ static struct clk clk_mdivclk = {
 	.name		= "mdivclk",
 	.parent		= &clk_mpllref,
 	.id		= -1,
-	.get_rate	= s3c2443_getrate_mdivclk,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_mdivclk,
+	},
 };
 
 static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
@@ -232,7 +236,9 @@ static struct clk clk_msysclk = {
 	.name		= "msysclk",
 	.parent		= &clk_xtal,
 	.id		= -1,
-	.set_parent	= s3c2443_setparent_msysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_msysclk,
+	},
 };
 
 /* armdiv
@@ -273,7 +279,9 @@ static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent)
 static struct clk clk_arm = {
 	.name		= "armclk",
 	.id		= -1,
-	.set_parent	= s3c2443_setparent_armclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_armclk,
+	},
 };
 
 /* esysclk
@@ -302,7 +310,9 @@ static struct clk clk_esysclk = {
 	.name		= "esysclk",
 	.parent		= &clk_epll,
 	.id		= -1,
-	.set_parent	= s3c2443_setparent_esysclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_esysclk,
+	},
 };
 
 /* uartclk
@@ -341,9 +351,11 @@ static struct clk clk_uart = {
 	.name		= "uartclk",
 	.id		= -1,
 	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_uart,
-	.set_rate	= s3c2443_setrate_uart,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_uart,
+		.set_rate	= s3c2443_setrate_uart,
+		.round_rate	= s3c2443_roundrate_clksrc16,
+	},
 };
 
 /* hsspi
@@ -384,9 +396,11 @@ static struct clk clk_hsspi = {
 	.parent		= &clk_esysclk,
 	.ctrlbit	= S3C2443_SCLKCON_HSSPICLK,
 	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_hsspi,
-	.set_rate	= s3c2443_setrate_hsspi,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_hsspi,
+		.set_rate	= s3c2443_setrate_hsspi,
+		.round_rate	= s3c2443_roundrate_clksrc4,
+	},
 };
 
 /* usbhost
@@ -426,9 +440,11 @@ static struct clk clk_usb_bus_host = {
 	.parent		= &clk_esysclk,
 	.ctrlbit	= S3C2443_SCLKCON_USBHOST,
 	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_usbhost,
-	.set_rate	= s3c2443_setrate_usbhost,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_usbhost,
+		.set_rate	= s3c2443_setrate_usbhost,
+		.round_rate	= s3c2443_roundrate_clksrc4,
+	},
 };
 
 /* clk_hsmcc_div
@@ -468,9 +484,11 @@ static struct clk clk_hsmmc_div = {
 	.name		= "hsmmc-div",
 	.id		= -1,
 	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_hsmmc_div,
-	.set_rate	= s3c2443_setrate_hsmmc_div,
-	.round_rate	= s3c2443_roundrate_clksrc4,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_hsmmc_div,
+		.set_rate	= s3c2443_setrate_hsmmc_div,
+		.round_rate	= s3c2443_roundrate_clksrc4,
+	},
 };
 
 static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
@@ -505,7 +523,9 @@ static struct clk clk_hsmmc = {
 	.id		= -1,
 	.parent		= &clk_hsmmc_div,
 	.enable		= s3c2443_enable_hsmmc,
-	.set_parent	= s3c2443_setparent_hsmmc,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_hsmmc,
+	},
 };
 
 /* i2s_eplldiv
@@ -543,9 +563,11 @@ static struct clk clk_i2s_eplldiv = {
 	.name		= "i2s-eplldiv",
 	.id		= -1,
 	.parent		= &clk_esysclk,
-	.get_rate	= s3c2443_getrate_i2s_eplldiv,
-	.set_rate	= s3c2443_setrate_i2s_eplldiv,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_i2s_eplldiv,
+		.set_rate	= s3c2443_setrate_i2s_eplldiv,
+		.round_rate	= s3c2443_roundrate_clksrc16,
+	},
 };
 
 /* i2s-ref
@@ -578,7 +600,9 @@ static struct clk clk_i2s = {
 	.parent		= &clk_i2s_eplldiv,
 	.ctrlbit	= S3C2443_SCLKCON_I2SCLK,
 	.enable		= s3c2443_clkcon_enable_s,
-	.set_parent	= s3c2443_setparent_i2s,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2443_setparent_i2s,
+	},
 };
 
 /* cam-if
@@ -618,9 +642,11 @@ static struct clk clk_cam = {
 	.parent		= &clk_esysclk,
 	.ctrlbit	= S3C2443_SCLKCON_CAMCLK,
 	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_cam,
-	.set_rate	= s3c2443_setrate_cam,
-	.round_rate	= s3c2443_roundrate_clksrc16,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_cam,
+		.set_rate	= s3c2443_setrate_cam,
+		.round_rate	= s3c2443_roundrate_clksrc16,
+	},
 };
 
 /* display-if
@@ -660,9 +686,11 @@ static struct clk clk_display = {
 	.parent		= &clk_esysclk,
 	.ctrlbit	= S3C2443_SCLKCON_DISPCLK,
 	.enable		= s3c2443_clkcon_enable_s,
-	.get_rate	= s3c2443_getrate_display,
-	.set_rate	= s3c2443_setrate_display,
-	.round_rate	= s3c2443_roundrate_clksrc256,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_getrate_display,
+		.set_rate	= s3c2443_setrate_display,
+		.round_rate	= s3c2443_roundrate_clksrc256,
+	},
 };
 
 /* prediv
@@ -685,7 +713,9 @@ static struct clk clk_prediv = {
 	.name		= "prediv",
 	.id		= -1,
 	.parent		= &clk_msysclk,
-	.get_rate	= s3c2443_prediv_getrate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c2443_prediv_getrate,
+	},
 };
 
 /* standard clock definitions */
diff --git a/arch/arm/plat-s3c/clock.c b/arch/arm/plat-s3c/clock.c
index 619cfa8..fa91125 100644
--- a/arch/arm/plat-s3c/clock.c
+++ b/arch/arm/plat-s3c/clock.c
@@ -150,8 +150,8 @@ unsigned long clk_get_rate(struct clk *clk)
 	if (clk->rate != 0)
 		return clk->rate;
 
-	if (clk->get_rate != NULL)
-		return (clk->get_rate)(clk);
+	if (clk->ops != NULL && clk->ops->get_rate != NULL)
+		return (clk->ops->get_rate)(clk);
 
 	if (clk->parent != NULL)
 		return clk_get_rate(clk->parent);
@@ -161,8 +161,8 @@ unsigned long clk_get_rate(struct clk *clk)
 
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
-	if (!IS_ERR(clk) && clk->round_rate)
-		return (clk->round_rate)(clk, rate);
+	if (!IS_ERR(clk) && clk->ops && clk->ops->round_rate)
+		return (clk->ops->round_rate)(clk, rate);
 
 	return rate;
 }
@@ -178,13 +178,14 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 	 * the clock may have been made this way by choice.
 	 */
 
-	WARN_ON(clk->set_rate == NULL);
+	WARN_ON(clk->ops == NULL);
+	WARN_ON(clk->ops && clk->ops->set_rate == NULL);
 
-	if (clk->set_rate == NULL)
+	if (clk->ops == NULL || clk->ops->set_rate == NULL)
 		return -EINVAL;
 
 	spin_lock(&clocks_lock);
-	ret = (clk->set_rate)(clk, rate);
+	ret = (clk->ops->set_rate)(clk, rate);
 	spin_unlock(&clocks_lock);
 
 	return ret;
@@ -204,8 +205,8 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
 
 	spin_lock(&clocks_lock);
 
-	if (clk->set_parent)
-		ret = (clk->set_parent)(clk, parent);
+	if (clk->ops && clk->ops->set_parent)
+		ret = (clk->ops->set_parent)(clk, parent);
 
 	spin_unlock(&clocks_lock);
 
@@ -230,6 +231,10 @@ static int clk_default_setrate(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
+static struct clk_ops clk_ops_def_setrate = {
+	.set_rate	= clk_default_setrate,
+};
+
 struct clk clk_xtal = {
 	.name		= "xtal",
 	.id		= -1,
@@ -251,7 +256,7 @@ struct clk clk_epll = {
 struct clk clk_mpll = {
 	.name		= "mpll",
 	.id		= -1,
-	.set_rate	= clk_default_setrate,
+	.ops		= &clk_ops_def_setrate,
 };
 
 struct clk clk_upll = {
@@ -267,7 +272,6 @@ struct clk clk_f = {
 	.rate		= 0,
 	.parent		= &clk_mpll,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
 };
 
 struct clk clk_h = {
@@ -276,7 +280,7 @@ struct clk clk_h = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
+	.ops		= &clk_ops_def_setrate,
 };
 
 struct clk clk_p = {
@@ -285,7 +289,7 @@ struct clk clk_p = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
+	.ops		= &clk_ops_def_setrate,
 };
 
 struct clk clk_usb_bus = {
@@ -296,7 +300,6 @@ struct clk clk_usb_bus = {
 };
 
 
-
 struct clk s3c24xx_uclk = {
 	.name		= "uclk",
 	.id		= -1,
diff --git a/arch/arm/plat-s3c/pwm-clock.c b/arch/arm/plat-s3c/pwm-clock.c
index a318215..1808fa8 100644
--- a/arch/arm/plat-s3c/pwm-clock.c
+++ b/arch/arm/plat-s3c/pwm-clock.c
@@ -130,20 +130,22 @@ static int clk_pwm_scaler_set_rate(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
+static struct clk_ops clk_pwm_scaler_ops = {
+	.get_rate	= clk_pwm_scaler_get_rate,
+	.set_rate	= clk_pwm_scaler_set_rate,
+	.round_rate	= clk_pwm_scaler_round_rate,
+};
+
 static struct clk clk_timer_scaler[] = {
 	[0]	= {
 		.name		= "pwm-scaler0",
 		.id		= -1,
-		.get_rate	= clk_pwm_scaler_get_rate,
-		.set_rate	= clk_pwm_scaler_set_rate,
-		.round_rate	= clk_pwm_scaler_round_rate,
+		.ops		= &clk_pwm_scaler_ops,
 	},
 	[1]	= {
 		.name		= "pwm-scaler1",
 		.id		= -1,
-		.get_rate	= clk_pwm_scaler_get_rate,
-		.set_rate	= clk_pwm_scaler_set_rate,
-		.round_rate	= clk_pwm_scaler_round_rate,
+		.ops		= &clk_pwm_scaler_ops,
 	},
 };
 
@@ -256,50 +258,46 @@ static int clk_pwm_tdiv_set_rate(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
+static struct clk_ops clk_tdiv_ops = {
+	.get_rate	= clk_pwm_tdiv_get_rate,
+	.set_rate	= clk_pwm_tdiv_set_rate,
+	.round_rate	= clk_pwm_tdiv_round_rate,
+};
+
 static struct pwm_tdiv_clk clk_timer_tdiv[] = {
 	[0]	= {
 		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[0],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[0],
 		},
 	},
 	[1]	= {
 		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[0],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[0],
 		}
 	},
 	[2]	= {
 		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
 		},
 	},
 	[3]	= {
 		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
 		},
 	},
 	[4]	= {
 		.clk	= {
-			.name		= "pwm-tdiv",
-			.parent		= &clk_timer_scaler[1],
-			.get_rate	= clk_pwm_tdiv_get_rate,
-			.set_rate	= clk_pwm_tdiv_set_rate,
-			.round_rate	= clk_pwm_tdiv_round_rate,
+			.name	= "pwm-tdiv",
+			.ops	= &clk_tdiv_ops,
+			.parent	= &clk_timer_scaler[1],
 		},
 	},
 };
@@ -356,31 +354,35 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
 	return 0;
 }
 
+static struct clk_ops clk_tin_ops = {
+	.set_parent	= clk_pwm_tin_set_parent,
+};
+
 static struct clk clk_tin[] = {
 	[0]	= {
-		.name		= "pwm-tin",
-		.id		= 0,
-		.set_parent	= clk_pwm_tin_set_parent,
+		.name	= "pwm-tin",
+		.id	= 0,
+		.ops	= &clk_tin_ops,
 	},
 	[1]	= {
-		.name		= "pwm-tin",
-		.id		= 1,
-		.set_parent	= clk_pwm_tin_set_parent,
+		.name	= "pwm-tin",
+		.id	= 1,
+		.ops	= &clk_tin_ops,
 	},
 	[2]	= {
-		.name		= "pwm-tin",
-		.id		= 2,
-		.set_parent	= clk_pwm_tin_set_parent,
+		.name	= "pwm-tin",
+		.id	= 2,
+		.ops	= &clk_tin_ops,
 	},
 	[3]	= {
-		.name		= "pwm-tin",
-		.id		= 3,
-		.set_parent	= clk_pwm_tin_set_parent,
+		.name	= "pwm-tin",
+		.id	= 3,
+		.ops	= &clk_tin_ops,
 	},
 	[4]	= {
-		.name		= "pwm-tin",
-		.id		= 4,
-		.set_parent	= clk_pwm_tin_set_parent,
+		.name	= "pwm-tin",
+		.id	= 4,
+		.ops	= &clk_tin_ops,
 	},
 };
 
diff --git a/arch/arm/plat-s3c24xx/clock-dclk.c b/arch/arm/plat-s3c24xx/clock-dclk.c
index ac061a1..cf97caa 100644
--- a/arch/arm/plat-s3c24xx/clock-dclk.c
+++ b/arch/arm/plat-s3c24xx/clock-dclk.c
@@ -161,14 +161,18 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
 
 /* external clock definitions */
 
+static struct clk_ops dclk_ops = {
+	.set_parent	= s3c24xx_dclk_setparent,
+	.set_rate	= s3c24xx_set_dclk_rate,
+	.round_rate	= s3c24xx_round_dclk_rate,
+};
+
 struct clk s3c24xx_dclk0 = {
 	.name		= "dclk0",
 	.id		= -1,
 	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
 	.enable	        = s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
+	.ops		= &dclk_ops,
 };
 
 struct clk s3c24xx_dclk1 = {
@@ -176,19 +180,21 @@ struct clk s3c24xx_dclk1 = {
 	.id		= -1,
 	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
 	.enable		= s3c24xx_dclk_enable,
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
+	.ops		= &dclk_ops,
+};
+
+static struct clk_ops clkout_ops = {
+	.set_parent	= s3c24xx_clkout_setparent,
 };
 
 struct clk s3c24xx_clkout0 = {
 	.name		= "clkout0",
 	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
+	.ops		= &clkout_ops,
 };
 
 struct clk s3c24xx_clkout1 = {
 	.name		= "clkout1",
 	.id		= -1,
-	.set_parent	= s3c24xx_clkout_setparent,
+	.ops		= &clkout_ops,
 };
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
index 7937109..f8d9613 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c
@@ -68,7 +68,9 @@ static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
 static struct clk clk_arm = {
 	.name		= "armclk",
 	.id		= -1,
-	.set_parent	= s3c2440_setparent_armclk,
+	.ops		= &(struct clk_ops) {
+		.set_parent	= s3c2440_setparent_armclk,
+	},
 };
 
 static int s3c244x_clk_add(struct sys_device *sysdev)
diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index adc2e0a..79e4bd7 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -169,9 +169,11 @@ static struct clk clk_arm = {
 	.name		= "armclk",
 	.id		= -1,
 	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s3c64xx_clk_arm_get_rate,
-	.set_rate	= s3c64xx_clk_arm_set_rate,
-	.round_rate	= s3c64xx_clk_arm_round_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s3c64xx_clk_arm_get_rate,
+		.set_rate	= s3c64xx_clk_arm_set_rate,
+		.round_rate	= s3c64xx_clk_arm_round_rate,
+	},
 };
 
 static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
@@ -186,11 +188,15 @@ static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk)
 	return rate;
 }
 
+static struct clk_ops clk_dout_ops = {
+	.get_rate	= s3c64xx_clk_doutmpll_get_rate,
+};
+
 static struct clk clk_dout_mpll = {
 	.name		= "dout_mpll",
 	.id		= -1,
 	.parent		= &clk_mout_mpll.clk,
-	.get_rate	= s3c64xx_clk_doutmpll_get_rate,
+	.ops		= &clk_dout_ops,
 };
 
 static struct clk *clkset_spi_mmc_list[] = {
diff --git a/arch/arm/plat-s5pc1xx/clock.c b/arch/arm/plat-s5pc1xx/clock.c
index 26c21d8..2f4d8d4 100644
--- a/arch/arm/plat-s5pc1xx/clock.c
+++ b/arch/arm/plat-s5pc1xx/clock.c
@@ -70,6 +70,10 @@ static int clk_default_setrate(struct clk *clk, unsigned long rate)
 	return 0;
 }
 
+static struct clk_ops clk_ops_default_setrate = {
+	.set_rate	= clk_default_setrate,
+};
+
 static int clk_dummy_enable(struct clk *clk, int enable)
 {
 	return 0;
@@ -81,8 +85,8 @@ struct clk clk_hd0 = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
 	.enable		= clk_dummy_enable,
+	.ops		= &clk_ops_default_setrate,
 };
 
 struct clk clk_pd0 = {
@@ -91,7 +95,7 @@ struct clk clk_pd0 = {
 	.rate		= 0,
 	.parent		= NULL,
 	.ctrlbit	= 0,
-	.set_rate	= clk_default_setrate,
+	.ops		= &clk_ops_default_setrate,
 	.enable		= clk_dummy_enable,
 };
 
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
index b436d44..16f0b90 100644
--- a/arch/arm/plat-s5pc1xx/s5pc100-clock.c
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -111,7 +111,9 @@ static struct clk clk_dout_apll = {
 	.name		= "dout_apll",
 	.id		= -1,
 	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s5pc100_clk_dout_apll_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_apll_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_arm_get_rate(struct clk *clk)
@@ -165,9 +167,11 @@ static struct clk clk_arm = {
 	.name		= "armclk",
 	.id		= -1,
 	.parent		= &clk_dout_apll,
-	.get_rate	= s5pc100_clk_arm_get_rate,
-	.set_rate	= s5pc100_clk_arm_set_rate,
-	.round_rate	= s5pc100_clk_arm_round_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_arm_get_rate,
+		.set_rate	= s5pc100_clk_arm_set_rate,
+		.round_rate	= s5pc100_clk_arm_round_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_d0_bus_get_rate(struct clk *clk)
@@ -185,7 +189,9 @@ static struct clk clk_dout_d0_bus = {
 	.name		= "dout_d0_bus",
 	.id		= -1,
 	.parent		= &clk_arm,
-	.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_d0_bus_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_pclkd0_get_rate(struct clk *clk)
@@ -203,7 +209,9 @@ static struct clk clk_dout_pclkd0 = {
 	.name		= "dout_pclkd0",
 	.id		= -1,
 	.parent		= &clk_dout_d0_bus,
-	.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_pclkd0_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_apll2_get_rate(struct clk *clk)
@@ -221,7 +229,9 @@ static struct clk clk_dout_apll2 = {
 	.name		= "dout_apll2",
 	.id		= -1,
 	.parent		= &clk_mout_apll.clk,
-	.get_rate	= s5pc100_clk_dout_apll2_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_apll2_get_rate,
+	},
 };
 
 /* MPLL */
@@ -284,7 +294,9 @@ static struct clk clk_dout_d1_bus = {
 	.name		= "dout_d1_bus",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_d1_bus_get_rate,
+	},
 };
 
 static struct clk *clkset_onenand_list[] = {
@@ -325,7 +337,9 @@ static struct clk clk_dout_pclkd1 = {
 	.name		= "dout_pclkd1",
 	.id		= -1,
 	.parent		= &clk_dout_d1_bus,
-	.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_pclkd1_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_mpll2_get_rate(struct clk *clk)
@@ -345,7 +359,9 @@ static struct clk clk_dout_mpll2 = {
 	.name		= "dout_mpll2",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_mpll2_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_cam_get_rate(struct clk *clk)
@@ -365,7 +381,9 @@ static struct clk clk_dout_cam = {
 	.name		= "dout_cam",
 	.id		= -1,
 	.parent		= &clk_dout_mpll2,
-	.get_rate	= s5pc100_clk_dout_cam_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_cam_get_rate,
+	},
 };
 
 static unsigned long s5pc100_clk_dout_mpll_get_rate(struct clk *clk)
@@ -385,7 +403,9 @@ static struct clk clk_dout_mpll = {
 	.name		= "dout_mpll",
 	.id		= -1,
 	.parent		= &clk_mout_am.clk,
-	.get_rate	= s5pc100_clk_dout_mpll_get_rate,
+	.ops		= &(struct clk_ops) {
+		.get_rate	= s5pc100_clk_dout_mpll_get_rate,
+	},
 };
 
 /* EPLL */
@@ -540,6 +560,13 @@ static unsigned long s5pc100_roundrate_clksrc(struct clk *clk,
 	return rate;
 }
 
+static struct clk_ops s5pc100_clksrc_ops = {
+	.set_parent	= s5pc100_setparent_clksrc,
+	.get_rate	= s5pc100_getrate_clksrc,
+	.set_rate	= s5pc100_setrate_clksrc,
+	.round_rate	= s5pc100_roundrate_clksrc,
+};
+
 static struct clk *clkset_spi_list[] = {
 	&clk_mout_epll.clk,
 	&clk_dout_mpll2,
@@ -558,10 +585,7 @@ static struct clksrc_clk clk_spi0 = {
 		.id		= 0,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI0,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+
 	},
 	.shift		= S5PC100_CLKSRC1_SPI0_SHIFT,
 	.mask		= S5PC100_CLKSRC1_SPI0_MASK,
@@ -577,10 +601,7 @@ static struct clksrc_clk clk_spi1 = {
 		.id		= 1,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI1,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC1_SPI1_SHIFT,
 	.mask		= S5PC100_CLKSRC1_SPI1_MASK,
@@ -596,10 +617,7 @@ static struct clksrc_clk clk_spi2 = {
 		.id		= 2,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_SPI2,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC1_SPI2_SHIFT,
 	.mask		= S5PC100_CLKSRC1_SPI2_MASK,
@@ -625,10 +643,7 @@ static struct clksrc_clk clk_uart_uclk1 = {
 		.id		= -1,
 		.ctrlbit        = S5PC100_CLKGATE_SCLK0_UART,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC1_UART_SHIFT,
 	.mask		= S5PC100_CLKSRC1_UART_MASK,
@@ -683,10 +698,7 @@ static struct clksrc_clk clk_audio0 = {
 		.id		= 0,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO0,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC3_AUDIO0_SHIFT,
 	.mask		= S5PC100_CLKSRC3_AUDIO0_MASK,
@@ -716,10 +728,7 @@ static struct clksrc_clk clk_audio1 = {
 		.id		= 1,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO1,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC3_AUDIO1_SHIFT,
 	.mask		= S5PC100_CLKSRC3_AUDIO1_MASK,
@@ -748,10 +757,7 @@ static struct clksrc_clk clk_audio2 = {
 		.id		= 2,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_AUDIO2,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC3_AUDIO2_SHIFT,
 	.mask		= S5PC100_CLKSRC3_AUDIO2_MASK,
@@ -801,10 +807,7 @@ static struct clksrc_clk clk_lcd = {
 		.id		= -1,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_LCD,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_LCD_SHIFT,
 	.mask		= S5PC100_CLKSRC2_LCD_MASK,
@@ -820,10 +823,7 @@ static struct clksrc_clk clk_fimc0 = {
 		.id		= 0,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC0,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_FIMC0_SHIFT,
 	.mask		= S5PC100_CLKSRC2_FIMC0_MASK,
@@ -839,10 +839,7 @@ static struct clksrc_clk clk_fimc1 = {
 		.id		= 1,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC1,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_FIMC1_SHIFT,
 	.mask		= S5PC100_CLKSRC2_FIMC1_MASK,
@@ -858,10 +855,7 @@ static struct clksrc_clk clk_fimc2 = {
 		.id		= 2,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK1_FIMC2,
 		.enable		= s5pc100_sclk1_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_FIMC2_SHIFT,
 	.mask		= S5PC100_CLKSRC2_FIMC2_MASK,
@@ -889,10 +883,7 @@ static struct clksrc_clk clk_mmc0 = {
 		.id		= 0,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC0,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_MMC0_SHIFT,
 	.mask		= S5PC100_CLKSRC2_MMC0_MASK,
@@ -908,10 +899,7 @@ static struct clksrc_clk clk_mmc1 = {
 		.id		= 1,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC1,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_MMC1_SHIFT,
 	.mask		= S5PC100_CLKSRC2_MMC1_MASK,
@@ -927,10 +915,7 @@ static struct clksrc_clk clk_mmc2 = {
 		.id		= 2,
 		.ctrlbit	= S5PC100_CLKGATE_SCLK0_MMC2,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC2_MMC2_SHIFT,
 	.mask		= S5PC100_CLKSRC2_MMC2_MASK,
@@ -959,10 +944,7 @@ static struct clksrc_clk clk_usbhost = {
 		.id		= -1,
 		.ctrlbit        = S5PC100_CLKGATE_SCLK0_USBHOST,
 		.enable		= s5pc100_sclk0_ctrl,
-		.set_parent	= s5pc100_setparent_clksrc,
-		.get_rate	= s5pc100_getrate_clksrc,
-		.set_rate	= s5pc100_setrate_clksrc,
-		.round_rate	= s5pc100_roundrate_clksrc,
+		.ops		= &s5pc100_clksrc_ops,
 	},
 	.shift		= S5PC100_CLKSRC1_UHOST_SHIFT,
 	.mask		= S5PC100_CLKSRC1_UHOST_MASK,
diff --git a/arch/arm/plat-samsung/clock-clksrc.c b/arch/arm/plat-samsung/clock-clksrc.c
index 5872f0b..ad4e872 100644
--- a/arch/arm/plat-samsung/clock-clksrc.c
+++ b/arch/arm/plat-samsung/clock-clksrc.c
@@ -150,20 +150,21 @@ void __init_or_cpufreq s3c_set_clksrc(struct clksrc_clk *clk)
 	       clk_get_rate(&clk->clk));
 }
 
+static struct clk_ops clksrc_ops = {
+	.set_parent	= s3c_setparent_clksrc,
+	.get_rate	= s3c_getrate_clksrc,
+	.set_rate	= s3c_setrate_clksrc,
+	.round_rate	= s3c_roundrate_clksrc,
+};
+
 void __init s3c_register_clksrc(struct clksrc_clk *clksrc, int size)
 {
 	int ret;
 
 	for (; size > 0; size--, clksrc++) {
 		/* fill in the default functions */
-		if (!clksrc->clk.set_parent)
-			clksrc->clk.set_parent = s3c_setparent_clksrc;
-		if (!clksrc->clk.get_rate)
-			clksrc->clk.get_rate = s3c_getrate_clksrc;
-		if (!clksrc->clk.set_rate)
-			clksrc->clk.set_rate = s3c_setrate_clksrc;
-		if (!clksrc->clk.round_rate)
-			clksrc->clk.round_rate = s3c_roundrate_clksrc;
+		if (!clksrc->clk.ops)
+			clksrc->clk.ops = &clksrc_ops;
 
 		s3c_set_clksrc(clksrc);
 
diff --git a/arch/arm/plat-samsung/include/plat/clock.h b/arch/arm/plat-samsung/include/plat/clock.h
index d86af84..43324af 100644
--- a/arch/arm/plat-samsung/include/plat/clock.h
+++ b/arch/arm/plat-samsung/include/plat/clock.h
@@ -11,6 +11,30 @@
 
 #include <linux/spinlock.h>
 
+struct clk;
+
+/**
+ * struct clk_ops - standard clock operations
+ * @set_rate: set the clock rate, see clk_set_rate().
+ * @get_rate: get the clock rate, see clk_get_rate().
+ * @round_rate: round a given clock rate, see clk_round_rate().
+ * @set_parent: set the clock's parent, see clk_set_parent().
+ *
+ * Group the common clock implementations together so that we
+ * don't have to keep setting the same fiels again. We leave
+ * enable in struct clk.
+ *
+ * Adding an extra layer of indirection into the process should
+ * not be a problem as it is unlikely these operations are going
+ * to need to be called quickly.
+ */
+struct clk_ops {
+	int		    (*set_rate)(struct clk *c, unsigned long rate);
+	unsigned long	    (*get_rate)(struct clk *c);
+	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
+	int		    (*set_parent)(struct clk *c, struct clk *parent);
+};
+
 struct clk {
 	struct list_head      list;
 	struct module        *owner;
@@ -21,11 +45,8 @@ struct clk {
 	unsigned long         rate;
 	unsigned long         ctrlbit;
 
+	struct clk_ops		*ops;
 	int		    (*enable)(struct clk *, int enable);
-	int		    (*set_rate)(struct clk *c, unsigned long rate);
-	unsigned long	    (*get_rate)(struct clk *c);
-	unsigned long	    (*round_rate)(struct clk *c, unsigned long rate);
-	int		    (*set_parent)(struct clk *c, struct clk *parent);
 };
 
 /* other clocks which may be registered by board support */
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [[clock v2]] ARM: S3C64XX: Fixup .reg_src and .reg_div with named initialisers
  2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
                   ` (6 preceding siblings ...)
  2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Reduce size of struct clk Ben Dooks
@ 2009-12-08  2:07 ` Ben Dooks
  7 siblings, 0 replies; 9+ messages in thread
From: Ben Dooks @ 2009-12-08  2:07 UTC (permalink / raw)
  To: linux-arm-kernel

Change these two fields to have named initialisers as per the
review comments from Kyungmin Park.

sed used:

s@\.reg_src\(.*\)=\(.*\){\(.*\),\(.*\),\(.*\)}@.reg_src\1=\2{ .reg =\3, .shift =\4, .size =\5 }@g

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
---
 arch/arm/plat-s3c64xx/s3c6400-clock.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/arch/arm/plat-s3c64xx/s3c6400-clock.c b/arch/arm/plat-s3c64xx/s3c6400-clock.c
index 79e4bd7..8f6a0d1 100644
--- a/arch/arm/plat-s3c64xx/s3c6400-clock.c
+++ b/arch/arm/plat-s3c64xx/s3c6400-clock.c
@@ -68,7 +68,7 @@ static struct clksrc_clk clk_mout_apll = {
 		.name		= "mout_apll",
 		.id		= -1,
 	},
-	.reg_src	= { S3C_CLK_SRC, 0, 1 },
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 0, .size = 1  },
 	.sources	= &clk_src_apll,
 };
 
@@ -92,7 +92,7 @@ static struct clksrc_clk clk_mout_epll = {
 		.name		= "mout_epll",
 		.id		= -1,
 	},
-	.reg_src	= { S3C_CLK_SRC, 2, 1 },
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 2, .size = 1  },
 	.sources	= &clk_src_epll,
 };
 
@@ -111,7 +111,7 @@ static struct clksrc_clk clk_mout_mpll = {
 		.name		= "mout_mpll",
 		.id		= -1,
 	},
-	.reg_src	= { S3C_CLK_SRC, 1, 1 },
+	.reg_src	= { .reg = S3C_CLK_SRC, .shift = 1, .size = 1  },
 	.sources	= &clk_src_mpll,
 };
 
@@ -317,7 +317,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 18, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 18, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV1, 0, 4 },
 		.sources	= &clkset_spi_mmc,
 	}, {
@@ -327,7 +327,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 20, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 20, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV1, 4, 4 },
 		.sources	= &clkset_spi_mmc,
 	}, {
@@ -337,7 +337,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_MMC2,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 22, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 22, .size = 2  },
 		.reg_div 	= { S3C_CLK_DIV1, 8, 4 },
 		.sources	= &clkset_spi_mmc,
 	}, {
@@ -347,7 +347,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_UHOST,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src 	= { S3C_CLK_SRC, 5, 2 },
+		.reg_src 	= { .reg = S3C_CLK_SRC, .shift = 5, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV1, 20, 4 },
 		.sources	= &clkset_uhost,
 	}, {
@@ -357,7 +357,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_UART,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 13, 1 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 13, .size = 1  },
 		.reg_div	= { S3C_CLK_DIV2, 16, 4 },
 		.sources	= &clkset_uart,
 	}, {
@@ -368,7 +368,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_SPI0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 14, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 14, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV2, 0, 4 },
 		.sources	= &clkset_spi_mmc,
 	}, {
@@ -378,7 +378,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_SPI1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 16, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 16, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV2, 4, 4 },
 		.sources	= &clkset_spi_mmc,
 	}, {
@@ -388,7 +388,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO0,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 7, 3 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 7, .size = 3  },
 		.reg_div	= { S3C_CLK_DIV2, 8, 4 },
 		.sources	= &clkset_audio0,
 	}, {
@@ -398,7 +398,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_AUDIO1,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 10, 3 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 10, .size = 3  },
 		.reg_div	= { S3C_CLK_DIV2, 12, 4 },
 		.sources	= &clkset_audio1,
 	}, {
@@ -408,7 +408,7 @@ static struct clksrc_clk clksrcs[] = {
 			.ctrlbit        = S3C_CLKCON_SCLK_IRDA,
 			.enable		= s3c64xx_sclk_ctrl,
 		},
-		.reg_src	= { S3C_CLK_SRC, 24, 2 },
+		.reg_src	= { .reg = S3C_CLK_SRC, .shift = 24, .size = 2  },
 		.reg_div	= { S3C_CLK_DIV2, 20, 4 },
 		.sources	= &clkset_irda,
 	}, {
@@ -419,7 +419,7 @@ static struct clksrc_clk clksrcs[] = {
 			.enable		= s3c64xx_sclk_ctrl,
 		},
 		.reg_div	= { S3C_CLK_DIV0, 20, 4 },
-		.reg_src	= { NULL, 0, 0 },
+		.reg_src	= { .reg = NULL, .shift = 0, .size = 0  },
 		.sources	= &clkset_camif,
 	},
 };
-- 
1.5.6.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-12-08  2:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-08  2:07 Samsung clock updates v2 Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Move <plat/clock.h> to plat-samsung Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Cleanup common init code in s3c6400-clock.c Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Compress s3c6400-clock.c code Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Add core clock implementation for clksrc based clocks Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Use new clock-clksrc.c code for clocks Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Remove unused clock definitions from clock header Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: SAMSUNG: Reduce size of struct clk Ben Dooks
2009-12-08  2:07 ` [[clock v2]] ARM: S3C64XX: Fixup .reg_src and .reg_div with named initialisers Ben Dooks

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).