aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-05-13 17:38:11 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-05-13 17:38:11 +0900
commit253b0887b3736160feac9ccdcf146a2073e41463 (patch)
treefb7e0776555cff9275760293c10c13e8c8f365fe
parent100890c55e326a9acb4429593c5ad2012c194564 (diff)
sh: clkfwk: Rework legacy CPG clock handling.
This moves out the old legacy CPG clocks to their own file, and converts over the existing users. With these clocks going away and each CPU dealing with them on their own, CPUs can gradually move over to the new interface. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/include/asm/clock.h5
-rw-r--r--arch/sh/include/asm/machvec.h2
-rw-r--r--arch/sh/kernel/cpu/Makefile1
-rw-r--r--arch/sh/kernel/cpu/clock-cpg.c60
-rw-r--r--arch/sh/kernel/cpu/clock.c70
-rw-r--r--arch/sh/kernel/cpu/sh4/clock-sh4-202.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7763.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7780.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7785.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7786.c5
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-shx3.c5
13 files changed, 110 insertions, 63 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index fb75c2d1928..d7990cd2f8d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -513,6 +513,9 @@ config SH_PCLK_FREQ
This is necessary for determining the reference clock value on
platforms lacking an RTC.
+config SH_CLK_CPG_LEGACY
+ def_bool y
+
config SH_CLK_MD
int "CPU Mode Pin Setting"
depends on CPU_SH2
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index e2f5bf1b4a9..c27e844db0d 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -47,7 +47,7 @@ struct clk_lookup {
#define CLK_ENABLE_ON_INIT (1 << 0)
/* Should be defined by processor-specific code */
-void arch_init_clk_ops(struct clk_ops **, int type);
+void __deprecated arch_init_clk_ops(struct clk_ops **, int type);
int __init arch_clk_init(void);
/* arch/sh/kernel/cpu/clock.c */
@@ -59,6 +59,9 @@ int clk_reparent(struct clk *child, struct clk *parent);
int clk_register(struct clk *);
void clk_unregister(struct clk *);
+/* arch/sh/kernel/cpu/clock-cpg.c */
+int __init __deprecated cpg_clk_init(void);
+
/* the exported API, in addition to clk_set_rate */
/**
* clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index 64b1c16a0f0..73d6d16fa06 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -46,6 +46,8 @@ struct sh_machine_vector {
void __iomem *(*mv_ioport_map)(unsigned long port, unsigned int size);
void (*mv_ioport_unmap)(void __iomem *);
+
+ int (*mv_clk_init)(void);
};
extern struct sh_machine_vector sh_mv;
diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile
index 2600641a483..05105b980c2 100644
--- a/arch/sh/kernel/cpu/Makefile
+++ b/arch/sh/kernel/cpu/Makefile
@@ -17,5 +17,6 @@ obj-$(CONFIG_ARCH_SHMOBILE) += shmobile/
obj-$(CONFIG_UBC_WAKEUP) += ubc.o
obj-$(CONFIG_SH_ADC) += adc.o
+obj-$(CONFIG_SH_CLK_CPG_LEGACY) += clock-cpg.o
obj-y += irq/ init.o clock.o
diff --git a/arch/sh/kernel/cpu/clock-cpg.c b/arch/sh/kernel/cpu/clock-cpg.c
new file mode 100644
index 00000000000..b4ca2004844
--- /dev/null
+++ b/arch/sh/kernel/cpu/clock-cpg.c
@@ -0,0 +1,60 @@
+#include <linux/clk.h>
+#include <linux/compiler.h>
+#include <asm/clock.h>
+
+static struct clk master_clk = {
+ .name = "master_clk",
+ .flags = CLK_ENABLE_ON_INIT,
+ .rate = CONFIG_SH_PCLK_FREQ,
+};
+
+static struct clk peripheral_clk = {
+ .name = "peripheral_clk",
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+static struct clk bus_clk = {
+ .name = "bus_clk",
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &master_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
+
+/*
+ * The ordering of these clocks matters, do not change it.
+ */
+static struct clk *onchip_clocks[] = {
+ &master_clk,
+ &peripheral_clk,
+ &bus_clk,
+ &cpu_clk,
+};
+
+int __init __deprecated cpg_clk_init(void)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
+ struct clk *clk = onchip_clocks[i];
+ arch_init_clk_ops(&clk->ops, i);
+ if (clk->ops)
+ ret |= clk_register(clk);
+ }
+
+ return ret;
+}
+
+/*
+ * Placeholder for compatability, until the lazy CPUs do this
+ * on their own.
+ */
+int __init __weak arch_clk_init(void)
+{
+ return cpg_clk_init();
+}
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index 0a7755cc8a2..033f4662b59 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -30,54 +30,12 @@
#include <linux/platform_device.h>
#include <linux/proc_fs.h>
#include <asm/clock.h>
+#include <asm/machvec.h>
static LIST_HEAD(clock_list);
static DEFINE_SPINLOCK(clock_lock);
static DEFINE_MUTEX(clock_list_sem);
-/*
- * Each subtype is expected to define the init routines for these clocks,
- * as each subtype (or processor family) will have these clocks at the
- * very least. These are all provided through the CPG, which even some of
- * the more quirky parts (such as ST40, SH4-202, etc.) still have.
- *
- * The processor-specific code is expected to register any additional
- * clock sources that are of interest.
- */
-static struct clk master_clk = {
- .name = "master_clk",
- .flags = CLK_ENABLE_ON_INIT,
- .rate = CONFIG_SH_PCLK_FREQ,
-};
-
-static struct clk peripheral_clk = {
- .name = "peripheral_clk",
- .parent = &master_clk,
- .flags = CLK_ENABLE_ON_INIT,
-};
-
-static struct clk bus_clk = {
- .name = "bus_clk",
- .parent = &master_clk,
- .flags = CLK_ENABLE_ON_INIT,
-};
-
-static struct clk cpu_clk = {
- .name = "cpu_clk",
- .parent = &master_clk,
- .flags = CLK_ENABLE_ON_INIT,
-};
-
-/*
- * The ordering of these clocks matters, do not change it.
- */
-static struct clk *onchip_clocks[] = {
- &master_clk,
- &peripheral_clk,
- &bus_clk,
- &cpu_clk,
-};
-
/* Used for clocks that always have same value as the parent clock */
unsigned long followparent_recalc(struct clk *clk)
{
@@ -443,10 +401,6 @@ void clk_put(struct clk *clk)
}
EXPORT_SYMBOL_GPL(clk_put);
-int __init __weak arch_clk_init(void)
-{
- return 0;
-}
static int show_clocks(char *buf, char **start, off_t off,
int len, int *eof, void *data)
@@ -533,18 +487,22 @@ subsys_initcall(clk_sysdev_init);
int __init clk_init(void)
{
- int i, ret = 0;
-
- BUG_ON(!master_clk.rate);
-
- for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) {
- struct clk *clk = onchip_clocks[i];
+ int ret;
- arch_init_clk_ops(&clk->ops, i);
- ret |= clk_register(clk);
+ ret = arch_clk_init();
+ if (unlikely(ret)) {
+ pr_err("%s: CPU clock registration failed.\n", __func__);
+ return ret;
}
- ret |= arch_clk_init();
+ if (sh_mv.mv_clk_init) {
+ ret = sh_mv.mv_clk_init();
+ if (unlikely(ret)) {
+ pr_err("%s: machvec clock initialization failed.\n",
+ __func__);
+ return ret;
+ }
+ }
/* Kick the child clocks.. */
recalculate_root_clocks();
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
index a72dc326d0b..21421e34e7d 100644
--- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
+++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c
@@ -152,9 +152,12 @@ static struct clk *sh4202_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
struct clk *clkp = sh4202_onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
index 426065b4326..a98d7da67b9 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c
@@ -892,6 +892,8 @@ int __init arch_clk_init(void)
struct clk *clk;
int i;
+ clk_cpg_init();
+
clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
index ce3d4e6319a..370cd47642e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7763.c
@@ -92,9 +92,12 @@ static struct clk *sh7763_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7763_onchip_clocks); i++) {
struct clk *clkp = sh7763_onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
index 38b8b1ddb28..a249d823578 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
@@ -98,9 +98,12 @@ static struct clk *sh7780_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {
struct clk *clkp = sh7780_onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
index fa14f35bc11..bf5a0dacf8e 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c
@@ -136,9 +136,12 @@ static struct clk *sh7785_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7785_onchip_clocks); i++) {
struct clk *clkp = sh7785_onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
index 7907002fa1d..a0e8869071a 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7786.c
@@ -122,9 +122,12 @@ static struct clk *sh7786_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(sh7786_onchip_clocks); i++) {
struct clk *clkp = sh7786_onchip_clocks[i];
diff --git a/arch/sh/kernel/cpu/sh4a/clock-shx3.c b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
index c14553e3e13..23c27d32d98 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-shx3.c
@@ -109,9 +109,12 @@ static struct clk *shx3_onchip_clocks[] = {
int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
+ struct clk *clk;
int i, ret = 0;
+ cpg_clk_init();
+
+ clk = clk_get(NULL, "master_clk");
for (i = 0; i < ARRAY_SIZE(shx3_onchip_clocks); i++) {
struct clk *clkp = shx3_onchip_clocks[i];