[PATCH 1/4] ARM: clps711x/p720t: Replace __initcall by .init_early call

Subsystems: arm port, the rest

STALE5161d

7 messages, 3 authors, 2012-07-19 · open the first message on its own page

[PATCH 1/4] ARM: clps711x/p720t: Replace __initcall by .init_early call

From: Alexander Shiyan <hidden>
Date: 2012-07-16 18:21:45

Since we are trying to do to support multiple machines in a single kernel,
we need to eliminate the use of __initcall to be used for all machines.
Using .init_early call solves this problem.

Signed-off-by: Alexander Shiyan <redacted>
---
 arch/arm/mach-clps711x/p720t.c |   34 +++++++++++++++-------------------
 1 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c
index 42ee8f3..f266d90 100644
--- a/arch/arm/mach-clps711x/p720t.c
+++ b/arch/arm/mach-clps711x/p720t.c
@@ -86,17 +86,7 @@ static void __init p720t_map_io(void)
 	iotable_init(p720t_io_desc, ARRAY_SIZE(p720t_io_desc));
 }
 
-MACHINE_START(P720T, "ARM-Prospector720T")
-	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
-	.atag_offset	= 0x100,
-	.fixup		= fixup_p720t,
-	.map_io		= p720t_map_io,
-	.init_irq	= clps711x_init_irq,
-	.timer		= &clps711x_timer,
-	.restart	= clps711x_restart,
-MACHINE_END
-
-static int p720t_hw_init(void)
+static void __init p720t_init_early(void)
 {
 	/*
 	 * Power down as much as possible in case we don't
@@ -111,13 +101,19 @@ static int p720t_hw_init(void)
 	PLD_CODEC = 0;
 	PLD_TCH   = 0;
 	PLD_SPI   = 0;
-#ifndef CONFIG_DEBUG_LL
-	PLD_COM2  = 0;
-	PLD_COM1  = 0;
-#endif
-
-	return 0;
+	if (!IS_ENABLED(CONFIG_DEBUG_LL)) {
+		PLD_COM2 = 0;
+		PLD_COM1 = 0;
+	}
 }
 
-__initcall(p720t_hw_init);
-
+MACHINE_START(P720T, "ARM-Prospector720T")
+	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
+	.atag_offset	= 0x100,
+	.fixup		= fixup_p720t,
+	.init_early	= p720t_init_early,
+	.map_io		= p720t_map_io,
+	.init_irq	= clps711x_init_irq,
+	.timer		= &clps711x_timer,
+	.restart	= clps711x_restart,
+MACHINE_END
-- 
1.7.3.4

[PATCH 2/4] ARM: clps711x: Removed superfluous transform virt_to_bus and related functions

From: Alexander Shiyan <hidden>
Date: 2012-07-16 18:21:46

This override does not allow support for multiple machines in a single core.

Signed-off-by: Alexander Shiyan <redacted>
---
 arch/arm/mach-clps711x/include/mach/memory.h |   37 --------------------------
 1 files changed, 0 insertions(+), 37 deletions(-)
diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h
index 3a032a6..fc0e028 100644
--- a/arch/arm/mach-clps711x/include/mach/memory.h
+++ b/arch/arm/mach-clps711x/include/mach/memory.h
@@ -25,26 +25,6 @@
  */
 #define PLAT_PHYS_OFFSET	UL(0xc0000000)
 
-#if !defined(CONFIG_ARCH_CDB89712) && !defined (CONFIG_ARCH_AUTCPU12)
-
-#define __virt_to_bus(x)	((x) - PAGE_OFFSET)
-#define __bus_to_virt(x)	((x) + PAGE_OFFSET)
-#define __pfn_to_bus(x)		(__pfn_to_phys(x) - PHYS_OFFSET)
-#define __bus_to_pfn(x)		__phys_to_pfn((x) + PHYS_OFFSET)
-
-#endif
-
-
-/*
- * Like the SA1100, the EDB7211 has a large gap between physical RAM
- * banks.  In 2.2, the Psion (CL-PS7110) port added custom support for
- * discontiguous physical memory.  In 2.4, we can use the standard
- * Linux NUMA support.
- *
- * This is not necessary for EP7211 implementations with only one used
- * memory bank.  For those systems, simply undefine CONFIG_DISCONTIGMEM.
- */
-
 /*
  * The PS7211 allows up to 256MB max per DRAM bank, but the EDB7211
  * uses only one of the two banks (bank #1).  However, even within
@@ -54,23 +34,6 @@
  * them, so we use 24 for the node max shift to get 16MB node sizes.
  */
 
-/*
- * Because of the wide memory address space between physical RAM banks on the 
- * SA1100, it's much more convenient to use Linux's NUMA support to implement
- * our memory map representation.  Assuming all memory nodes have equal access 
- * characteristics, we then have generic discontiguous memory support.
- *
- * Of course, all this isn't mandatory for SA1100 implementations with only
- * one used memory bank.  For those, simply undefine CONFIG_DISCONTIGMEM.
- *
- * The nodes are matched with the physical memory bank addresses which are 
- * incidentally the same as virtual addresses.
- * 
- * 	node 0:  0xc0000000 - 0xc7ffffff
- * 	node 1:  0xc8000000 - 0xcfffffff
- * 	node 2:  0xd0000000 - 0xd7ffffff
- * 	node 3:  0xd8000000 - 0xdfffffff
- */
 #define SECTION_SIZE_BITS	24
 #define MAX_PHYSMEM_BITS	32
 
-- 
1.7.3.4

[PATCH 3/4] ARM: clps711x: Remove the setting of the time

From: Alexander Shiyan <hidden>
Date: 2012-07-16 18:21:47

This patch fixes "bug: interrupts were enabled early" due to
do_settimeofday() which used in common code for clps711x-platform.

Signed-off-by: Alexander Shiyan <redacted>
---
 arch/arm/mach-clps711x/common.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index c965fd8..f15293b 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -26,7 +26,6 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
-#include <linux/timex.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
@@ -188,7 +187,6 @@ static struct irqaction clps711x_timer_irq = {
 
 static void __init clps711x_timer_init(void)
 {
-	struct timespec tv;
 	unsigned int syscon;
 
 	syscon = clps_readl(SYSCON1);
@@ -198,10 +196,6 @@ static void __init clps711x_timer_init(void)
 	clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
 
 	setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
-
-	tv.tv_nsec = 0;
-	tv.tv_sec = clps_readl(RTCDR);
-	do_settimeofday(&tv);
 }
 
 struct sys_timer clps711x_timer = {
-- 
1.7.3.4

[PATCH 4/4] ARM: clps711x: Added simple clkdev framework

From: Alexander Shiyan <hidden>
Date: 2012-07-16 18:21:48

Modern CPUs from CLPS711X-line can operate at frequencies other than 73 MHz.
This patch adds simple clkdev framework for handling all possible CPU rates.

Signed-off-by: Alexander Shiyan <redacted>
---
 arch/arm/Kconfig                            |    1 +
 arch/arm/mach-clps711x/common.c             |  104 +++++++++++++++++++++++++--
 arch/arm/mach-clps711x/include/mach/timex.h |   23 +------
 drivers/tty/serial/clps711x.c               |   19 ++++-
 4 files changed, 115 insertions(+), 32 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..fc2b454 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -361,6 +361,7 @@ config ARCH_HIGHBANK
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 	select CPU_ARM720T
+	select CLKDEV_LOOKUP
 	select ARCH_USES_GETTIMEOFFSET
 	select NEED_MACH_MEMORY_H
 	help
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index f15293b..daab6bf 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -26,6 +26,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/module.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
@@ -37,6 +40,52 @@
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk rtc_clk;
+static struct clk osc_clk;
+static struct clk ext_clk;
+static struct clk pll_clk;
+static struct clk cpu_clk;
+static struct clk bus_clk;
+static struct clk uart_clk;
+static struct clk timer_h_clk;
+static struct clk timer_l_clk;
+
+static unsigned long latch;
+
+/* Enable and Disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static struct clk_lookup clps711x_lookups[] = {
+	CLKDEV_INIT( NULL, "rtc", &rtc_clk),
+	CLKDEV_INIT( NULL, "osc", &pll_clk),
+	CLKDEV_INIT( NULL, "ext", &ext_clk),
+	CLKDEV_INIT( NULL, "pll", &pll_clk),
+	CLKDEV_INIT( NULL, "cpu", &cpu_clk),
+	CLKDEV_INIT( NULL, "bus", &bus_clk),
+	CLKDEV_INIT( NULL, "uart", &uart_clk),
+	CLKDEV_INIT( NULL, "timer_h", &timer_h_clk),
+	CLKDEV_INIT( NULL, "timer_l", &timer_l_clk),
+};
+
 /*
  * This maps the generic CLPS711x registers
  */
@@ -166,8 +215,8 @@ void __init clps711x_init_irq(void)
 static unsigned long clps711x_gettimeoffset(void)
 {
 	unsigned long hwticks;
-	hwticks = LATCH - (clps_readl(TC2D) & 0xffff);	/* since last underflow */
-	return (hwticks * (tick_nsec / 1000)) / LATCH;
+	hwticks = latch - (clps_readl(TC2D) & 0xffff);
+	return (hwticks * (tick_nsec / 1000)) / latch;
 }
 
 /*
@@ -187,13 +236,54 @@ static struct irqaction clps711x_timer_irq = {
 
 static void __init clps711x_timer_init(void)
 {
-	unsigned int syscon;
+	u32 tmp;
+
+	rtc_clk.rate = 32768;
+	osc_clk.rate = 3686400;
+	ext_clk.rate = 13000000;
+
+	tmp = clps_readl(PLLR) >> 24;
+	if (tmp)
+		pll_clk.rate = (osc_clk.rate * tmp) / 2;
+	else
+		pll_clk.rate = 73728000; /* Default value */
+
+	tmp = clps_readl(SYSFLG2);
+	if (tmp & SYSFLG2_CKMODE) {
+		cpu_clk.rate = ext_clk.rate;
+		bus_clk.rate = cpu_clk.rate;
+	} else {
+		cpu_clk.rate = pll_clk.rate;
+		if (cpu_clk.rate >= 36864000)
+			bus_clk.rate = cpu_clk.rate / 2;
+		else
+			bus_clk.rate = 36864000 / 2;
+	}
+
+	uart_clk.rate = bus_clk.rate / 10;
+
+	if (tmp & SYSFLG2_CKMODE) {
+		tmp = clps_readl(SYSCON2);
+		if (tmp & SYSCON2_OSTB)
+			timer_h_clk.rate = ext_clk.rate / 26; /* 500 kHz */
+		else
+			timer_h_clk.rate = 541440;
+	} else
+		timer_h_clk.rate = cpu_clk.rate / 144;
+
+	timer_l_clk.rate = timer_h_clk.rate / 256;
+
+	latch = (timer_h_clk.rate + HZ / 2) / HZ;
+
+	clkdev_add_table(clps711x_lookups, ARRAY_SIZE(clps711x_lookups));
+
+	pr_info("CPU frequency set at %lu Hz.\n", cpu_clk.rate);
 
-	syscon = clps_readl(SYSCON1);
-	syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
-	clps_writel(syscon, SYSCON1);
+	tmp = clps_readl(SYSCON1);
+	tmp |= SYSCON1_TC2S | SYSCON1_TC2M;
+	clps_writel(tmp, SYSCON1);
 
-	clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
+	clps_writel(latch - 1, TC2D);
 
 	setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
 }
diff --git a/arch/arm/mach-clps711x/include/mach/timex.h b/arch/arm/mach-clps711x/include/mach/timex.h
index ac8823c..3d98736 100644
--- a/arch/arm/mach-clps711x/include/mach/timex.h
+++ b/arch/arm/mach-clps711x/include/mach/timex.h
@@ -1,23 +1,2 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/timex.h
- *
- *  Prospector 720T architecture timex specifications
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
+/* Bugus value */
 #define CLOCK_TICK_RATE 512000
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index d0f719f..d9f4983 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -37,6 +37,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -401,7 +402,6 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	{
 		.iobase		= SYSCON1,
 		.irq		= IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
-		.uartclk	= 3686400,
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 0,
@@ -410,7 +410,6 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	{
 		.iobase		= SYSCON2,
 		.irq		= IRQ_UTXINT2, /* IRQ_URXINT2 */
-		.uartclk	= 3686400,
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 1,
@@ -418,6 +417,17 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	}
 };
 
+static unsigned long clps711xuart_get_uartclk(void)
+{
+	struct clk *uart_clk;
+
+	uart_clk = clk_get(NULL, "uart");
+	if (!IS_ERR(uart_clk))
+		return clk_get_rate(uart_clk);
+
+	return 3686400; /* Default value */
+}
+
 #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
 static void clps711xuart_console_putchar(struct uart_port *port, int ch)
 {
@@ -501,6 +511,7 @@ static int __init clps711xuart_console_setup(struct console *co, char *options)
 	 * console support.
 	 */
 	port = uart_get_console(clps711x_ports, UART_NR, co);
+	port->uartclk = clps711xuart_get_uartclk();
 
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -553,8 +564,10 @@ static int __init clps711xuart_init(void)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < UART_NR; i++)
+	for (i = 0; i < UART_NR; i++) {
+		clps711x_ports[i].uartclk = clps711xuart_get_uartclk();
 		uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
+	}
 
 	return 0;
 }
-- 
1.7.3.4

[PATCH 1/4] ARM: clps711x/p720t: Replace __initcall by .init_early call

From: arnd@arndb.de (Arnd Bergmann)
Date: 2012-07-17 20:27:36

On Monday 16 July 2012, Alexander Shiyan wrote:
Since we are trying to do to support multiple machines in a single kernel,
we need to eliminate the use of __initcall to be used for all machines.
Using .init_early call solves this problem.

Signed-off-by: Alexander Shiyan <redacted>
I've added patches 1-3 to the next/cleanup branch now.

Let's wait for comments on the clock patch first. My feeling is that
you should be using the clock framework.

	Arnd

[PATCH 4/4] ARM: clps711x: Added simple clkdev framework

From: arnd@arndb.de (Arnd Bergmann)
Date: 2012-07-17 20:33:09

On Monday 16 July 2012, Alexander Shiyan wrote:
Modern CPUs from CLPS711X-line can operate at frequencies other than 73 MHz.
This patch adds simple clkdev framework for handling all possible CPU rates.

Signed-off-by: Alexander Shiyan <redacted>
+Mike Turquette

We just had the exact same discussion about a new clock implementation for
mcs814x and for the socfpga port. My feeling is that it makes no sense
to keep adding new private implementations of the API as we're trying
to get rid of the existing ones and replace them with the common code.

If I understand this correctly, you should be using DEFINE_CLK_FIXED_RATE
and DEFINE_CLK_DIVIDER etc to define the initial clocks and the lookup
table, and possibly move all of that to drivers/clk.

	Arnd
quoted hunk
 arch/arm/Kconfig                            |    1 +
 arch/arm/mach-clps711x/common.c             |  104 +++++++++++++++++++++++++--
 arch/arm/mach-clps711x/include/mach/timex.h |   23 +------
 drivers/tty/serial/clps711x.c               |   19 ++++-
 4 files changed, 115 insertions(+), 32 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a91009c..fc2b454 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -361,6 +361,7 @@ config ARCH_HIGHBANK
 config ARCH_CLPS711X
 	bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
 	select CPU_ARM720T
+	select CLKDEV_LOOKUP
 	select ARCH_USES_GETTIMEOFFSET
 	select NEED_MACH_MEMORY_H
 	help
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index f15293b..daab6bf 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -26,6 +26,9 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/sched.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/module.h>
 
 #include <asm/sizes.h>
 #include <mach/hardware.h>
@@ -37,6 +40,52 @@
 #include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
+struct clk {
+	unsigned long rate;
+};
+
+static struct clk rtc_clk;
+static struct clk osc_clk;
+static struct clk ext_clk;
+static struct clk pll_clk;
+static struct clk cpu_clk;
+static struct clk bus_clk;
+static struct clk uart_clk;
+static struct clk timer_h_clk;
+static struct clk timer_l_clk;
+
+static unsigned long latch;
+
+/* Enable and Disable do nothing */
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static struct clk_lookup clps711x_lookups[] = {
+	CLKDEV_INIT( NULL, "rtc", &rtc_clk),
+	CLKDEV_INIT( NULL, "osc", &pll_clk),
+	CLKDEV_INIT( NULL, "ext", &ext_clk),
+	CLKDEV_INIT( NULL, "pll", &pll_clk),
+	CLKDEV_INIT( NULL, "cpu", &cpu_clk),
+	CLKDEV_INIT( NULL, "bus", &bus_clk),
+	CLKDEV_INIT( NULL, "uart", &uart_clk),
+	CLKDEV_INIT( NULL, "timer_h", &timer_h_clk),
+	CLKDEV_INIT( NULL, "timer_l", &timer_l_clk),
+};
+
 /*
  * This maps the generic CLPS711x registers
  */
@@ -166,8 +215,8 @@ void __init clps711x_init_irq(void)
 static unsigned long clps711x_gettimeoffset(void)
 {
 	unsigned long hwticks;
-	hwticks = LATCH - (clps_readl(TC2D) & 0xffff);	/* since last underflow */
-	return (hwticks * (tick_nsec / 1000)) / LATCH;
+	hwticks = latch - (clps_readl(TC2D) & 0xffff);
+	return (hwticks * (tick_nsec / 1000)) / latch;
 }
 
 /*
@@ -187,13 +236,54 @@ static struct irqaction clps711x_timer_irq = {
 
 static void __init clps711x_timer_init(void)
 {
-	unsigned int syscon;
+	u32 tmp;
+
+	rtc_clk.rate = 32768;
+	osc_clk.rate = 3686400;
+	ext_clk.rate = 13000000;
+
+	tmp = clps_readl(PLLR) >> 24;
+	if (tmp)
+		pll_clk.rate = (osc_clk.rate * tmp) / 2;
+	else
+		pll_clk.rate = 73728000; /* Default value */
+
+	tmp = clps_readl(SYSFLG2);
+	if (tmp & SYSFLG2_CKMODE) {
+		cpu_clk.rate = ext_clk.rate;
+		bus_clk.rate = cpu_clk.rate;
+	} else {
+		cpu_clk.rate = pll_clk.rate;
+		if (cpu_clk.rate >= 36864000)
+			bus_clk.rate = cpu_clk.rate / 2;
+		else
+			bus_clk.rate = 36864000 / 2;
+	}
+
+	uart_clk.rate = bus_clk.rate / 10;
+
+	if (tmp & SYSFLG2_CKMODE) {
+		tmp = clps_readl(SYSCON2);
+		if (tmp & SYSCON2_OSTB)
+			timer_h_clk.rate = ext_clk.rate / 26; /* 500 kHz */
+		else
+			timer_h_clk.rate = 541440;
+	} else
+		timer_h_clk.rate = cpu_clk.rate / 144;
+
+	timer_l_clk.rate = timer_h_clk.rate / 256;
+
+	latch = (timer_h_clk.rate + HZ / 2) / HZ;
+
+	clkdev_add_table(clps711x_lookups, ARRAY_SIZE(clps711x_lookups));
+
+	pr_info("CPU frequency set at %lu Hz.\n", cpu_clk.rate);
 
-	syscon = clps_readl(SYSCON1);
-	syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
-	clps_writel(syscon, SYSCON1);
+	tmp = clps_readl(SYSCON1);
+	tmp |= SYSCON1_TC2S | SYSCON1_TC2M;
+	clps_writel(tmp, SYSCON1);
 
-	clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
+	clps_writel(latch - 1, TC2D);
 
 	setup_irq(IRQ_TC2OI, &clps711x_timer_irq);
 }
diff --git a/arch/arm/mach-clps711x/include/mach/timex.h b/arch/arm/mach-clps711x/include/mach/timex.h
index ac8823c..3d98736 100644
--- a/arch/arm/mach-clps711x/include/mach/timex.h
+++ b/arch/arm/mach-clps711x/include/mach/timex.h
@@ -1,23 +1,2 @@
-/*
- *  arch/arm/mach-clps711x/include/mach/timex.h
- *
- *  Prospector 720T architecture timex specifications
- *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
+/* Bugus value */
 #define CLOCK_TICK_RATE 512000
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index d0f719f..d9f4983 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -37,6 +37,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -401,7 +402,6 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	{
 		.iobase		= SYSCON1,
 		.irq		= IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
-		.uartclk	= 3686400,
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 0,
@@ -410,7 +410,6 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	{
 		.iobase		= SYSCON2,
 		.irq		= IRQ_UTXINT2, /* IRQ_URXINT2 */
-		.uartclk	= 3686400,
 		.fifosize	= 16,
 		.ops		= &clps711x_pops,
 		.line		= 1,
@@ -418,6 +417,17 @@ static struct uart_port clps711x_ports[UART_NR] = {
 	}
 };
 
+static unsigned long clps711xuart_get_uartclk(void)
+{
+	struct clk *uart_clk;
+
+	uart_clk = clk_get(NULL, "uart");
+	if (!IS_ERR(uart_clk))
+		return clk_get_rate(uart_clk);
+
+	return 3686400; /* Default value */
+}
+
 #ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
 static void clps711xuart_console_putchar(struct uart_port *port, int ch)
 {
@@ -501,6 +511,7 @@ static int __init clps711xuart_console_setup(struct console *co, char *options)
 	 * console support.
 	 */
 	port = uart_get_console(clps711x_ports, UART_NR, co);
+	port->uartclk = clps711xuart_get_uartclk();
 
 	if (options)
 		uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -553,8 +564,10 @@ static int __init clps711xuart_init(void)
 	if (ret)
 		return ret;
 
-	for (i = 0; i < UART_NR; i++)
+	for (i = 0; i < UART_NR; i++) {
+		clps711x_ports[i].uartclk = clps711xuart_get_uartclk();
 		uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
+	}
 
 	return 0;
 }
-- 
1.7.3.4

[PATCH 4/4] ARM: clps711x: Added simple clkdev framework

From: Turquette, Mike <hidden>
Date: 2012-07-19 22:02:00

On Tue, Jul 17, 2012 at 1:33 PM, Arnd Bergmann [off-list ref] wrote:
On Monday 16 July 2012, Alexander Shiyan wrote:
quoted
Modern CPUs from CLPS711X-line can operate at frequencies other than 73 MHz.
This patch adds simple clkdev framework for handling all possible CPU rates.

Signed-off-by: Alexander Shiyan <redacted>
+Mike Turquette

We just had the exact same discussion about a new clock implementation for
mcs814x and for the socfpga port. My feeling is that it makes no sense
to keep adding new private implementations of the API as we're trying
to get rid of the existing ones and replace them with the common code.

If I understand this correctly, you should be using DEFINE_CLK_FIXED_RATE
and DEFINE_CLK_DIVIDER etc to define the initial clocks and the lookup
table, and possibly move all of that to drivers/clk.
Arnd is correct.  Let's go ahead and move everything over to the
common clk framework.  These patches will have to wait for 3.7
anyways, so there is plenty of time to port it over.

Regards,
Mike
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help