All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-20 22:54 ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

This series add device-tree support using CLKSRC_OF for initialization
of integrator ap and cp timers and sp804 timers. The timer code for all
of these is moved to drivers/clocksource. The common DT based
initialization of sp804 is supported on highbank, versatile-ab and
vexpress. The DT init support is newly added for versatile-ab.

This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
sched_clock selection series[1], and Arnd's default machine descriptor
patch (for default clocksource_of_init call). The full series is
available here:

git://sources.calxeda.com/kernel/linux.git arm-timers

http://sources.calxeda.com/gitweb/?p=kernel/linux.git;a=shortlog;h=refs/heads/arm-timers

I've tested integrator and versatile on qemu and on highbank h/w.

Rob

[1] http://comments.gmane.org/gmane.linux.ports.arm.kernel/222282

Haojian Zhuang (1):
  devtree: add binding documentation for sp804

Rob Herring (10):
  OF: add empty of_device_is_available for !OF
  ARM: remove extra timer-sp control register clearing
  ARM: timer-sp: convert to use CLKSRC_OF init
  ARM: highbank: use OF init for sp804 timer
  ARM: vexpress: remove sp804 OF init
  ARM: dts: vexpress: disable CA9 core tile sp804 timer
  ARM: versatile: add versatile dtbs to dtbs target
  ARM: versatile: use OF init for sp804 timer
  ARM: integrator-cp: convert use CLKSRC_OF for timer init
  ARM: move sp804 and integrator timers to drivers/clocksource

 .../devicetree/bindings/timer/arm,sp804.txt        |   29 +++
 arch/arm/Kconfig                                   |    5 -
 arch/arm/boot/dts/Makefile                         |    2 +
 arch/arm/boot/dts/integratorcp.dts                 |    6 +-
 arch/arm/boot/dts/versatile-ab.dts                 |   12 ++
 arch/arm/boot/dts/vexpress-v2p-ca9.dts             |    1 +
 arch/arm/common/Makefile                           |    1 -
 arch/arm/include/asm/hardware/timer-sp.h           |   15 --
 arch/arm/mach-highbank/highbank.c                  |   19 --
 arch/arm/mach-integrator/Kconfig                   |    1 +
 arch/arm/mach-integrator/integrator_ap.c           |  173 +-----------------
 arch/arm/mach-integrator/integrator_cp.c           |   42 +----
 arch/arm/mach-realview/core.c                      |   12 +-
 arch/arm/mach-versatile/core.c                     |   37 ++--
 arch/arm/mach-versatile/versatile_dt.c             |    1 -
 arch/arm/mach-vexpress/ct-ca9x4.c                  |    4 +-
 arch/arm/mach-vexpress/v2m.c                       |   17 +-
 drivers/clocksource/Kconfig                        |   12 ++
 drivers/clocksource/Makefile                       |    2 +
 .../hardware => drivers/clocksource}/arm_timer.h   |    6 +-
 drivers/clocksource/integrator_ap_timer.c          |  190 ++++++++++++++++++++
 .../arm/common => drivers/clocksource}/timer-sp.c  |  132 ++++++++++++--
 include/clocksource/integrator_ap_timer.h          |    7 +
 include/clocksource/timer-sp.h                     |   31 ++++
 include/linux/of.h                                 |    5 +
 25 files changed, 429 insertions(+), 333 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/arm,sp804.txt
 delete mode 100644 arch/arm/include/asm/hardware/timer-sp.h
 rename {arch/arm/include/asm/hardware => drivers/clocksource}/arm_timer.h (89%)
 create mode 100644 drivers/clocksource/integrator_ap_timer.c
 rename {arch/arm/common => drivers/clocksource}/timer-sp.c (60%)
 create mode 100644 include/clocksource/integrator_ap_timer.h
 create mode 100644 include/clocksource/timer-sp.h

-- 
1.7.10.4


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

* [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-20 22:54 ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This series add device-tree support using CLKSRC_OF for initialization
of integrator ap and cp timers and sp804 timers. The timer code for all
of these is moved to drivers/clocksource. The common DT based
initialization of sp804 is supported on highbank, versatile-ab and
vexpress. The DT init support is newly added for versatile-ab.

This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
sched_clock selection series[1], and Arnd's default machine descriptor
patch (for default clocksource_of_init call). The full series is
available here:

git://sources.calxeda.com/kernel/linux.git arm-timers

http://sources.calxeda.com/gitweb/?p=kernel/linux.git;a=shortlog;h=refs/heads/arm-timers

I've tested integrator and versatile on qemu and on highbank h/w.

Rob

[1] http://comments.gmane.org/gmane.linux.ports.arm.kernel/222282

Haojian Zhuang (1):
  devtree: add binding documentation for sp804

Rob Herring (10):
  OF: add empty of_device_is_available for !OF
  ARM: remove extra timer-sp control register clearing
  ARM: timer-sp: convert to use CLKSRC_OF init
  ARM: highbank: use OF init for sp804 timer
  ARM: vexpress: remove sp804 OF init
  ARM: dts: vexpress: disable CA9 core tile sp804 timer
  ARM: versatile: add versatile dtbs to dtbs target
  ARM: versatile: use OF init for sp804 timer
  ARM: integrator-cp: convert use CLKSRC_OF for timer init
  ARM: move sp804 and integrator timers to drivers/clocksource

 .../devicetree/bindings/timer/arm,sp804.txt        |   29 +++
 arch/arm/Kconfig                                   |    5 -
 arch/arm/boot/dts/Makefile                         |    2 +
 arch/arm/boot/dts/integratorcp.dts                 |    6 +-
 arch/arm/boot/dts/versatile-ab.dts                 |   12 ++
 arch/arm/boot/dts/vexpress-v2p-ca9.dts             |    1 +
 arch/arm/common/Makefile                           |    1 -
 arch/arm/include/asm/hardware/timer-sp.h           |   15 --
 arch/arm/mach-highbank/highbank.c                  |   19 --
 arch/arm/mach-integrator/Kconfig                   |    1 +
 arch/arm/mach-integrator/integrator_ap.c           |  173 +-----------------
 arch/arm/mach-integrator/integrator_cp.c           |   42 +----
 arch/arm/mach-realview/core.c                      |   12 +-
 arch/arm/mach-versatile/core.c                     |   37 ++--
 arch/arm/mach-versatile/versatile_dt.c             |    1 -
 arch/arm/mach-vexpress/ct-ca9x4.c                  |    4 +-
 arch/arm/mach-vexpress/v2m.c                       |   17 +-
 drivers/clocksource/Kconfig                        |   12 ++
 drivers/clocksource/Makefile                       |    2 +
 .../hardware => drivers/clocksource}/arm_timer.h   |    6 +-
 drivers/clocksource/integrator_ap_timer.c          |  190 ++++++++++++++++++++
 .../arm/common => drivers/clocksource}/timer-sp.c  |  132 ++++++++++++--
 include/clocksource/integrator_ap_timer.h          |    7 +
 include/clocksource/timer-sp.h                     |   31 ++++
 include/linux/of.h                                 |    5 +
 25 files changed, 429 insertions(+), 333 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/arm,sp804.txt
 delete mode 100644 arch/arm/include/asm/hardware/timer-sp.h
 rename {arch/arm/include/asm/hardware => drivers/clocksource}/arm_timer.h (89%)
 create mode 100644 drivers/clocksource/integrator_ap_timer.c
 rename {arch/arm/common => drivers/clocksource}/timer-sp.c (60%)
 create mode 100644 include/clocksource/integrator_ap_timer.h
 create mode 100644 include/clocksource/timer-sp.h

-- 
1.7.10.4

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

* [PATCH 01/11] OF: add empty of_device_is_available for !OF
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Add an empty version of of_device_is_available.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 include/linux/of.h |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index a0f1292..6fe655b 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
 	return 0;
 }
 
+static inline int of_device_is_available(const struct device_node *device,)
+{
+	return 0;
+}
+
 static inline struct property *of_find_property(const struct device_node *np,
 						const char *name,
 						int *lenp)
-- 
1.7.10.4


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

* [PATCH 01/11] OF: add empty of_device_is_available for !OF
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Add an empty version of of_device_is_available.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 include/linux/of.h |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/linux/of.h b/include/linux/of.h
index a0f1292..6fe655b 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
 	return 0;
 }
 
+static inline int of_device_is_available(const struct device_node *device,)
+{
+	return 0;
+}
+
 static inline struct property *of_find_property(const struct device_node *np,
 						const char *name,
 						int *lenp)
-- 
1.7.10.4

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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

The timer-sp initialization code clears the control register before
initializing the timers, so every platform doing this is redundant.

For unused timers, we should not care what state they are in.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-integrator/integrator_ap.c |    4 ----
 arch/arm/mach-integrator/integrator_cp.c |    7 -------
 arch/arm/mach-realview/core.c            |    9 ---------
 arch/arm/mach-versatile/core.c           |    9 ---------
 arch/arm/mach-vexpress/v2m.c             |    3 ---
 5 files changed, 32 deletions(-)

diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index ea96144..4cb322d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
 	clk_prepare_enable(clk);
 	rate = clk_get_rate(clk);
 
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
 	integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
 				IRQ_TIMERINT1);
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 2b0db82..c68e7d8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -33,7 +33,6 @@
 #include <mach/platform.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <mach/cm.h>
@@ -267,7 +266,6 @@ static void __init cp_of_timer_init(void)
 	base = of_iomap(node, 0);
 	if (WARN_ON(!base))
 		return;
-	writel(0, base + TIMER_CTRL);
 	sp804_clocksource_init(base, node->name);
 
 	err = of_property_read_string(of_aliases,
@@ -279,7 +277,6 @@ static void __init cp_of_timer_init(void)
 	if (WARN_ON(!base))
 		return;
 	irq = irq_of_parse_and_map(node, 0);
-	writel(0, base + TIMER_CTRL);
 	sp804_clockevents_init(base, irq, node->name);
 }
 
@@ -510,10 +507,6 @@ static void __init intcp_init_irq(void)
 
 static void __init cp_timer_init(void)
 {
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
 	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
 }
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 1d5ee5c..8ce6366 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -35,7 +35,6 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
@@ -355,14 +354,6 @@ void __init realview_timer_init(unsigned int timer_irq)
 	       (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
 	       __io_address(REALVIEW_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, timer0_va_base + TIMER_CTRL);
-	writel(0, timer1_va_base + TIMER_CTRL);
-	writel(0, timer2_va_base + TIMER_CTRL);
-	writel(0, timer3_va_base + TIMER_CTRL);
-
 	sp804_clocksource_init(timer3_va_base, "timer3");
 	sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 25160ae..286303a 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -40,7 +40,6 @@
 #include <linux/bitops.h>
 
 #include <asm/irq.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 #include <asm/mach-types.h>
 
@@ -799,14 +798,6 @@ void __init versatile_timer_init(void)
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
 	       __io_address(VERSATILE_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
 }
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 6215717..9fbfbe4 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -61,9 +61,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
 	if (WARN_ON(!base || irq == NO_IRQ))
 		return;
 
-	writel(0, base + TIMER_1_BASE + TIMER_CTRL);
-	writel(0, base + TIMER_2_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
 	sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
 }
-- 
1.7.10.4


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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Russell King, pawel.moll-5wv7dgnIgG8, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ

From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>

The timer-sp initialization code clears the control register before
initializing the timers, so every platform doing this is redundant.

For unused timers, we should not care what state they are in.

Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/mach-integrator/integrator_ap.c |    4 ----
 arch/arm/mach-integrator/integrator_cp.c |    7 -------
 arch/arm/mach-realview/core.c            |    9 ---------
 arch/arm/mach-versatile/core.c           |    9 ---------
 arch/arm/mach-vexpress/v2m.c             |    3 ---
 5 files changed, 32 deletions(-)

diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index ea96144..4cb322d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
 	clk_prepare_enable(clk);
 	rate = clk_get_rate(clk);
 
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
 	integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
 				IRQ_TIMERINT1);
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 2b0db82..c68e7d8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -33,7 +33,6 @@
 #include <mach/platform.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <mach/cm.h>
@@ -267,7 +266,6 @@ static void __init cp_of_timer_init(void)
 	base = of_iomap(node, 0);
 	if (WARN_ON(!base))
 		return;
-	writel(0, base + TIMER_CTRL);
 	sp804_clocksource_init(base, node->name);
 
 	err = of_property_read_string(of_aliases,
@@ -279,7 +277,6 @@ static void __init cp_of_timer_init(void)
 	if (WARN_ON(!base))
 		return;
 	irq = irq_of_parse_and_map(node, 0);
-	writel(0, base + TIMER_CTRL);
 	sp804_clockevents_init(base, irq, node->name);
 }
 
@@ -510,10 +507,6 @@ static void __init intcp_init_irq(void)
 
 static void __init cp_timer_init(void)
 {
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
 	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
 }
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 1d5ee5c..8ce6366 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -35,7 +35,6 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
@@ -355,14 +354,6 @@ void __init realview_timer_init(unsigned int timer_irq)
 	       (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
 	       __io_address(REALVIEW_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, timer0_va_base + TIMER_CTRL);
-	writel(0, timer1_va_base + TIMER_CTRL);
-	writel(0, timer2_va_base + TIMER_CTRL);
-	writel(0, timer3_va_base + TIMER_CTRL);
-
 	sp804_clocksource_init(timer3_va_base, "timer3");
 	sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 25160ae..286303a 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -40,7 +40,6 @@
 #include <linux/bitops.h>
 
 #include <asm/irq.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 #include <asm/mach-types.h>
 
@@ -799,14 +798,6 @@ void __init versatile_timer_init(void)
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
 	       __io_address(VERSATILE_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
 }
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 6215717..9fbfbe4 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -61,9 +61,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
 	if (WARN_ON(!base || irq == NO_IRQ))
 		return;
 
-	writel(0, base + TIMER_1_BASE + TIMER_CTRL);
-	writel(0, base + TIMER_2_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
 	sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
 }
-- 
1.7.10.4

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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

The timer-sp initialization code clears the control register before
initializing the timers, so every platform doing this is redundant.

For unused timers, we should not care what state they are in.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-integrator/integrator_ap.c |    4 ----
 arch/arm/mach-integrator/integrator_cp.c |    7 -------
 arch/arm/mach-realview/core.c            |    9 ---------
 arch/arm/mach-versatile/core.c           |    9 ---------
 arch/arm/mach-vexpress/v2m.c             |    3 ---
 5 files changed, 32 deletions(-)

diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index ea96144..4cb322d 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
 	clk_prepare_enable(clk);
 	rate = clk_get_rate(clk);
 
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE);
 	integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE,
 				IRQ_TIMERINT1);
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 2b0db82..c68e7d8 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -33,7 +33,6 @@
 #include <mach/platform.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <mach/cm.h>
@@ -267,7 +266,6 @@ static void __init cp_of_timer_init(void)
 	base = of_iomap(node, 0);
 	if (WARN_ON(!base))
 		return;
-	writel(0, base + TIMER_CTRL);
 	sp804_clocksource_init(base, node->name);
 
 	err = of_property_read_string(of_aliases,
@@ -279,7 +277,6 @@ static void __init cp_of_timer_init(void)
 	if (WARN_ON(!base))
 		return;
 	irq = irq_of_parse_and_map(node, 0);
-	writel(0, base + TIMER_CTRL);
 	sp804_clockevents_init(base, irq, node->name);
 }
 
@@ -510,10 +507,6 @@ static void __init intcp_init_irq(void)
 
 static void __init cp_timer_init(void)
 {
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
 	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
 }
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 1d5ee5c..8ce6366 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -35,7 +35,6 @@
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
@@ -355,14 +354,6 @@ void __init realview_timer_init(unsigned int timer_irq)
 	       (REALVIEW_TIMCLK << REALVIEW_TIMER4_EnSel) | val,
 	       __io_address(REALVIEW_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, timer0_va_base + TIMER_CTRL);
-	writel(0, timer1_va_base + TIMER_CTRL);
-	writel(0, timer2_va_base + TIMER_CTRL);
-	writel(0, timer3_va_base + TIMER_CTRL);
-
 	sp804_clocksource_init(timer3_va_base, "timer3");
 	sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
 }
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 25160ae..286303a 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -40,7 +40,6 @@
 #include <linux/bitops.h>
 
 #include <asm/irq.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/icst.h>
 #include <asm/mach-types.h>
 
@@ -799,14 +798,6 @@ void __init versatile_timer_init(void)
 	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
 	       __io_address(VERSATILE_SCTL_BASE));
 
-	/*
-	 * Initialise to a known state (all timers off)
-	 */
-	writel(0, TIMER0_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
-	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
 }
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 6215717..9fbfbe4 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -61,9 +61,6 @@ static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
 	if (WARN_ON(!base || irq == NO_IRQ))
 		return;
 
-	writel(0, base + TIMER_1_BASE + TIMER_CTRL);
-	writel(0, base + TIMER_2_BASE + TIMER_CTRL);
-
 	sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
 	sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
 }
-- 
1.7.10.4

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

This adds CLKSRC_OF based init for sp804 timer. The clock initialization is
refactored to support retrieving the clock(s) from the DT.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/Kconfig                         |    1 +
 arch/arm/common/timer-sp.c               |   98 +++++++++++++++++++++++++-----
 arch/arm/include/asm/hardware/timer-sp.h |   16 +++--
 3 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f0f90f0..774131a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1172,6 +1172,7 @@ config PLAT_VERSATILE
 config ARM_TIMER_SP804
 	bool
 	select CLKSRC_MMIO
+	select CLKSRC_OF if OF
 	select HAVE_SCHED_CLOCK
 
 source arch/arm/mm/Kconfig
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 9d2d3ba..3e86835 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -25,33 +25,28 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 
-static long __init sp804_get_clock_rate(const char *name)
+static long __init sp804_get_clock_rate(struct clk *clk)
 {
-	struct clk *clk;
 	long rate;
 	int err;
 
-	clk = clk_get_sys("sp804", name);
-	if (IS_ERR(clk)) {
-		pr_err("sp804: %s clock not found: %d\n", name,
-			(int)PTR_ERR(clk));
-		return PTR_ERR(clk);
-	}
-
 	err = clk_prepare(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to prepare: %d\n", name, err);
+		pr_err("sp804: clock failed to prepare: %d\n", err);
 		clk_put(clk);
 		return err;
 	}
 
 	err = clk_enable(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+		pr_err("sp804: clock failed to enable: %d\n", err);
 		clk_unprepare(clk);
 		clk_put(clk);
 		return err;
@@ -59,7 +54,7 @@ static long __init sp804_get_clock_rate(const char *name)
 
 	rate = clk_get_rate(clk);
 	if (rate < 0) {
-		pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+		pr_err("sp804: clock failed to get rate: %ld\n", rate);
 		clk_disable(clk);
 		clk_unprepare(clk);
 		clk_put(clk);
@@ -77,9 +72,21 @@ static u32 sp804_read(void)
 
 void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
 						     const char *name,
+						     struct clk *clk,
 						     int use_sched_clock)
 {
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk) {
+		clk = clk_get_sys("sp804", name);
+		if (IS_ERR(clk)) {
+			pr_err("sp804: clock not found: %d\n",
+			       (int)PTR_ERR(clk));
+			return;
+		}
+	}
+
+	rate = sp804_get_clock_rate(clk);
 
 	if (rate < 0)
 		return;
@@ -171,12 +178,20 @@ static struct irqaction sp804_timer_irq = {
 	.dev_id		= &sp804_clockevent,
 };
 
-void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
-	const char *name)
+void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name)
 {
 	struct clock_event_device *evt = &sp804_clockevent;
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk)
+		clk = clk_get_sys("sp804", name);
+	if (IS_ERR(clk)) {
+		pr_err("sp804: %s clock not found: %d\n", name,
+			(int)PTR_ERR(clk));
+		return;
+	}
 
+	rate = sp804_get_clock_rate(clk);
 	if (rate < 0)
 		return;
 
@@ -186,6 +201,57 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
 	evt->irq = irq;
 	evt->cpumask = cpu_possible_mask;
 
+	writel(0, clkevt_base + TIMER_CTRL);
+
 	setup_irq(irq, &sp804_timer_irq);
 	clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
 }
+
+static void __init sp804_of_init(struct device_node *np)
+{
+	static bool initialized = false;
+	void __iomem *base;
+	int irq;
+	u32 irq_num = 0;
+	bool tmr2_evt = false;
+	struct clk *clk0, *clk1;
+	const char *name = of_get_property(np, "compatible", NULL);
+
+	if (initialized || !of_device_is_available(np))
+		return;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	clk0 = of_clk_get(np, 0);
+	if (IS_ERR(clk0))
+		clk0 = NULL;
+
+	/* Get the 2nd clock if the timer has 2 timer clocks */
+	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
+		clk1 = of_clk_get(np, 1);
+		if (IS_ERR(clk1)) {
+			pr_err("sp804: %s clock not found: %d\n", np->name,
+				(int)PTR_ERR(clk1));
+			return;
+		}
+	} else
+		clk1 = clk0;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0)
+		return;
+
+	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
+	if (irq_num == 2)
+		tmr2_evt = true;
+
+	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
+				 irq, tmr2_evt ? clk1 : clk0, name);
+	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
+						 name, tmr2_evt ? clk0 : clk1, 1);
+
+	initialized = true;
+}
+CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 2dd9d3f..bb28af7 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -1,15 +1,23 @@
+struct clk;
+
 void __sp804_clocksource_and_sched_clock_init(void __iomem *,
-					      const char *, int);
+					      const char *, struct clk *, int);
+void __sp804_clockevents_init(void __iomem *, unsigned int,
+			      struct clk *, const char *);
 
 static inline void sp804_clocksource_init(void __iomem *base, const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 0);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 0);
 }
 
 static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
 							  const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 1);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 1);
 }
 
-void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
+static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name)
+{
+	__sp804_clockevents_init(base, irq, NULL, name);
+
+}
-- 
1.7.10.4


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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Russell King, pawel.moll-5wv7dgnIgG8, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ

From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>

This adds CLKSRC_OF based init for sp804 timer. The clock initialization is
refactored to support retrieving the clock(s) from the DT.

Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/Kconfig                         |    1 +
 arch/arm/common/timer-sp.c               |   98 +++++++++++++++++++++++++-----
 arch/arm/include/asm/hardware/timer-sp.h |   16 +++--
 3 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f0f90f0..774131a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1172,6 +1172,7 @@ config PLAT_VERSATILE
 config ARM_TIMER_SP804
 	bool
 	select CLKSRC_MMIO
+	select CLKSRC_OF if OF
 	select HAVE_SCHED_CLOCK
 
 source arch/arm/mm/Kconfig
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 9d2d3ba..3e86835 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -25,33 +25,28 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 
-static long __init sp804_get_clock_rate(const char *name)
+static long __init sp804_get_clock_rate(struct clk *clk)
 {
-	struct clk *clk;
 	long rate;
 	int err;
 
-	clk = clk_get_sys("sp804", name);
-	if (IS_ERR(clk)) {
-		pr_err("sp804: %s clock not found: %d\n", name,
-			(int)PTR_ERR(clk));
-		return PTR_ERR(clk);
-	}
-
 	err = clk_prepare(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to prepare: %d\n", name, err);
+		pr_err("sp804: clock failed to prepare: %d\n", err);
 		clk_put(clk);
 		return err;
 	}
 
 	err = clk_enable(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+		pr_err("sp804: clock failed to enable: %d\n", err);
 		clk_unprepare(clk);
 		clk_put(clk);
 		return err;
@@ -59,7 +54,7 @@ static long __init sp804_get_clock_rate(const char *name)
 
 	rate = clk_get_rate(clk);
 	if (rate < 0) {
-		pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+		pr_err("sp804: clock failed to get rate: %ld\n", rate);
 		clk_disable(clk);
 		clk_unprepare(clk);
 		clk_put(clk);
@@ -77,9 +72,21 @@ static u32 sp804_read(void)
 
 void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
 						     const char *name,
+						     struct clk *clk,
 						     int use_sched_clock)
 {
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk) {
+		clk = clk_get_sys("sp804", name);
+		if (IS_ERR(clk)) {
+			pr_err("sp804: clock not found: %d\n",
+			       (int)PTR_ERR(clk));
+			return;
+		}
+	}
+
+	rate = sp804_get_clock_rate(clk);
 
 	if (rate < 0)
 		return;
@@ -171,12 +178,20 @@ static struct irqaction sp804_timer_irq = {
 	.dev_id		= &sp804_clockevent,
 };
 
-void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
-	const char *name)
+void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name)
 {
 	struct clock_event_device *evt = &sp804_clockevent;
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk)
+		clk = clk_get_sys("sp804", name);
+	if (IS_ERR(clk)) {
+		pr_err("sp804: %s clock not found: %d\n", name,
+			(int)PTR_ERR(clk));
+		return;
+	}
 
+	rate = sp804_get_clock_rate(clk);
 	if (rate < 0)
 		return;
 
@@ -186,6 +201,57 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
 	evt->irq = irq;
 	evt->cpumask = cpu_possible_mask;
 
+	writel(0, clkevt_base + TIMER_CTRL);
+
 	setup_irq(irq, &sp804_timer_irq);
 	clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
 }
+
+static void __init sp804_of_init(struct device_node *np)
+{
+	static bool initialized = false;
+	void __iomem *base;
+	int irq;
+	u32 irq_num = 0;
+	bool tmr2_evt = false;
+	struct clk *clk0, *clk1;
+	const char *name = of_get_property(np, "compatible", NULL);
+
+	if (initialized || !of_device_is_available(np))
+		return;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	clk0 = of_clk_get(np, 0);
+	if (IS_ERR(clk0))
+		clk0 = NULL;
+
+	/* Get the 2nd clock if the timer has 2 timer clocks */
+	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
+		clk1 = of_clk_get(np, 1);
+		if (IS_ERR(clk1)) {
+			pr_err("sp804: %s clock not found: %d\n", np->name,
+				(int)PTR_ERR(clk1));
+			return;
+		}
+	} else
+		clk1 = clk0;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0)
+		return;
+
+	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
+	if (irq_num == 2)
+		tmr2_evt = true;
+
+	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
+				 irq, tmr2_evt ? clk1 : clk0, name);
+	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
+						 name, tmr2_evt ? clk0 : clk1, 1);
+
+	initialized = true;
+}
+CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 2dd9d3f..bb28af7 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -1,15 +1,23 @@
+struct clk;
+
 void __sp804_clocksource_and_sched_clock_init(void __iomem *,
-					      const char *, int);
+					      const char *, struct clk *, int);
+void __sp804_clockevents_init(void __iomem *, unsigned int,
+			      struct clk *, const char *);
 
 static inline void sp804_clocksource_init(void __iomem *base, const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 0);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 0);
 }
 
 static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
 							  const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 1);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 1);
 }
 
-void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
+static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name)
+{
+	__sp804_clockevents_init(base, irq, NULL, name);
+
+}
-- 
1.7.10.4

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

This adds CLKSRC_OF based init for sp804 timer. The clock initialization is
refactored to support retrieving the clock(s) from the DT.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/Kconfig                         |    1 +
 arch/arm/common/timer-sp.c               |   98 +++++++++++++++++++++++++-----
 arch/arm/include/asm/hardware/timer-sp.h |   16 +++--
 3 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f0f90f0..774131a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1172,6 +1172,7 @@ config PLAT_VERSATILE
 config ARM_TIMER_SP804
 	bool
 	select CLKSRC_MMIO
+	select CLKSRC_OF if OF
 	select HAVE_SCHED_CLOCK
 
 source arch/arm/mm/Kconfig
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 9d2d3ba..3e86835 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -25,33 +25,28 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 
 #include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
 
-static long __init sp804_get_clock_rate(const char *name)
+static long __init sp804_get_clock_rate(struct clk *clk)
 {
-	struct clk *clk;
 	long rate;
 	int err;
 
-	clk = clk_get_sys("sp804", name);
-	if (IS_ERR(clk)) {
-		pr_err("sp804: %s clock not found: %d\n", name,
-			(int)PTR_ERR(clk));
-		return PTR_ERR(clk);
-	}
-
 	err = clk_prepare(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to prepare: %d\n", name, err);
+		pr_err("sp804: clock failed to prepare: %d\n", err);
 		clk_put(clk);
 		return err;
 	}
 
 	err = clk_enable(clk);
 	if (err) {
-		pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+		pr_err("sp804: clock failed to enable: %d\n", err);
 		clk_unprepare(clk);
 		clk_put(clk);
 		return err;
@@ -59,7 +54,7 @@ static long __init sp804_get_clock_rate(const char *name)
 
 	rate = clk_get_rate(clk);
 	if (rate < 0) {
-		pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+		pr_err("sp804: clock failed to get rate: %ld\n", rate);
 		clk_disable(clk);
 		clk_unprepare(clk);
 		clk_put(clk);
@@ -77,9 +72,21 @@ static u32 sp804_read(void)
 
 void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
 						     const char *name,
+						     struct clk *clk,
 						     int use_sched_clock)
 {
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk) {
+		clk = clk_get_sys("sp804", name);
+		if (IS_ERR(clk)) {
+			pr_err("sp804: clock not found: %d\n",
+			       (int)PTR_ERR(clk));
+			return;
+		}
+	}
+
+	rate = sp804_get_clock_rate(clk);
 
 	if (rate < 0)
 		return;
@@ -171,12 +178,20 @@ static struct irqaction sp804_timer_irq = {
 	.dev_id		= &sp804_clockevent,
 };
 
-void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
-	const char *name)
+void __init __sp804_clockevents_init(void __iomem *base, unsigned int irq, struct clk *clk, const char *name)
 {
 	struct clock_event_device *evt = &sp804_clockevent;
-	long rate = sp804_get_clock_rate(name);
+	long rate;
+
+	if (!clk)
+		clk = clk_get_sys("sp804", name);
+	if (IS_ERR(clk)) {
+		pr_err("sp804: %s clock not found: %d\n", name,
+			(int)PTR_ERR(clk));
+		return;
+	}
 
+	rate = sp804_get_clock_rate(clk);
 	if (rate < 0)
 		return;
 
@@ -186,6 +201,57 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
 	evt->irq = irq;
 	evt->cpumask = cpu_possible_mask;
 
+	writel(0, clkevt_base + TIMER_CTRL);
+
 	setup_irq(irq, &sp804_timer_irq);
 	clockevents_config_and_register(evt, rate, 0xf, 0xffffffff);
 }
+
+static void __init sp804_of_init(struct device_node *np)
+{
+	static bool initialized = false;
+	void __iomem *base;
+	int irq;
+	u32 irq_num = 0;
+	bool tmr2_evt = false;
+	struct clk *clk0, *clk1;
+	const char *name = of_get_property(np, "compatible", NULL);
+
+	if (initialized || !of_device_is_available(np))
+		return;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	clk0 = of_clk_get(np, 0);
+	if (IS_ERR(clk0))
+		clk0 = NULL;
+
+	/* Get the 2nd clock if the timer has 2 timer clocks */
+	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
+		clk1 = of_clk_get(np, 1);
+		if (IS_ERR(clk1)) {
+			pr_err("sp804: %s clock not found: %d\n", np->name,
+				(int)PTR_ERR(clk1));
+			return;
+		}
+	} else
+		clk1 = clk0;
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0)
+		return;
+
+	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
+	if (irq_num == 2)
+		tmr2_evt = true;
+
+	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
+				 irq, tmr2_evt ? clk1 : clk0, name);
+	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
+						 name, tmr2_evt ? clk0 : clk1, 1);
+
+	initialized = true;
+}
+CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/arch/arm/include/asm/hardware/timer-sp.h
index 2dd9d3f..bb28af7 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/arch/arm/include/asm/hardware/timer-sp.h
@@ -1,15 +1,23 @@
+struct clk;
+
 void __sp804_clocksource_and_sched_clock_init(void __iomem *,
-					      const char *, int);
+					      const char *, struct clk *, int);
+void __sp804_clockevents_init(void __iomem *, unsigned int,
+			      struct clk *, const char *);
 
 static inline void sp804_clocksource_init(void __iomem *base, const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 0);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 0);
 }
 
 static inline void sp804_clocksource_and_sched_clock_init(void __iomem *base,
 							  const char *name)
 {
-	__sp804_clocksource_and_sched_clock_init(base, name, 1);
+	__sp804_clocksource_and_sched_clock_init(base, name, NULL, 1);
 }
 
-void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
+static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq, const char *name)
+{
+	__sp804_clockevents_init(base, irq, NULL, name);
+
+}
-- 
1.7.10.4

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

* [PATCH 04/11] ARM: highbank: use OF init for sp804 timer
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Remove the highbank specific setup for the sp804 timer now that
clocksource_of_init will do it.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-highbank/highbank.c |   19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 758150e..e7df2dd 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -32,8 +32,6 @@
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/smp_plat.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/timer-sp.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -90,33 +88,16 @@ static void __init highbank_init_irq(void)
 #endif
 }
 
-static struct clk_lookup lookup = {
-	.dev_id = "sp804",
-	.con_id = NULL,
-};
-
 static void __init highbank_timer_init(void)
 {
-	int irq;
 	struct device_node *np;
-	void __iomem *timer_base;
 
 	/* Map system registers */
 	np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
 	sregs_base = of_iomap(np, 0);
 	WARN_ON(!sregs_base);
 
-	np = of_find_compatible_node(NULL, NULL, "arm,sp804");
-	timer_base = of_iomap(np, 0);
-	WARN_ON(!timer_base);
-	irq = irq_of_parse_and_map(np, 0);
-
 	of_clk_init(NULL);
-	lookup.clk = of_clk_get(np, 0);
-	clkdev_add(&lookup);
-
-	sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
-	sp804_clockevents_init(timer_base, irq, "timer0");
 
 	clocksource_of_init();
 }
-- 
1.7.10.4


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

* [PATCH 04/11] ARM: highbank: use OF init for sp804 timer
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Remove the highbank specific setup for the sp804 timer now that
clocksource_of_init will do it.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-highbank/highbank.c |   19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 758150e..e7df2dd 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -32,8 +32,6 @@
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/smp_plat.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/timer-sp.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -90,33 +88,16 @@ static void __init highbank_init_irq(void)
 #endif
 }
 
-static struct clk_lookup lookup = {
-	.dev_id = "sp804",
-	.con_id = NULL,
-};
-
 static void __init highbank_timer_init(void)
 {
-	int irq;
 	struct device_node *np;
-	void __iomem *timer_base;
 
 	/* Map system registers */
 	np = of_find_compatible_node(NULL, NULL, "calxeda,hb-sregs");
 	sregs_base = of_iomap(np, 0);
 	WARN_ON(!sregs_base);
 
-	np = of_find_compatible_node(NULL, NULL, "arm,sp804");
-	timer_base = of_iomap(np, 0);
-	WARN_ON(!timer_base);
-	irq = irq_of_parse_and_map(np, 0);
-
 	of_clk_init(NULL);
-	lookup.clk = of_clk_get(np, 0);
-	clkdev_add(&lookup);
-
-	sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
-	sp804_clockevents_init(timer_base, irq, "timer0");
 
 	clocksource_of_init();
 }
-- 
1.7.10.4

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

* [PATCH 05/11] ARM: vexpress: remove sp804 OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Remove the vexpress specific setup for the sp804 timer now that
clocksource_of_init will do it.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-vexpress/v2m.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 9fbfbe4..09e571d 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -428,20 +428,9 @@ void __init v2m_dt_init_early(void)
 
 static void __init v2m_dt_timer_init(void)
 {
-	struct device_node *node = NULL;
-
 	vexpress_clk_of_init();
 
 	clocksource_of_init();
-	do {
-		node = of_find_compatible_node(node, NULL, "arm,sp804");
-	} while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
-	if (node) {
-		pr_info("Using SP804 '%s' as a clock & events source\n",
-				node->full_name);
-		v2m_sp804_init(of_iomap(node, 0),
-				irq_of_parse_and_map(node, 0));
-	}
 
 	versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
 				24000000);
-- 
1.7.10.4


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

* [PATCH 05/11] ARM: vexpress: remove sp804 OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Russell King, pawel.moll-5wv7dgnIgG8, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ

From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>

Remove the vexpress specific setup for the sp804 timer now that
clocksource_of_init will do it.

Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/mach-vexpress/v2m.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 9fbfbe4..09e571d 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -428,20 +428,9 @@ void __init v2m_dt_init_early(void)
 
 static void __init v2m_dt_timer_init(void)
 {
-	struct device_node *node = NULL;
-
 	vexpress_clk_of_init();
 
 	clocksource_of_init();
-	do {
-		node = of_find_compatible_node(node, NULL, "arm,sp804");
-	} while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
-	if (node) {
-		pr_info("Using SP804 '%s' as a clock & events source\n",
-				node->full_name);
-		v2m_sp804_init(of_iomap(node, 0),
-				irq_of_parse_and_map(node, 0));
-	}
 
 	versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
 				24000000);
-- 
1.7.10.4

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

* [PATCH 05/11] ARM: vexpress: remove sp804 OF init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Remove the vexpress specific setup for the sp804 timer now that
clocksource_of_init will do it.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/mach-vexpress/v2m.c |   11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 9fbfbe4..09e571d 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -428,20 +428,9 @@ void __init v2m_dt_init_early(void)
 
 static void __init v2m_dt_timer_init(void)
 {
-	struct device_node *node = NULL;
-
 	vexpress_clk_of_init();
 
 	clocksource_of_init();
-	do {
-		node = of_find_compatible_node(node, NULL, "arm,sp804");
-	} while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
-	if (node) {
-		pr_info("Using SP804 '%s' as a clock & events source\n",
-				node->full_name);
-		v2m_sp804_init(of_iomap(node, 0),
-				irq_of_parse_and_map(node, 0));
-	}
 
 	versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
 				24000000);
-- 
1.7.10.4

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

* [PATCH 06/11] ARM: dts: vexpress: disable CA9 core tile sp804 timer
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

The motherboard sp804 timer is used, but core tile sp804 timer is not.
According to Russell King, the clock configuration is undocumented and
defaults to 32kHz which is not desireable. So mark core tile sp804 timer
as disabled.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/vexpress-v2p-ca9.dts |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 1420bb1..62d9b22 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -98,6 +98,7 @@
 			     <0 49 4>;
 		clocks = <&oscclk2>, <&oscclk2>;
 		clock-names = "timclk", "apb_pclk";
+		status = "disabled";
 	};
 
 	watchdog@100e5000 {
-- 
1.7.10.4


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

* [PATCH 06/11] ARM: dts: vexpress: disable CA9 core tile sp804 timer
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ
  Cc: Russell King, pawel.moll-5wv7dgnIgG8, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ

From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>

The motherboard sp804 timer is used, but core tile sp804 timer is not.
According to Russell King, the clock configuration is undocumented and
defaults to 32kHz which is not desireable. So mark core tile sp804 timer
as disabled.

Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
---
 arch/arm/boot/dts/vexpress-v2p-ca9.dts |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 1420bb1..62d9b22 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -98,6 +98,7 @@
 			     <0 49 4>;
 		clocks = <&oscclk2>, <&oscclk2>;
 		clock-names = "timclk", "apb_pclk";
+		status = "disabled";
 	};
 
 	watchdog@100e5000 {
-- 
1.7.10.4

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

* [PATCH 06/11] ARM: dts: vexpress: disable CA9 core tile sp804 timer
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

The motherboard sp804 timer is used, but core tile sp804 timer is not.
According to Russell King, the clock configuration is undocumented and
defaults to 32kHz which is not desireable. So mark core tile sp804 timer
as disabled.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/vexpress-v2p-ca9.dts |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/vexpress-v2p-ca9.dts b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
index 1420bb1..62d9b22 100644
--- a/arch/arm/boot/dts/vexpress-v2p-ca9.dts
+++ b/arch/arm/boot/dts/vexpress-v2p-ca9.dts
@@ -98,6 +98,7 @@
 			     <0 49 4>;
 		clocks = <&oscclk2>, <&oscclk2>;
 		clock-names = "timclk", "apb_pclk";
+		status = "disabled";
 	};
 
 	watchdog at 100e5000 {
-- 
1.7.10.4

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

* [PATCH 07/11] ARM: versatile: add versatile dtbs to dtbs target
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Add the versatile platform dtbs to the dtbs make rule.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/Makefile |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 9c62558..08d298d 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -165,6 +165,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
 	tegra30-cardhu-a04.dtb \
 	tegra114-dalmore.dtb \
 	tegra114-pluto.dtb
+dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
+	versatile-pb.dtb
 dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
 	vexpress-v2p-ca9.dtb \
 	vexpress-v2p-ca15-tc1.dtb \
-- 
1.7.10.4


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

* [PATCH 07/11] ARM: versatile: add versatile dtbs to dtbs target
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Add the versatile platform dtbs to the dtbs make rule.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/Makefile |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 9c62558..08d298d 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -165,6 +165,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \
 	tegra30-cardhu-a04.dtb \
 	tegra114-dalmore.dtb \
 	tegra114-pluto.dtb
+dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \
+	versatile-pb.dtb
 dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \
 	vexpress-v2p-ca9.dtb \
 	vexpress-v2p-ca15-tc1.dtb \
-- 
1.7.10.4

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

* [PATCH 08/11] ARM: versatile: use OF init for sp804 timer
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Enable DT based init for the sp804 timers on versatile DT platform.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/versatile-ab.dts     |   12 ++++++++++++
 arch/arm/mach-versatile/core.c         |   26 +++++++++++++-------------
 arch/arm/mach-versatile/versatile_dt.c |    1 -
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index e2fe319..dde75ae 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -121,6 +121,18 @@
 			interrupts = <0>;
 		};
 
+		timer@101e2000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x101e2000 0x1000>;
+			interrupts = <4>;
+		};
+
+		timer@101e3000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x101e3000 0x1000>;
+			interrupts = <5>;
+		};
+
 		gpio0: gpio@101e4000 {
 			compatible = "arm,pl061", "arm,primecell";
 			reg = <0x101e4000 0x1000>;
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 286303a..5cdfc87 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -748,12 +748,25 @@ void versatile_restart(char mode, const char *cmd)
 /* Early initializations */
 void __init versatile_init_early(void)
 {
+	u32 val;
 	void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
 
 	osc4_clk.vcoreg	= sys + VERSATILE_SYS_OSCCLCD_OFFSET;
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
+
+	/*
+	 * set clock frequency:
+	 *	VERSATILE_REFCLK is 32KHz
+	 *	VERSATILE_TIMCLK is 1MHz
+	 */
+	val = readl(__io_address(VERSATILE_SCTL_BASE));
+	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+	       __io_address(VERSATILE_SCTL_BASE));
 }
 
 void __init versatile_init(void)
@@ -784,19 +797,6 @@ void __init versatile_init(void)
  */
 void __init versatile_timer_init(void)
 {
-	u32 val;
-
-	/* 
-	 * set clock frequency: 
-	 *	VERSATILE_REFCLK is 32KHz
-	 *	VERSATILE_TIMCLK is 1MHz
-	 */
-	val = readl(__io_address(VERSATILE_SCTL_BASE));
-	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
-	       __io_address(VERSATILE_SCTL_BASE));
 
 	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
index 2558f2e..3621b00 100644
--- a/arch/arm/mach-versatile/versatile_dt.c
+++ b/arch/arm/mach-versatile/versatile_dt.c
@@ -45,7 +45,6 @@ DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
 	.map_io		= versatile_map_io,
 	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
-	.init_time	= versatile_timer_init,
 	.init_machine	= versatile_dt_init,
 	.dt_compat	= versatile_dt_match,
 	.restart	= versatile_restart,
-- 
1.7.10.4


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

* [PATCH 08/11] ARM: versatile: use OF init for sp804 timer
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Enable DT based init for the sp804 timers on versatile DT platform.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/versatile-ab.dts     |   12 ++++++++++++
 arch/arm/mach-versatile/core.c         |   26 +++++++++++++-------------
 arch/arm/mach-versatile/versatile_dt.c |    1 -
 3 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index e2fe319..dde75ae 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -121,6 +121,18 @@
 			interrupts = <0>;
 		};
 
+		timer at 101e2000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x101e2000 0x1000>;
+			interrupts = <4>;
+		};
+
+		timer at 101e3000 {
+			compatible = "arm,sp804", "arm,primecell";
+			reg = <0x101e3000 0x1000>;
+			interrupts = <5>;
+		};
+
 		gpio0: gpio at 101e4000 {
 			compatible = "arm,pl061", "arm,primecell";
 			reg = <0x101e4000 0x1000>;
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 286303a..5cdfc87 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -748,12 +748,25 @@ void versatile_restart(char mode, const char *cmd)
 /* Early initializations */
 void __init versatile_init_early(void)
 {
+	u32 val;
 	void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
 
 	osc4_clk.vcoreg	= sys + VERSATILE_SYS_OSCCLCD_OFFSET;
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
 
 	versatile_sched_clock_init(sys + VERSATILE_SYS_24MHz_OFFSET, 24000000);
+
+	/*
+	 * set clock frequency:
+	 *	VERSATILE_REFCLK is 32KHz
+	 *	VERSATILE_TIMCLK is 1MHz
+	 */
+	val = readl(__io_address(VERSATILE_SCTL_BASE));
+	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
+	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
+	       __io_address(VERSATILE_SCTL_BASE));
 }
 
 void __init versatile_init(void)
@@ -784,19 +797,6 @@ void __init versatile_init(void)
  */
 void __init versatile_timer_init(void)
 {
-	u32 val;
-
-	/* 
-	 * set clock frequency: 
-	 *	VERSATILE_REFCLK is 32KHz
-	 *	VERSATILE_TIMCLK is 1MHz
-	 */
-	val = readl(__io_address(VERSATILE_SCTL_BASE));
-	writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) |
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) |
-	       (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val,
-	       __io_address(VERSATILE_SCTL_BASE));
 
 	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
diff --git a/arch/arm/mach-versatile/versatile_dt.c b/arch/arm/mach-versatile/versatile_dt.c
index 2558f2e..3621b00 100644
--- a/arch/arm/mach-versatile/versatile_dt.c
+++ b/arch/arm/mach-versatile/versatile_dt.c
@@ -45,7 +45,6 @@ DT_MACHINE_START(VERSATILE_PB, "ARM-Versatile (Device Tree Support)")
 	.map_io		= versatile_map_io,
 	.init_early	= versatile_init_early,
 	.init_irq	= versatile_init_irq,
-	.init_time	= versatile_timer_init,
 	.init_machine	= versatile_dt_init,
 	.dt_compat	= versatile_dt_match,
 	.restart	= versatile_restart,
-- 
1.7.10.4

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

* [PATCH 09/11] ARM: integrator-cp: convert use CLKSRC_OF for timer init
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Move the integrator-cp timer init to timer-sp.c and use CLKSRC_OF. There is
no reason to use the aliases, so drop them from the init code.

The integrator-cp timers are mistakenly called sp804 timers in the dts, but
in fact they are not sp804 dual timers, but single timers with the same
programming model. Fix the dts to reflect this.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/integratorcp.dts       |    6 +++---
 arch/arm/common/timer-sp.c               |   29 +++++++++++++++++++++++++++
 arch/arm/mach-integrator/integrator_cp.c |   32 ------------------------------
 3 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index 8b11939..ff1aea0 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -24,15 +24,15 @@
 	};
 
 	timer0: timer@13000000 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	timer1: timer@13000100 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	timer2: timer@13000200 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	pic: pic@14000000 {
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 3e86835..203a2b3 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -31,6 +31,7 @@
 
 #include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
 
 static long __init sp804_get_clock_rate(struct clk *clk)
 {
@@ -255,3 +256,31 @@ static void __init sp804_of_init(struct device_node *np)
 	initialized = true;
 }
 CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
+
+static void __init integrator_cp_of_init(struct device_node *np)
+{
+	static int init_count = 0;
+	void __iomem *base;
+	int irq;
+	const char *name = of_get_property(np, "compatible", NULL);
+
+	if (init_count == 2 || !of_device_is_available(np))
+		return;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	if (!init_count)
+		sp804_clocksource_init(base, name);
+	else {
+		irq = irq_of_parse_and_map(np, 0);
+		if (irq <= 0)
+			return;
+
+		sp804_clockevents_init(base, irq, name);
+	}
+
+	init_count++;
+}
+CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
\ No newline at end of file
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index c68e7d8..5729c3d 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -249,37 +249,6 @@ static void __init intcp_init_early(void)
 }
 
 #ifdef CONFIG_OF
-
-static void __init cp_of_timer_init(void)
-{
-	struct device_node *node;
-	const char *path;
-	void __iomem *base;
-	int err;
-	int irq;
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-primary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	sp804_clocksource_init(base, node->name);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-secondary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	irq = irq_of_parse_and_map(node, 0);
-	sp804_clockevents_init(base, irq, node->name);
-}
-
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
 	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 	{ /* Sentinel */ }
@@ -383,7 +352,6 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
 	.init_early	= intcp_init_early,
 	.init_irq	= intcp_init_irq_of,
 	.handle_irq	= fpga_handle_irq,
-	.init_time	= cp_of_timer_init,
 	.init_machine	= intcp_init_of,
 	.restart	= integrator_restart,
 	.dt_compat      = intcp_dt_board_compat,
-- 
1.7.10.4


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

* [PATCH 09/11] ARM: integrator-cp: convert use CLKSRC_OF for timer init
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Move the integrator-cp timer init to timer-sp.c and use CLKSRC_OF. There is
no reason to use the aliases, so drop them from the init code.

The integrator-cp timers are mistakenly called sp804 timers in the dts, but
in fact they are not sp804 dual timers, but single timers with the same
programming model. Fix the dts to reflect this.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 arch/arm/boot/dts/integratorcp.dts       |    6 +++---
 arch/arm/common/timer-sp.c               |   29 +++++++++++++++++++++++++++
 arch/arm/mach-integrator/integrator_cp.c |   32 ------------------------------
 3 files changed, 32 insertions(+), 35 deletions(-)

diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index 8b11939..ff1aea0 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -24,15 +24,15 @@
 	};
 
 	timer0: timer at 13000000 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	timer1: timer at 13000100 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	timer2: timer at 13000200 {
-		compatible = "arm,sp804", "arm,primecell";
+		compatible = "arm,integrator-cp-timer";
 	};
 
 	pic: pic at 14000000 {
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index 3e86835..203a2b3 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -31,6 +31,7 @@
 
 #include <asm/sched_clock.h>
 #include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
 
 static long __init sp804_get_clock_rate(struct clk *clk)
 {
@@ -255,3 +256,31 @@ static void __init sp804_of_init(struct device_node *np)
 	initialized = true;
 }
 CLOCKSOURCE_OF_DECLARE(sp804, "arm,sp804", sp804_of_init);
+
+static void __init integrator_cp_of_init(struct device_node *np)
+{
+	static int init_count = 0;
+	void __iomem *base;
+	int irq;
+	const char *name = of_get_property(np, "compatible", NULL);
+
+	if (init_count == 2 || !of_device_is_available(np))
+		return;
+
+	base = of_iomap(np, 0);
+	if (WARN_ON(!base))
+		return;
+
+	if (!init_count)
+		sp804_clocksource_init(base, name);
+	else {
+		irq = irq_of_parse_and_map(np, 0);
+		if (irq <= 0)
+			return;
+
+		sp804_clockevents_init(base, irq, name);
+	}
+
+	init_count++;
+}
+CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
\ No newline@end of file
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index c68e7d8..5729c3d 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -249,37 +249,6 @@ static void __init intcp_init_early(void)
 }
 
 #ifdef CONFIG_OF
-
-static void __init cp_of_timer_init(void)
-{
-	struct device_node *node;
-	const char *path;
-	void __iomem *base;
-	int err;
-	int irq;
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-primary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	sp804_clocksource_init(base, node->name);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-secondary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	irq = irq_of_parse_and_map(node, 0);
-	sp804_clockevents_init(base, irq, node->name);
-}
-
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
 	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 	{ /* Sentinel */ }
@@ -383,7 +352,6 @@ DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)")
 	.init_early	= intcp_init_early,
 	.init_irq	= intcp_init_irq_of,
 	.handle_irq	= fpga_handle_irq,
-	.init_time	= cp_of_timer_init,
 	.init_machine	= intcp_init_of,
 	.restart	= integrator_restart,
 	.dt_compat      = intcp_dt_board_compat,
-- 
1.7.10.4

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

* [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Rob Herring <rob.herring@calxeda.com>

Move timer-sp and integrator-ap timer code to drivers/clocksource and
update timer-sp.h and arm_timer.h includes.

This adds CLKSRC_OF support for the integrator-ap timer and removes the
use of "arm,timer-primary" and "arm,timer-secondary" aliases. The timer
selection should not be important as all 3 timers are equal capability.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/Kconfig                                   |    6 -
 arch/arm/common/Makefile                           |    1 -
 arch/arm/mach-integrator/Kconfig                   |    1 +
 arch/arm/mach-integrator/integrator_ap.c           |  169 +----------------
 arch/arm/mach-integrator/integrator_cp.c           |    3 +-
 arch/arm/mach-realview/core.c                      |    3 +-
 arch/arm/mach-versatile/core.c                     |    2 +-
 arch/arm/mach-vexpress/ct-ca9x4.c                  |    4 +-
 arch/arm/mach-vexpress/v2m.c                       |    3 +-
 drivers/clocksource/Kconfig                        |   12 ++
 drivers/clocksource/Makefile                       |    2 +
 .../hardware => drivers/clocksource}/arm_timer.h   |    6 +-
 drivers/clocksource/integrator_ap_timer.c          |  190 ++++++++++++++++++++
 .../arm/common => drivers/clocksource}/timer-sp.c  |    9 +-
 include/clocksource/integrator_ap_timer.h          |    7 +
 .../hardware => include/clocksource}/timer-sp.h    |    8 +
 16 files changed, 232 insertions(+), 194 deletions(-)
 rename {arch/arm/include/asm/hardware => drivers/clocksource}/arm_timer.h (89%)
 create mode 100644 drivers/clocksource/integrator_ap_timer.c
 rename {arch/arm/common => drivers/clocksource}/timer-sp.c (98%)
 create mode 100644 include/clocksource/integrator_ap_timer.h
 rename {arch/arm/include/asm/hardware => include/clocksource}/timer-sp.h (84%)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 774131a..46970d7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1169,12 +1169,6 @@ config PLAT_PXA
 config PLAT_VERSATILE
 	bool
 
-config ARM_TIMER_SP804
-	bool
-	select CLKSRC_MMIO
-	select CLKSRC_OF if OF
-	select HAVE_SCHED_CLOCK
-
 source arch/arm/mm/Kconfig
 
 config ARM_NR_BANKS
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index dc8dd0d..5a4cc1a 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -10,4 +10,3 @@ obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
-obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index abeff25..c5e4ff3 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -5,6 +5,7 @@ menu "Integrator Options"
 config ARCH_INTEGRATOR_AP
 	bool "Support Integrator/AP and Integrator/PP2 platforms"
 	select CLKSRC_MMIO
+	select INTEGRATOR_AP_TIMER
 	select MIGHT_HAVE_PCI
 	select SERIAL_AMBA_PL010
 	select SERIAL_AMBA_PL010_CONSOLE
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 4cb322d..6b5f540 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,8 +27,6 @@
 #include <linux/syscore_ops.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irqchip/versatile-fpga.h>
@@ -41,15 +39,14 @@
 #include <linux/stat.h>
 #include <linux/sys_soc.h>
 #include <linux/termios.h>
+#include <clocksource/integrator_ap_timer.h>
 #include <video/vga.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/mach-types.h>
-#include <asm/sched_clock.h>
 
 #include <mach/lm.h>
 #include <mach/irqs.h>
@@ -58,7 +55,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/pci.h>
-#include <asm/mach/time.h>
 
 #include "common.h"
 
@@ -296,174 +292,12 @@ struct amba_pl010_data ap_uart_data = {
 #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
 #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
 
-static unsigned long timer_reload;
-
-static u32 notrace integrator_read_sched_clock(void)
-{
-	return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
-}
-
-static void integrator_clocksource_init(unsigned long inrate,
-					void __iomem *base)
-{
-	u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
-	unsigned long rate = inrate;
-
-	if (rate >= 1500000) {
-		rate /= 16;
-		ctrl |= TIMER_CTRL_DIV16;
-	}
-
-	writel(0xffff, base + TIMER_LOAD);
-	writel(ctrl, base + TIMER_CTRL);
-
-	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
-			rate, 200, 16, clocksource_mmio_readl_down);
-	setup_sched_clock(integrator_read_sched_clock, 16, rate);
-}
-
-static void __iomem * clkevt_base;
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	/* clear the interrupt */
-	writel(1, clkevt_base + TIMER_INTCLR);
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
-{
-	u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
-
-	/* Disable timer */
-	writel(ctrl, clkevt_base + TIMER_CTRL);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		/* Enable the timer and start the periodic tick */
-		writel(timer_reload, clkevt_base + TIMER_LOAD);
-		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
-		writel(ctrl, clkevt_base + TIMER_CTRL);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* Leave the timer disabled, .set_next_event will enable it */
-		ctrl &= ~TIMER_CTRL_PERIODIC;
-		writel(ctrl, clkevt_base + TIMER_CTRL);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-	default:
-		/* Just leave in disabled state */
-		break;
-	}
-
-}
-
-static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
-{
-	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
-
-	writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
-	writel(next, clkevt_base + TIMER_LOAD);
-	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
-
-	return 0;
-}
-
-static struct clock_event_device integrator_clockevent = {
-	.name		= "timer1",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= clkevt_set_mode,
-	.set_next_event	= clkevt_set_next_event,
-	.rating		= 300,
-};
-
-static struct irqaction integrator_timer_irq = {
-	.name		= "timer",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= integrator_timer_interrupt,
-	.dev_id		= &integrator_clockevent,
-};
-
-static void integrator_clockevent_init(unsigned long inrate,
-				void __iomem *base, int irq)
-{
-	unsigned long rate = inrate;
-	unsigned int ctrl = 0;
-
-	clkevt_base = base;
-	/* Calculate and program a divisor */
-	if (rate > 0x100000 * HZ) {
-		rate /= 256;
-		ctrl |= TIMER_CTRL_DIV256;
-	} else if (rate > 0x10000 * HZ) {
-		rate /= 16;
-		ctrl |= TIMER_CTRL_DIV16;
-	}
-	timer_reload = rate / HZ;
-	writel(ctrl, clkevt_base + TIMER_CTRL);
-
-	setup_irq(irq, &integrator_timer_irq);
-	clockevents_config_and_register(&integrator_clockevent,
-					rate,
-					1,
-					0xffffU);
-}
-
 void __init ap_init_early(void)
 {
 }
 
 #ifdef CONFIG_OF
 
-static void __init ap_of_timer_init(void)
-{
-	struct device_node *node;
-	const char *path;
-	void __iomem *base;
-	int err;
-	int irq;
-	struct clk *clk;
-	unsigned long rate;
-
-	clk = clk_get_sys("ap_timer", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-	rate = clk_get_rate(clk);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-primary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	writel(0, base + TIMER_CTRL);
-	integrator_clocksource_init(rate, base);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-secondary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	irq = irq_of_parse_and_map(node, 0);
-	writel(0, base + TIMER_CTRL);
-	integrator_clockevent_init(rate, base, irq);
-}
-
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
 	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 	{ /* Sentinel */ }
@@ -582,7 +416,6 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
 	.init_early	= ap_init_early,
 	.init_irq	= ap_init_irq_of,
 	.handle_irq	= fpga_handle_irq,
-	.init_time	= ap_of_timer_init,
 	.init_machine	= ap_init_of,
 	.restart	= integrator_restart,
 	.dt_compat      = ap_dt_board_compat,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 5729c3d..b5c7a7b 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -28,6 +28,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/sys_soc.h>
+#include <clocksource/timer-sp.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
@@ -44,8 +45,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <asm/hardware/timer-sp.h>
-
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
 
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 8ce6366..2009f8f 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -31,6 +31,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/gfp.h>
 #include <linux/mtd/physmap.h>
+#include <clocksource/timer-sp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -41,10 +42,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 
-
 #include <mach/platform.h>
 #include <mach/irqs.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 5cdfc87..56ec027 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -38,6 +38,7 @@
 #include <linux/clkdev.h>
 #include <linux/mtd/physmap.h>
 #include <linux/bitops.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/irq.h>
 #include <asm/hardware/icst.h>
@@ -49,7 +50,6 @@
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 6f34497..8cce326 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -11,16 +11,14 @@
 #include <linux/clkdev.h>
 #include <linux/vexpress.h>
 #include <linux/irqchip/arm-gic.h>
+#include <clocksource/timer-sp.h>
 
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 
 #include <mach/ct-ca9x4.h>
 
-#include <asm/hardware/timer-sp.h>
-
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 09e571d..fb4cdc6 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -23,15 +23,14 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/vexpress.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/mach-types.h>
 #include <asm/sizes.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <mach/ct-ca9x4.h>
 #include <mach/motherboard.h>
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index d98e7e1..00aa4cd 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -25,6 +25,18 @@ config DW_APB_TIMER_OF
 config ARMADA_370_XP_TIMER
 	bool
 
+config ARM_TIMER_SP804
+	bool
+	depends on ARM
+	select CLKSRC_MMIO
+	select CLKSRC_OF if OF
+	select HAVE_SCHED_CLOCK
+
+config INTEGRATOR_AP_TIMER
+	bool
+	depends on ARM
+	select CLKSRC_OF if OF
+
 config SUNXI_TIMER
 	bool
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 4d8283a..9f3b62b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -14,8 +14,10 @@ obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
+obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
+obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= integrator_ap_timer.o
 obj-$(CONFIG_SUNXI_TIMER)	+= sunxi_timer.o
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra20_timer.o
 obj-$(CONFIG_VT8500_TIMER)	+= vt8500_timer.o
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/drivers/clocksource/arm_timer.h
similarity index 89%
rename from arch/arm/include/asm/hardware/arm_timer.h
rename to drivers/clocksource/arm_timer.h
index d6030ff..3d3f679 100644
--- a/arch/arm/include/asm/hardware/arm_timer.h
+++ b/drivers/clocksource/arm_timer.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
-#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+#ifndef __CLOCKSOURCE_ARM_TIMER_H
+#define __CLOCKSOURCE_ARM_TIMER_H
 
 /*
  * ARM timer implementation, found in Integrator, Versatile and Realview
@@ -12,8 +12,6 @@
  *
  * Every SP804 contains two identical timers.
  */
-#define TIMER_1_BASE	0x00
-#define TIMER_2_BASE	0x20
 
 #define TIMER_LOAD	0x00			/* ACVR rw */
 #define TIMER_VALUE	0x04			/* ACVR ro */
diff --git a/drivers/clocksource/integrator_ap_timer.c b/drivers/clocksource/integrator_ap_timer.c
new file mode 100644
index 0000000..75eb6c9
--- /dev/null
+++ b/drivers/clocksource/integrator_ap_timer.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2000-2003 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
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <asm/sched_clock.h>
+
+#include "arm_timer.h"
+
+static unsigned long timer_reload;
+static void __iomem *clksrc_base;
+
+static u32 notrace integrator_read_sched_clock(void)
+{
+	return -readl(clksrc_base + TIMER_VALUE);
+}
+
+void __init integrator_clocksource_init(unsigned long inrate,
+					void __iomem *base)
+{
+	u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+	unsigned long rate = inrate;
+
+	clksrc_base = base;
+	
+	if (rate >= 1500000) {
+		rate /= 16;
+		ctrl |= TIMER_CTRL_DIV16;
+	}
+
+	writel(0xffff, base + TIMER_LOAD);
+	writel(ctrl, base + TIMER_CTRL);
+
+	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
+			rate, 200, 16, clocksource_mmio_readl_down);
+	setup_sched_clock(integrator_read_sched_clock, 16, rate);
+}
+
+static void __iomem * clkevt_base;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	/* clear the interrupt */
+	writel(1, clkevt_base + TIMER_INTCLR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+	u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
+
+	/* Disable timer */
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* Enable the timer and start the periodic tick */
+		writel(timer_reload, clkevt_base + TIMER_LOAD);
+		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+		writel(ctrl, clkevt_base + TIMER_CTRL);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* Leave the timer disabled, .set_next_event will enable it */
+		ctrl &= ~TIMER_CTRL_PERIODIC;
+		writel(ctrl, clkevt_base + TIMER_CTRL);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+	default:
+		/* Just leave in disabled state */
+		break;
+	}
+
+}
+
+static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
+{
+	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+	writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+	writel(next, clkevt_base + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+	return 0;
+}
+
+static struct clock_event_device integrator_clockevent = {
+	.name		= "timer1",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= clkevt_set_mode,
+	.set_next_event	= clkevt_set_next_event,
+	.rating		= 300,
+};
+
+static struct irqaction integrator_timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= integrator_timer_interrupt,
+	.dev_id		= &integrator_clockevent,
+};
+
+void __init integrator_clockevent_init(unsigned long inrate,
+				       void __iomem *base, int irq)
+{
+	unsigned long rate = inrate;
+	unsigned int ctrl = 0;
+
+	clkevt_base = base;
+	/* Calculate and program a divisor */
+	if (rate > 0x100000 * HZ) {
+		rate /= 256;
+		ctrl |= TIMER_CTRL_DIV256;
+	} else if (rate > 0x10000 * HZ) {
+		rate /= 16;
+		ctrl |= TIMER_CTRL_DIV16;
+	}
+	timer_reload = rate / HZ;
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	setup_irq(irq, &integrator_timer_irq);
+	clockevents_config_and_register(&integrator_clockevent,
+					rate,
+					1,
+					0xffffU);
+}
+
+static void __init ap_of_timer_init(struct device_node *node)
+{
+	static int init_cnt = 0;
+	void __iomem *base;
+	int irq;
+	struct clk *clk;
+	unsigned long rate;
+
+	if ((init_cnt == 2) || !of_device_is_available(node))
+		return;
+
+	clk = clk_get_sys("ap_timer", NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+	rate = clk_get_rate(clk);
+
+	base = of_iomap(node, 0);
+	if (WARN_ON(!base))
+		return;
+
+	writel(0, base + TIMER_CTRL);
+
+	if (!init_cnt) {
+		irq = irq_of_parse_and_map(node, 0);
+		integrator_clockevent_init(rate, base, irq);
+	} else
+		integrator_clocksource_init(rate, base);
+
+	init_cnt++;
+}
+CLOCKSOURCE_OF_DECLARE(integrator_ap, "integrator-timer", ap_of_timer_init);
diff --git a/arch/arm/common/timer-sp.c b/drivers/clocksource/timer-sp.c
similarity index 98%
rename from arch/arm/common/timer-sp.c
rename to drivers/clocksource/timer-sp.c
index 203a2b3..91b12e3 100644
--- a/arch/arm/common/timer-sp.c
+++ b/drivers/clocksource/timer-sp.c
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/common/timer-sp.c
- *
  *  Copyright (C) 1999 - 2003 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
  *
@@ -28,10 +26,11 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/sched_clock.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/timer-sp.h>
+
+#include "arm_timer.h"
 
 static long __init sp804_get_clock_rate(struct clk *clk)
 {
@@ -283,4 +282,4 @@ static void __init integrator_cp_of_init(struct device_node *np)
 
 	init_count++;
 }
-CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
\ No newline at end of file
+CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
diff --git a/include/clocksource/integrator_ap_timer.h b/include/clocksource/integrator_ap_timer.h
new file mode 100644
index 0000000..2f585fc
--- /dev/null
+++ b/include/clocksource/integrator_ap_timer.h
@@ -0,0 +1,7 @@
+#ifndef __CLOCKSOURCE_INTEGRATOR_AP_TIMER
+#define __CLOCKSOURCE_INTEGRATOR_AP_TIMER
+
+void integrator_clocksource_init(unsigned long inrate, void __iomem *base);
+void integrator_clockevent_init(unsigned long inrate, void __iomem *base, int irq);
+
+#endif
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/include/clocksource/timer-sp.h
similarity index 84%
rename from arch/arm/include/asm/hardware/timer-sp.h
rename to include/clocksource/timer-sp.h
index bb28af7..f59dc9c 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/include/clocksource/timer-sp.h
@@ -1,3 +1,9 @@
+#ifndef __CLOCKSOURCE_TIMER_SP
+#define __CLOCKSOURCE_TIMER_SP
+
+#define TIMER_1_BASE	0x00
+#define TIMER_2_BASE	0x20
+
 struct clk;
 
 void __sp804_clocksource_and_sched_clock_init(void __iomem *,
@@ -21,3 +27,5 @@ static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq,
 	__sp804_clockevents_init(base, irq, NULL, name);
 
 }
+
+#endif
-- 
1.7.10.4


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

* [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <rob.herring@calxeda.com>

Move timer-sp and integrator-ap timer code to drivers/clocksource and
update timer-sp.h and arm_timer.h includes.

This adds CLKSRC_OF support for the integrator-ap timer and removes the
use of "arm,timer-primary" and "arm,timer-secondary" aliases. The timer
selection should not be important as all 3 timers are equal capability.

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
 arch/arm/Kconfig                                   |    6 -
 arch/arm/common/Makefile                           |    1 -
 arch/arm/mach-integrator/Kconfig                   |    1 +
 arch/arm/mach-integrator/integrator_ap.c           |  169 +----------------
 arch/arm/mach-integrator/integrator_cp.c           |    3 +-
 arch/arm/mach-realview/core.c                      |    3 +-
 arch/arm/mach-versatile/core.c                     |    2 +-
 arch/arm/mach-vexpress/ct-ca9x4.c                  |    4 +-
 arch/arm/mach-vexpress/v2m.c                       |    3 +-
 drivers/clocksource/Kconfig                        |   12 ++
 drivers/clocksource/Makefile                       |    2 +
 .../hardware => drivers/clocksource}/arm_timer.h   |    6 +-
 drivers/clocksource/integrator_ap_timer.c          |  190 ++++++++++++++++++++
 .../arm/common => drivers/clocksource}/timer-sp.c  |    9 +-
 include/clocksource/integrator_ap_timer.h          |    7 +
 .../hardware => include/clocksource}/timer-sp.h    |    8 +
 16 files changed, 232 insertions(+), 194 deletions(-)
 rename {arch/arm/include/asm/hardware => drivers/clocksource}/arm_timer.h (89%)
 create mode 100644 drivers/clocksource/integrator_ap_timer.c
 rename {arch/arm/common => drivers/clocksource}/timer-sp.c (98%)
 create mode 100644 include/clocksource/integrator_ap_timer.h
 rename {arch/arm/include/asm/hardware => include/clocksource}/timer-sp.h (84%)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 774131a..46970d7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1169,12 +1169,6 @@ config PLAT_PXA
 config PLAT_VERSATILE
 	bool
 
-config ARM_TIMER_SP804
-	bool
-	select CLKSRC_MMIO
-	select CLKSRC_OF if OF
-	select HAVE_SCHED_CLOCK
-
 source arch/arm/mm/Kconfig
 
 config ARM_NR_BANKS
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index dc8dd0d..5a4cc1a 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -10,4 +10,3 @@ obj-$(CONFIG_SHARP_LOCOMO)	+= locomo.o
 obj-$(CONFIG_SHARP_PARAM)	+= sharpsl_param.o
 obj-$(CONFIG_SHARP_SCOOP)	+= scoop.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
-obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig
index abeff25..c5e4ff3 100644
--- a/arch/arm/mach-integrator/Kconfig
+++ b/arch/arm/mach-integrator/Kconfig
@@ -5,6 +5,7 @@ menu "Integrator Options"
 config ARCH_INTEGRATOR_AP
 	bool "Support Integrator/AP and Integrator/PP2 platforms"
 	select CLKSRC_MMIO
+	select INTEGRATOR_AP_TIMER
 	select MIGHT_HAVE_PCI
 	select SERIAL_AMBA_PL010
 	select SERIAL_AMBA_PL010_CONSOLE
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 4cb322d..6b5f540 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -27,8 +27,6 @@
 #include <linux/syscore_ops.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irqchip/versatile-fpga.h>
@@ -41,15 +39,14 @@
 #include <linux/stat.h>
 #include <linux/sys_soc.h>
 #include <linux/termios.h>
+#include <clocksource/integrator_ap_timer.h>
 #include <video/vga.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/setup.h>
 #include <asm/param.h>		/* HZ */
 #include <asm/mach-types.h>
-#include <asm/sched_clock.h>
 
 #include <mach/lm.h>
 #include <mach/irqs.h>
@@ -58,7 +55,6 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/pci.h>
-#include <asm/mach/time.h>
 
 #include "common.h"
 
@@ -296,174 +292,12 @@ struct amba_pl010_data ap_uart_data = {
 #define TIMER1_VA_BASE __io_address(INTEGRATOR_TIMER1_BASE)
 #define TIMER2_VA_BASE __io_address(INTEGRATOR_TIMER2_BASE)
 
-static unsigned long timer_reload;
-
-static u32 notrace integrator_read_sched_clock(void)
-{
-	return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
-}
-
-static void integrator_clocksource_init(unsigned long inrate,
-					void __iomem *base)
-{
-	u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
-	unsigned long rate = inrate;
-
-	if (rate >= 1500000) {
-		rate /= 16;
-		ctrl |= TIMER_CTRL_DIV16;
-	}
-
-	writel(0xffff, base + TIMER_LOAD);
-	writel(ctrl, base + TIMER_CTRL);
-
-	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
-			rate, 200, 16, clocksource_mmio_readl_down);
-	setup_sched_clock(integrator_read_sched_clock, 16, rate);
-}
-
-static void __iomem * clkevt_base;
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	/* clear the interrupt */
-	writel(1, clkevt_base + TIMER_INTCLR);
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
-{
-	u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
-
-	/* Disable timer */
-	writel(ctrl, clkevt_base + TIMER_CTRL);
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		/* Enable the timer and start the periodic tick */
-		writel(timer_reload, clkevt_base + TIMER_LOAD);
-		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
-		writel(ctrl, clkevt_base + TIMER_CTRL);
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* Leave the timer disabled, .set_next_event will enable it */
-		ctrl &= ~TIMER_CTRL_PERIODIC;
-		writel(ctrl, clkevt_base + TIMER_CTRL);
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-	default:
-		/* Just leave in disabled state */
-		break;
-	}
-
-}
-
-static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
-{
-	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
-
-	writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
-	writel(next, clkevt_base + TIMER_LOAD);
-	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
-
-	return 0;
-}
-
-static struct clock_event_device integrator_clockevent = {
-	.name		= "timer1",
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= clkevt_set_mode,
-	.set_next_event	= clkevt_set_next_event,
-	.rating		= 300,
-};
-
-static struct irqaction integrator_timer_irq = {
-	.name		= "timer",
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= integrator_timer_interrupt,
-	.dev_id		= &integrator_clockevent,
-};
-
-static void integrator_clockevent_init(unsigned long inrate,
-				void __iomem *base, int irq)
-{
-	unsigned long rate = inrate;
-	unsigned int ctrl = 0;
-
-	clkevt_base = base;
-	/* Calculate and program a divisor */
-	if (rate > 0x100000 * HZ) {
-		rate /= 256;
-		ctrl |= TIMER_CTRL_DIV256;
-	} else if (rate > 0x10000 * HZ) {
-		rate /= 16;
-		ctrl |= TIMER_CTRL_DIV16;
-	}
-	timer_reload = rate / HZ;
-	writel(ctrl, clkevt_base + TIMER_CTRL);
-
-	setup_irq(irq, &integrator_timer_irq);
-	clockevents_config_and_register(&integrator_clockevent,
-					rate,
-					1,
-					0xffffU);
-}
-
 void __init ap_init_early(void)
 {
 }
 
 #ifdef CONFIG_OF
 
-static void __init ap_of_timer_init(void)
-{
-	struct device_node *node;
-	const char *path;
-	void __iomem *base;
-	int err;
-	int irq;
-	struct clk *clk;
-	unsigned long rate;
-
-	clk = clk_get_sys("ap_timer", NULL);
-	BUG_ON(IS_ERR(clk));
-	clk_prepare_enable(clk);
-	rate = clk_get_rate(clk);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-primary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	writel(0, base + TIMER_CTRL);
-	integrator_clocksource_init(rate, base);
-
-	err = of_property_read_string(of_aliases,
-				"arm,timer-secondary", &path);
-	if (WARN_ON(err))
-		return;
-	node = of_find_node_by_path(path);
-	base = of_iomap(node, 0);
-	if (WARN_ON(!base))
-		return;
-	irq = irq_of_parse_and_map(node, 0);
-	writel(0, base + TIMER_CTRL);
-	integrator_clockevent_init(rate, base, irq);
-}
-
 static const struct of_device_id fpga_irq_of_match[] __initconst = {
 	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, },
 	{ /* Sentinel */ }
@@ -582,7 +416,6 @@ DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)")
 	.init_early	= ap_init_early,
 	.init_irq	= ap_init_irq_of,
 	.handle_irq	= fpga_handle_irq,
-	.init_time	= ap_of_timer_init,
 	.init_machine	= ap_init_of,
 	.restart	= integrator_restart,
 	.dt_compat      = ap_dt_board_compat,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index 5729c3d..b5c7a7b 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -28,6 +28,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/sys_soc.h>
+#include <clocksource/timer-sp.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
@@ -44,8 +45,6 @@
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
-#include <asm/hardware/timer-sp.h>
-
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
 
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 8ce6366..2009f8f 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -31,6 +31,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/gfp.h>
 #include <linux/mtd/physmap.h>
+#include <clocksource/timer-sp.h>
 
 #include <mach/hardware.h>
 #include <asm/irq.h>
@@ -41,10 +42,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 
-
 #include <mach/platform.h>
 #include <mach/irqs.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 5cdfc87..56ec027 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -38,6 +38,7 @@
 #include <linux/clkdev.h>
 #include <linux/mtd/physmap.h>
 #include <linux/bitops.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/irq.h>
 #include <asm/hardware/icst.h>
@@ -49,7 +50,6 @@
 #include <asm/mach/map.h>
 #include <mach/hardware.h>
 #include <mach/platform.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <plat/clcd.h>
 #include <plat/sched_clock.h>
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 6f34497..8cce326 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -11,16 +11,14 @@
 #include <linux/clkdev.h>
 #include <linux/vexpress.h>
 #include <linux/irqchip/arm-gic.h>
+#include <clocksource/timer-sp.h>
 
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
 
 #include <mach/ct-ca9x4.h>
 
-#include <asm/hardware/timer-sp.h>
-
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 09e571d..fb4cdc6 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -23,15 +23,14 @@
 #include <linux/regulator/fixed.h>
 #include <linux/regulator/machine.h>
 #include <linux/vexpress.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/mach-types.h>
 #include <asm/sizes.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <asm/hardware/arm_timer.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/hardware/timer-sp.h>
 
 #include <mach/ct-ca9x4.h>
 #include <mach/motherboard.h>
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index d98e7e1..00aa4cd 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -25,6 +25,18 @@ config DW_APB_TIMER_OF
 config ARMADA_370_XP_TIMER
 	bool
 
+config ARM_TIMER_SP804
+	bool
+	depends on ARM
+	select CLKSRC_MMIO
+	select CLKSRC_OF if OF
+	select HAVE_SCHED_CLOCK
+
+config INTEGRATOR_AP_TIMER
+	bool
+	depends on ARM
+	select CLKSRC_OF if OF
+
 config SUNXI_TIMER
 	bool
 
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 4d8283a..9f3b62b 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -14,8 +14,10 @@ obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
+obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)	+= time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)	+= bcm2835_timer.o
+obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= integrator_ap_timer.o
 obj-$(CONFIG_SUNXI_TIMER)	+= sunxi_timer.o
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra20_timer.o
 obj-$(CONFIG_VT8500_TIMER)	+= vt8500_timer.o
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/drivers/clocksource/arm_timer.h
similarity index 89%
rename from arch/arm/include/asm/hardware/arm_timer.h
rename to drivers/clocksource/arm_timer.h
index d6030ff..3d3f679 100644
--- a/arch/arm/include/asm/hardware/arm_timer.h
+++ b/drivers/clocksource/arm_timer.h
@@ -1,5 +1,5 @@
-#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
-#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+#ifndef __CLOCKSOURCE_ARM_TIMER_H
+#define __CLOCKSOURCE_ARM_TIMER_H
 
 /*
  * ARM timer implementation, found in Integrator, Versatile and Realview
@@ -12,8 +12,6 @@
  *
  * Every SP804 contains two identical timers.
  */
-#define TIMER_1_BASE	0x00
-#define TIMER_2_BASE	0x20
 
 #define TIMER_LOAD	0x00			/* ACVR rw */
 #define TIMER_VALUE	0x04			/* ACVR ro */
diff --git a/drivers/clocksource/integrator_ap_timer.c b/drivers/clocksource/integrator_ap_timer.c
new file mode 100644
index 0000000..75eb6c9
--- /dev/null
+++ b/drivers/clocksource/integrator_ap_timer.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2000-2003 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
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include <asm/sched_clock.h>
+
+#include "arm_timer.h"
+
+static unsigned long timer_reload;
+static void __iomem *clksrc_base;
+
+static u32 notrace integrator_read_sched_clock(void)
+{
+	return -readl(clksrc_base + TIMER_VALUE);
+}
+
+void __init integrator_clocksource_init(unsigned long inrate,
+					void __iomem *base)
+{
+	u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;
+	unsigned long rate = inrate;
+
+	clksrc_base = base;
+	
+	if (rate >= 1500000) {
+		rate /= 16;
+		ctrl |= TIMER_CTRL_DIV16;
+	}
+
+	writel(0xffff, base + TIMER_LOAD);
+	writel(ctrl, base + TIMER_CTRL);
+
+	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
+			rate, 200, 16, clocksource_mmio_readl_down);
+	setup_sched_clock(integrator_read_sched_clock, 16, rate);
+}
+
+static void __iomem * clkevt_base;
+
+/*
+ * IRQ handler for the timer
+ */
+static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	/* clear the interrupt */
+	writel(1, clkevt_base + TIMER_INTCLR);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt)
+{
+	u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
+
+	/* Disable timer */
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		/* Enable the timer and start the periodic tick */
+		writel(timer_reload, clkevt_base + TIMER_LOAD);
+		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
+		writel(ctrl, clkevt_base + TIMER_CTRL);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		/* Leave the timer disabled, .set_next_event will enable it */
+		ctrl &= ~TIMER_CTRL_PERIODIC;
+		writel(ctrl, clkevt_base + TIMER_CTRL);
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_RESUME:
+	default:
+		/* Just leave in disabled state */
+		break;
+	}
+
+}
+
+static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
+{
+	unsigned long ctrl = readl(clkevt_base + TIMER_CTRL);
+
+	writel(ctrl & ~TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+	writel(next, clkevt_base + TIMER_LOAD);
+	writel(ctrl | TIMER_CTRL_ENABLE, clkevt_base + TIMER_CTRL);
+
+	return 0;
+}
+
+static struct clock_event_device integrator_clockevent = {
+	.name		= "timer1",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.set_mode	= clkevt_set_mode,
+	.set_next_event	= clkevt_set_next_event,
+	.rating		= 300,
+};
+
+static struct irqaction integrator_timer_irq = {
+	.name		= "timer",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= integrator_timer_interrupt,
+	.dev_id		= &integrator_clockevent,
+};
+
+void __init integrator_clockevent_init(unsigned long inrate,
+				       void __iomem *base, int irq)
+{
+	unsigned long rate = inrate;
+	unsigned int ctrl = 0;
+
+	clkevt_base = base;
+	/* Calculate and program a divisor */
+	if (rate > 0x100000 * HZ) {
+		rate /= 256;
+		ctrl |= TIMER_CTRL_DIV256;
+	} else if (rate > 0x10000 * HZ) {
+		rate /= 16;
+		ctrl |= TIMER_CTRL_DIV16;
+	}
+	timer_reload = rate / HZ;
+	writel(ctrl, clkevt_base + TIMER_CTRL);
+
+	setup_irq(irq, &integrator_timer_irq);
+	clockevents_config_and_register(&integrator_clockevent,
+					rate,
+					1,
+					0xffffU);
+}
+
+static void __init ap_of_timer_init(struct device_node *node)
+{
+	static int init_cnt = 0;
+	void __iomem *base;
+	int irq;
+	struct clk *clk;
+	unsigned long rate;
+
+	if ((init_cnt == 2) || !of_device_is_available(node))
+		return;
+
+	clk = clk_get_sys("ap_timer", NULL);
+	BUG_ON(IS_ERR(clk));
+	clk_prepare_enable(clk);
+	rate = clk_get_rate(clk);
+
+	base = of_iomap(node, 0);
+	if (WARN_ON(!base))
+		return;
+
+	writel(0, base + TIMER_CTRL);
+
+	if (!init_cnt) {
+		irq = irq_of_parse_and_map(node, 0);
+		integrator_clockevent_init(rate, base, irq);
+	} else
+		integrator_clocksource_init(rate, base);
+
+	init_cnt++;
+}
+CLOCKSOURCE_OF_DECLARE(integrator_ap, "integrator-timer", ap_of_timer_init);
diff --git a/arch/arm/common/timer-sp.c b/drivers/clocksource/timer-sp.c
similarity index 98%
rename from arch/arm/common/timer-sp.c
rename to drivers/clocksource/timer-sp.c
index 203a2b3..91b12e3 100644
--- a/arch/arm/common/timer-sp.c
+++ b/drivers/clocksource/timer-sp.c
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/arm/common/timer-sp.c
- *
  *  Copyright (C) 1999 - 2003 ARM Limited
  *  Copyright (C) 2000 Deep Blue Solutions Ltd
  *
@@ -28,10 +26,11 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <clocksource/timer-sp.h>
 
 #include <asm/sched_clock.h>
-#include <asm/hardware/arm_timer.h>
-#include <asm/hardware/timer-sp.h>
+
+#include "arm_timer.h"
 
 static long __init sp804_get_clock_rate(struct clk *clk)
 {
@@ -283,4 +282,4 @@ static void __init integrator_cp_of_init(struct device_node *np)
 
 	init_count++;
 }
-CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
\ No newline at end of file
+CLOCKSOURCE_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);
diff --git a/include/clocksource/integrator_ap_timer.h b/include/clocksource/integrator_ap_timer.h
new file mode 100644
index 0000000..2f585fc
--- /dev/null
+++ b/include/clocksource/integrator_ap_timer.h
@@ -0,0 +1,7 @@
+#ifndef __CLOCKSOURCE_INTEGRATOR_AP_TIMER
+#define __CLOCKSOURCE_INTEGRATOR_AP_TIMER
+
+void integrator_clocksource_init(unsigned long inrate, void __iomem *base);
+void integrator_clockevent_init(unsigned long inrate, void __iomem *base, int irq);
+
+#endif
diff --git a/arch/arm/include/asm/hardware/timer-sp.h b/include/clocksource/timer-sp.h
similarity index 84%
rename from arch/arm/include/asm/hardware/timer-sp.h
rename to include/clocksource/timer-sp.h
index bb28af7..f59dc9c 100644
--- a/arch/arm/include/asm/hardware/timer-sp.h
+++ b/include/clocksource/timer-sp.h
@@ -1,3 +1,9 @@
+#ifndef __CLOCKSOURCE_TIMER_SP
+#define __CLOCKSOURCE_TIMER_SP
+
+#define TIMER_1_BASE	0x00
+#define TIMER_2_BASE	0x20
+
 struct clk;
 
 void __sp804_clocksource_and_sched_clock_init(void __iomem *,
@@ -21,3 +27,5 @@ static inline void sp804_clockevents_init(void __iomem *base, unsigned int irq,
 	__sp804_clockevents_init(base, irq, NULL, name);
 
 }
+
+#endif
-- 
1.7.10.4

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

* [PATCH 11/11] devtree: add binding documentation for sp804
  2013-03-20 22:54 ` Rob Herring
@ 2013-03-20 22:54   ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel, linux-kernel, devicetree-discuss
  Cc: Arnd Bergmann, linus.walleij, Russell King, haojian.zhuang,
	pawel.moll, john.stultz, tglx, Rob Herring

From: Haojian Zhuang <haojian.zhuang@linaro.org>

The sp804 binding is already in use by several platforms. This adds missing
documentation for the binding and also extends the binding to handle some
additional possible interrupt configurations.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 .../devicetree/bindings/timer/arm,sp804.txt        |   29 ++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/arm,sp804.txt

diff --git a/Documentation/devicetree/bindings/timer/arm,sp804.txt b/Documentation/devicetree/bindings/timer/arm,sp804.txt
new file mode 100644
index 0000000..5cd8eee
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/arm,sp804.txt
@@ -0,0 +1,29 @@
+ARM sp804 Dual Timers
+---------------------------------------
+
+Required properties:
+- compatible: Should be "arm,sp804" & "arm,primecell"
+- interrupts: Should contain the list of Dual Timer interrupts. This is the
+	interrupt for timer 1 and timer 2. In the case of a single entry, it is
+	the combined interrupt or if "arm,sp804-has-irq" is present that
+	specifies which timer interrupt is connected.
+- reg: Should contain location and length for dual timer register.
+- clocks: clocks driving the dual timer hardware. This list should be 1 or 3
+	clocks.	With 3 clocks, the order is timer0 clock, timer1 clock,
+	apb_pclk. A single clock can also be specified if the same clock is
+	used for all clock inputs.
+
+Optional properties:
+- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this
+	specifies if the irq connection is for timer 1 or timer 2. A value of 1
+	or 2 should be used.
+
+Example:
+
+	timer0: timer@fc800000 {
+		compatible = "arm,sp804", "arm,primecell";
+		reg = <0xfc800000 0x1000>;
+		interrupts = <0 0 4>, <0 1 4>;
+		clocks = <&timclk1 &timclk2 &pclk>;
+		clock-names = "timer1", "timer2", "apb_pclk";
+	};
-- 
1.7.10.4


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

* [PATCH 11/11] devtree: add binding documentation for sp804
@ 2013-03-20 22:54   ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-20 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

From: Haojian Zhuang <haojian.zhuang@linaro.org>

The sp804 binding is already in use by several platforms. This adds missing
documentation for the binding and also extends the binding to handle some
additional possible interrupt configurations.

Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
 .../devicetree/bindings/timer/arm,sp804.txt        |   29 ++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/arm,sp804.txt

diff --git a/Documentation/devicetree/bindings/timer/arm,sp804.txt b/Documentation/devicetree/bindings/timer/arm,sp804.txt
new file mode 100644
index 0000000..5cd8eee
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/arm,sp804.txt
@@ -0,0 +1,29 @@
+ARM sp804 Dual Timers
+---------------------------------------
+
+Required properties:
+- compatible: Should be "arm,sp804" & "arm,primecell"
+- interrupts: Should contain the list of Dual Timer interrupts. This is the
+	interrupt for timer 1 and timer 2. In the case of a single entry, it is
+	the combined interrupt or if "arm,sp804-has-irq" is present that
+	specifies which timer interrupt is connected.
+- reg: Should contain location and length for dual timer register.
+- clocks: clocks driving the dual timer hardware. This list should be 1 or 3
+	clocks.	With 3 clocks, the order is timer0 clock, timer1 clock,
+	apb_pclk. A single clock can also be specified if the same clock is
+	used for all clock inputs.
+
+Optional properties:
+- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this
+	specifies if the irq connection is for timer 1 or timer 2. A value of 1
+	or 2 should be used.
+
+Example:
+
+	timer0: timer at fc800000 {
+		compatible = "arm,sp804", "arm,primecell";
+		reg = <0xfc800000 0x1000>;
+		interrupts = <0 0 4>, <0 1 4>;
+		clocks = <&timclk1 &timclk2 &pclk>;
+		clock-names = "timer1", "timer2", "apb_pclk";
+	};
-- 
1.7.10.4

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

* Re: [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-21 13:24   ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2013-03-21 13:24 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	linus.walleij, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wednesday 20 March 2013, Rob Herring wrote:
> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
> sched_clock selection series[1], and Arnd's default machine descriptor
> patch (for default clocksource_of_init call). The full series is
> available here:

All your patches look good to me, but I'd suggest you don't depend on
my default machine descriptor patch yet, that just makes the dependencies
harder to track, and we can easily remove all the calls once they
are obsoletely.

	Arnd

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

* Re: [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-21 13:24   ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2013-03-21 13:24 UTC (permalink / raw)
  To: Rob Herring
  Cc: Russell King, pawel.moll-5wv7dgnIgG8,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wednesday 20 March 2013, Rob Herring wrote:
> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
> sched_clock selection series[1], and Arnd's default machine descriptor
> patch (for default clocksource_of_init call). The full series is
> available here:

All your patches look good to me, but I'd suggest you don't depend on
my default machine descriptor patch yet, that just makes the dependencies
harder to track, and we can easily remove all the calls once they
are obsoletely.

	Arnd

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

* [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-21 13:24   ` Arnd Bergmann
  0 siblings, 0 replies; 67+ messages in thread
From: Arnd Bergmann @ 2013-03-21 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 20 March 2013, Rob Herring wrote:
> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
> sched_clock selection series[1], and Arnd's default machine descriptor
> patch (for default clocksource_of_init call). The full series is
> available here:

All your patches look good to me, but I'd suggest you don't depend on
my default machine descriptor patch yet, that just makes the dependencies
harder to track, and we can easily remove all the calls once they
are obsoletely.

	Arnd

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

* Re: [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
  2013-03-21 13:24   ` Arnd Bergmann
  (?)
@ 2013-03-21 14:06     ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	linus.walleij, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On 03/21/2013 08:24 AM, Arnd Bergmann wrote:
> On Wednesday 20 March 2013, Rob Herring wrote:
>> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
>> sched_clock selection series[1], and Arnd's default machine descriptor
>> patch (for default clocksource_of_init call). The full series is
>> available here:
> 
> All your patches look good to me, but I'd suggest you don't depend on
> my default machine descriptor patch yet, that just makes the dependencies
> harder to track, and we can easily remove all the calls once they
> are obsoletely.
> 

I really only need the hunk that calls clocksource_of_init which is
really somewhat unrelated to a default machine desc. So what if I just
pull out this hunk to a separate patch:

diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 955d92d..abff4e9 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/profile.h>
 #include <linux/timer.h>
+#include <linux/clocksource.h>
 #include <linux/irq.h>

 #include <asm/thread_info.h>
@@ -115,6 +116,10 @@ int __init
register_persistent_clock(clock_access_fn read_boot,

 void __init time_init(void)
 {
-	machine_desc->init_time();
+	if (machine_desc->init_time)
+		machine_desc->init_time();
+	else
+		clocksource_of_init();
+
 	sched_clock_postinit();
 }


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

* Re: [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-21 14:06     ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:06 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	linus.walleij, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On 03/21/2013 08:24 AM, Arnd Bergmann wrote:
> On Wednesday 20 March 2013, Rob Herring wrote:
>> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
>> sched_clock selection series[1], and Arnd's default machine descriptor
>> patch (for default clocksource_of_init call). The full series is
>> available here:
> 
> All your patches look good to me, but I'd suggest you don't depend on
> my default machine descriptor patch yet, that just makes the dependencies
> harder to track, and we can easily remove all the calls once they
> are obsoletely.
> 

I really only need the hunk that calls clocksource_of_init which is
really somewhat unrelated to a default machine desc. So what if I just
pull out this hunk to a separate patch:

diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 955d92d..abff4e9 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/profile.h>
 #include <linux/timer.h>
+#include <linux/clocksource.h>
 #include <linux/irq.h>

 #include <asm/thread_info.h>
@@ -115,6 +116,10 @@ int __init
register_persistent_clock(clock_access_fn read_boot,

 void __init time_init(void)
 {
-	machine_desc->init_time();
+	if (machine_desc->init_time)
+		machine_desc->init_time();
+	else
+		clocksource_of_init();
+
 	sched_clock_postinit();
 }

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

* [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support
@ 2013-03-21 14:06     ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/21/2013 08:24 AM, Arnd Bergmann wrote:
> On Wednesday 20 March 2013, Rob Herring wrote:
>> This series is dependent on my CLKSRC_OF clean-up in arm-soc, my
>> sched_clock selection series[1], and Arnd's default machine descriptor
>> patch (for default clocksource_of_init call). The full series is
>> available here:
> 
> All your patches look good to me, but I'd suggest you don't depend on
> my default machine descriptor patch yet, that just makes the dependencies
> harder to track, and we can easily remove all the calls once they
> are obsoletely.
> 

I really only need the hunk that calls clocksource_of_init which is
really somewhat unrelated to a default machine desc. So what if I just
pull out this hunk to a separate patch:

diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 955d92d..abff4e9 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/errno.h>
 #include <linux/profile.h>
 #include <linux/timer.h>
+#include <linux/clocksource.h>
 #include <linux/irq.h>

 #include <asm/thread_info.h>
@@ -115,6 +116,10 @@ int __init
register_persistent_clock(clock_access_fn read_boot,

 void __init time_init(void)
 {
-	machine_desc->init_time();
+	if (machine_desc->init_time)
+		machine_desc->init_time();
+	else
+		clocksource_of_init();
+
 	sched_clock_postinit();
 }

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

* Re: [PATCH 01/11] OF: add empty of_device_is_available for !OF
  2013-03-20 22:54   ` Rob Herring
  (?)
@ 2013-03-21 14:18     ` Mark Rutland
  -1 siblings, 0 replies; 67+ messages in thread
From: Mark Rutland @ 2013-03-21 14:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss, Russell King,
	Pawel Moll, rob.herring, john.stultz, haojian.zhuang, tglx

On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Add an empty version of of_device_is_available.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---
>  include/linux/of.h |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index a0f1292..6fe655b 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>  	return 0;
>  }
>  
> +static inline int of_device_is_available(const struct device_node *device,)

I assume that comma shouldn't be there?                                     ^

Mark.

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

* Re: [PATCH 01/11] OF: add empty of_device_is_available for !OF
@ 2013-03-21 14:18     ` Mark Rutland
  0 siblings, 0 replies; 67+ messages in thread
From: Mark Rutland @ 2013-03-21 14:18 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss, Russell King,
	Pawel Moll, rob.herring, john.stultz, haojian.zhuang, tglx

On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Add an empty version of of_device_is_available.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---
>  include/linux/of.h |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index a0f1292..6fe655b 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>  	return 0;
>  }
>  
> +static inline int of_device_is_available(const struct device_node *device,)

I assume that comma shouldn't be there?                                     ^

Mark.

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

* [PATCH 01/11] OF: add empty of_device_is_available for !OF
@ 2013-03-21 14:18     ` Mark Rutland
  0 siblings, 0 replies; 67+ messages in thread
From: Mark Rutland @ 2013-03-21 14:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> Add an empty version of of_device_is_available.
> 
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> ---
>  include/linux/of.h |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/linux/of.h b/include/linux/of.h
> index a0f1292..6fe655b 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>  	return 0;
>  }
>  
> +static inline int of_device_is_available(const struct device_node *device,)

I assume that comma shouldn't be there?                                     ^

Mark.

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

* Re: [PATCH 01/11] OF: add empty of_device_is_available for !OF
  2013-03-21 14:18     ` Mark Rutland
  (?)
@ 2013-03-21 14:26       ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:26 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss, Russell King,
	Pawel Moll, rob.herring, john.stultz, haojian.zhuang, tglx

On 03/21/2013 09:18 AM, Mark Rutland wrote:
> On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Add an empty version of of_device_is_available.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> ---
>>  include/linux/of.h |    5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/include/linux/of.h b/include/linux/of.h
>> index a0f1292..6fe655b 100644
>> --- a/include/linux/of.h
>> +++ b/include/linux/of.h
>> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>>  	return 0;
>>  }
>>  
>> +static inline int of_device_is_available(const struct device_node *device,)
> 
> I assume that comma shouldn't be there?                                     ^

Right. I've fixed that up in my git tree.

Rob


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

* Re: [PATCH 01/11] OF: add empty of_device_is_available for !OF
@ 2013-03-21 14:26       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:26 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss, Russell King,
	Pawel Moll, rob.herring, john.stultz, haojian.zhuang, tglx

On 03/21/2013 09:18 AM, Mark Rutland wrote:
> On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Add an empty version of of_device_is_available.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> ---
>>  include/linux/of.h |    5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/include/linux/of.h b/include/linux/of.h
>> index a0f1292..6fe655b 100644
>> --- a/include/linux/of.h
>> +++ b/include/linux/of.h
>> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>>  	return 0;
>>  }
>>  
>> +static inline int of_device_is_available(const struct device_node *device,)
> 
> I assume that comma shouldn't be there?                                     ^

Right. I've fixed that up in my git tree.

Rob

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

* [PATCH 01/11] OF: add empty of_device_is_available for !OF
@ 2013-03-21 14:26       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 14:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/21/2013 09:18 AM, Mark Rutland wrote:
> On Wed, Mar 20, 2013 at 10:54:01PM +0000, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Add an empty version of of_device_is_available.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> ---
>>  include/linux/of.h |    5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/include/linux/of.h b/include/linux/of.h
>> index a0f1292..6fe655b 100644
>> --- a/include/linux/of.h
>> +++ b/include/linux/of.h
>> @@ -379,6 +379,11 @@ static inline int of_device_is_compatible(const struct device_node *device,
>>  	return 0;
>>  }
>>  
>> +static inline int of_device_is_available(const struct device_node *device,)
> 
> I assume that comma shouldn't be there?                                     ^

Right. I've fixed that up in my git tree.

Rob

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

* Re: [PATCH 02/11] ARM: remove extra timer-sp control register clearing
  2013-03-20 22:54   ` Rob Herring
@ 2013-03-21 17:58     ` Linus Walleij
  -1 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 17:58 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> The timer-sp initialization code clears the control register before
> initializing the timers, so every platform doing this is redundant.
>
> For unused timers, we should not care what state they are in.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
(...)
> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
> index ea96144..4cb322d 100644
> --- a/arch/arm/mach-integrator/integrator_ap.c
> +++ b/arch/arm/mach-integrator/integrator_ap.c
> @@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
>         clk_prepare_enable(clk);
>         rate = clk_get_rate(clk);
>
> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
> -

As noted this is not an init function for timer-sp.c so please drop this
hunk of the patch. Maybe this zeroing is pointless but that would
be a separate patch that I can test.

> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
> index 2b0db82..c68e7d8 100644
> --- a/arch/arm/mach-integrator/integrator_cp.c
> +++ b/arch/arm/mach-integrator/integrator_cp.c
> @@ -33,7 +33,6 @@
>  #include <mach/platform.h>
>  #include <asm/setup.h>
>  #include <asm/mach-types.h>
> -#include <asm/hardware/arm_timer.h>

What doe this change has to do with $SUBJECT?

>  #include <asm/hardware/icst.h>
>
>  #include <mach/cm.h>
> @@ -267,7 +266,6 @@ static void __init cp_of_timer_init(void)
>         base = of_iomap(node, 0);
>         if (WARN_ON(!base))
>                 return;
> -       writel(0, base + TIMER_CTRL);
>         sp804_clocksource_init(base, node->name);
>
>         err = of_property_read_string(of_aliases,
> @@ -279,7 +277,6 @@ static void __init cp_of_timer_init(void)
>         if (WARN_ON(!base))
>                 return;
>         irq = irq_of_parse_and_map(node, 0);
> -       writel(0, base + TIMER_CTRL);
>         sp804_clockevents_init(base, irq, node->name);
>  }
>
> @@ -510,10 +507,6 @@ static void __init intcp_init_irq(void)
>
>  static void __init cp_timer_init(void)
>  {
> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
> -
>         sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
>         sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
>  }

The rest of the changes to integrator_cp.c looks OK...

Yours,
Linus Walleij

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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-21 17:58     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 17:58 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> The timer-sp initialization code clears the control register before
> initializing the timers, so every platform doing this is redundant.
>
> For unused timers, we should not care what state they are in.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
(...)
> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
> index ea96144..4cb322d 100644
> --- a/arch/arm/mach-integrator/integrator_ap.c
> +++ b/arch/arm/mach-integrator/integrator_ap.c
> @@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
>         clk_prepare_enable(clk);
>         rate = clk_get_rate(clk);
>
> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
> -

As noted this is not an init function for timer-sp.c so please drop this
hunk of the patch. Maybe this zeroing is pointless but that would
be a separate patch that I can test.

> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
> index 2b0db82..c68e7d8 100644
> --- a/arch/arm/mach-integrator/integrator_cp.c
> +++ b/arch/arm/mach-integrator/integrator_cp.c
> @@ -33,7 +33,6 @@
>  #include <mach/platform.h>
>  #include <asm/setup.h>
>  #include <asm/mach-types.h>
> -#include <asm/hardware/arm_timer.h>

What doe this change has to do with $SUBJECT?

>  #include <asm/hardware/icst.h>
>
>  #include <mach/cm.h>
> @@ -267,7 +266,6 @@ static void __init cp_of_timer_init(void)
>         base = of_iomap(node, 0);
>         if (WARN_ON(!base))
>                 return;
> -       writel(0, base + TIMER_CTRL);
>         sp804_clocksource_init(base, node->name);
>
>         err = of_property_read_string(of_aliases,
> @@ -279,7 +277,6 @@ static void __init cp_of_timer_init(void)
>         if (WARN_ON(!base))
>                 return;
>         irq = irq_of_parse_and_map(node, 0);
> -       writel(0, base + TIMER_CTRL);
>         sp804_clockevents_init(base, irq, node->name);
>  }
>
> @@ -510,10 +507,6 @@ static void __init intcp_init_irq(void)
>
>  static void __init cp_timer_init(void)
>  {
> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
> -
>         sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
>         sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
>  }

The rest of the changes to integrator_cp.c looks OK...

Yours,
Linus Walleij

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
  2013-03-20 22:54   ` Rob Herring
@ 2013-03-21 18:02     ` Linus Walleij
  -1 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:02 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> This adds CLKSRC_OF based init for sp804 timer. The clock initialization is
> refactored to support retrieving the clock(s) from the DT.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
(...)
> @@ -186,6 +201,57 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
>         evt->irq = irq;
>         evt->cpumask = cpu_possible_mask;
>
> +       writel(0, clkevt_base + TIMER_CTRL);
> +

Wait, patch 1/11 depends on this being done first, right?

So patch 1/11 has to be moved after this one in the series
to avoid bisectability problems?

Apart from that:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-21 18:02     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> This adds CLKSRC_OF based init for sp804 timer. The clock initialization is
> refactored to support retrieving the clock(s) from the DT.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
(...)
> @@ -186,6 +201,57 @@ void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
>         evt->irq = irq;
>         evt->cpumask = cpu_possible_mask;
>
> +       writel(0, clkevt_base + TIMER_CTRL);
> +

Wait, patch 1/11 depends on this being done first, right?

So patch 1/11 has to be moved after this one in the series
to avoid bisectability problems?

Apart from that:
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-21 18:03       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 18:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On 03/21/2013 12:58 PM, Linus Walleij wrote:
> On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:
> 
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> The timer-sp initialization code clears the control register before
>> initializing the timers, so every platform doing this is redundant.
>>
>> For unused timers, we should not care what state they are in.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> (...)
>> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
>> index ea96144..4cb322d 100644
>> --- a/arch/arm/mach-integrator/integrator_ap.c
>> +++ b/arch/arm/mach-integrator/integrator_ap.c
>> @@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
>>         clk_prepare_enable(clk);
>>         rate = clk_get_rate(clk);
>>
>> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
>> -
> 
> As noted this is not an init function for timer-sp.c so please drop this
> hunk of the patch. Maybe this zeroing is pointless but that would
> be a separate patch that I can test.

Okay. I'll split this out.

> 
>> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
>> index 2b0db82..c68e7d8 100644
>> --- a/arch/arm/mach-integrator/integrator_cp.c
>> +++ b/arch/arm/mach-integrator/integrator_cp.c
>> @@ -33,7 +33,6 @@
>>  #include <mach/platform.h>
>>  #include <asm/setup.h>
>>  #include <asm/mach-types.h>
>> -#include <asm/hardware/arm_timer.h>
> 
> What doe this change has to do with $SUBJECT?

If I remove TIMER_CTRL use, then I don't need the header that defines it
any more.

Rob


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

* Re: [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-21 18:03       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 18:03 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Russell King, pawel.moll-5wv7dgnIgG8,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 03/21/2013 12:58 PM, Linus Walleij wrote:
> On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> 
>> From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
>>
>> The timer-sp initialization code clears the control register before
>> initializing the timers, so every platform doing this is redundant.
>>
>> For unused timers, we should not care what state they are in.
>>
>> Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
> (...)
>> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
>> index ea96144..4cb322d 100644
>> --- a/arch/arm/mach-integrator/integrator_ap.c
>> +++ b/arch/arm/mach-integrator/integrator_ap.c
>> @@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
>>         clk_prepare_enable(clk);
>>         rate = clk_get_rate(clk);
>>
>> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
>> -
> 
> As noted this is not an init function for timer-sp.c so please drop this
> hunk of the patch. Maybe this zeroing is pointless but that would
> be a separate patch that I can test.

Okay. I'll split this out.

> 
>> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
>> index 2b0db82..c68e7d8 100644
>> --- a/arch/arm/mach-integrator/integrator_cp.c
>> +++ b/arch/arm/mach-integrator/integrator_cp.c
>> @@ -33,7 +33,6 @@
>>  #include <mach/platform.h>
>>  #include <asm/setup.h>
>>  #include <asm/mach-types.h>
>> -#include <asm/hardware/arm_timer.h>
> 
> What doe this change has to do with $SUBJECT?

If I remove TIMER_CTRL use, then I don't need the header that defines it
any more.

Rob

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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-21 18:03       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-21 18:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/21/2013 12:58 PM, Linus Walleij wrote:
> On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:
> 
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> The timer-sp initialization code clears the control register before
>> initializing the timers, so every platform doing this is redundant.
>>
>> For unused timers, we should not care what state they are in.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> (...)
>> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
>> index ea96144..4cb322d 100644
>> --- a/arch/arm/mach-integrator/integrator_ap.c
>> +++ b/arch/arm/mach-integrator/integrator_ap.c
>> @@ -643,10 +643,6 @@ static void __init ap_timer_init(void)
>>         clk_prepare_enable(clk);
>>         rate = clk_get_rate(clk);
>>
>> -       writel(0, TIMER0_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER1_VA_BASE + TIMER_CTRL);
>> -       writel(0, TIMER2_VA_BASE + TIMER_CTRL);
>> -
> 
> As noted this is not an init function for timer-sp.c so please drop this
> hunk of the patch. Maybe this zeroing is pointless but that would
> be a separate patch that I can test.

Okay. I'll split this out.

> 
>> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
>> index 2b0db82..c68e7d8 100644
>> --- a/arch/arm/mach-integrator/integrator_cp.c
>> +++ b/arch/arm/mach-integrator/integrator_cp.c
>> @@ -33,7 +33,6 @@
>>  #include <mach/platform.h>
>>  #include <asm/setup.h>
>>  #include <asm/mach-types.h>
>> -#include <asm/hardware/arm_timer.h>
> 
> What doe this change has to do with $SUBJECT?

If I remove TIMER_CTRL use, then I don't need the header that defines it
any more.

Rob

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

* Re: [PATCH 09/11] ARM: integrator-cp: convert use CLKSRC_OF for timer init
  2013-03-20 22:54   ` Rob Herring
@ 2013-03-21 18:07     ` Linus Walleij
  -1 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:07 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> Move the integrator-cp timer init to timer-sp.c and use CLKSRC_OF. There is
> no reason to use the aliases, so drop them from the init code.
>
> The integrator-cp timers are mistakenly called sp804 timers in the dts, but
> in fact they are not sp804 dual timers, but single timers with the same
> programming model. Fix the dts to reflect this.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>

Looks correct to me. Throw it into linux-next and I'll
test if it works too! :-)
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* [PATCH 09/11] ARM: integrator-cp: convert use CLKSRC_OF for timer init
@ 2013-03-21 18:07     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> Move the integrator-cp timer init to timer-sp.c and use CLKSRC_OF. There is
> no reason to use the aliases, so drop them from the init code.
>
> The integrator-cp timers are mistakenly called sp804 timers in the dts, but
> in fact they are not sp804 dual timers, but single timers with the same
> programming model. Fix the dts to reflect this.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>

Looks correct to me. Throw it into linux-next and I'll
test if it works too! :-)
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource
@ 2013-03-21 18:15     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:15 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, Russell King, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> Move timer-sp and integrator-ap timer code to drivers/clocksource and
> update timer-sp.h and arm_timer.h includes.
>
> This adds CLKSRC_OF support for the integrator-ap timer and removes the
> use of "arm,timer-primary" and "arm,timer-secondary" aliases. The timer
> selection should not be important as all 3 timers are equal capability.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>

Nice!

This looks like it'll work.

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource
@ 2013-03-21 18:15     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:15 UTC (permalink / raw)
  To: Rob Herring
  Cc: Russell King, pawel.moll-5wv7dgnIgG8,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

> From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
>
> Move timer-sp and integrator-ap timer code to drivers/clocksource and
> update timer-sp.h and arm_timer.h includes.
>
> This adds CLKSRC_OF support for the integrator-ap timer and removes the
> use of "arm,timer-primary" and "arm,timer-secondary" aliases. The timer
> selection should not be important as all 3 timers are equal capability.
>
> Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
> Cc: Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>
> Cc: John Stultz <john.stultz-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Cc: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>

Nice!

This looks like it'll work.

Acked-by: Linus Walleij <linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

Yours,
Linus Walleij

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

* [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource
@ 2013-03-21 18:15     ` Linus Walleij
  0 siblings, 0 replies; 67+ messages in thread
From: Linus Walleij @ 2013-03-21 18:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 11:54 PM, Rob Herring <robherring2@gmail.com> wrote:

> From: Rob Herring <rob.herring@calxeda.com>
>
> Move timer-sp and integrator-ap timer code to drivers/clocksource and
> update timer-sp.h and arm_timer.h includes.
>
> This adds CLKSRC_OF support for the integrator-ap timer and removes the
> use of "arm,timer-primary" and "arm,timer-secondary" aliases. The timer
> selection should not be important as all 3 timers are equal capability.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Russell King <linux@arm.linux.org.uk>
> Cc: John Stultz <john.stultz@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>

Nice!

This looks like it'll work.

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* Re: [PATCH 02/11] ARM: remove extra timer-sp control register clearing
  2013-03-20 22:54   ` Rob Herring
@ 2013-03-21 19:23     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:23 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, linus.walleij, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 05:54:02PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> The timer-sp initialization code clears the control register before
> initializing the timers, so every platform doing this is redundant.
> 
> For unused timers, we should not care what state they are in.

NAK.  We do care what state they're in.  What if they have their interrupt
enable bit set, and IRQ is shared with the clock event timer?

No, this patch is just wrong.

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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-21 19:23     ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 05:54:02PM -0500, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
> 
> The timer-sp initialization code clears the control register before
> initializing the timers, so every platform doing this is redundant.
> 
> For unused timers, we should not care what state they are in.

NAK.  We do care what state they're in.  What if they have their interrupt
enable bit set, and IRQ is shared with the clock event timer?

No, this patch is just wrong.

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
  2013-03-20 22:54   ` Rob Herring
  (?)
@ 2013-03-21 19:35     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, linus.walleij, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
> +	clk0 = of_clk_get(np, 0);
> +	if (IS_ERR(clk0))
> +		clk0 = NULL;
> +
> +	/* Get the 2nd clock if the timer has 2 timer clocks */
> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
> +		clk1 = of_clk_get(np, 1);
> +		if (IS_ERR(clk1)) {
> +			pr_err("sp804: %s clock not found: %d\n", np->name,
> +				(int)PTR_ERR(clk1));
> +			return;
> +		}
> +	} else
> +		clk1 = clk0;
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (irq <= 0)
> +		return;
> +
> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
> +	if (irq_num == 2)
> +		tmr2_evt = true;
> +
> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
> +				 irq, tmr2_evt ? clk1 : clk0, name);
> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
> +						 name, tmr2_evt ? clk0 : clk1, 1);

This just looks totally screwed to me.

A SP804 cell has two timers, and has one clock input and two clock
enable inputs.  The clock input is common to both timers.  The timers
only count on the rising edge of the clock input when the enable
input is high.  (the APB PCLK also matters too...)

Now, the clock enable inputs are controlled by the SP810 system
controller to achieve different clock rates for each.  So, we *can*
view an SP804 as having two clock inputs.

However, the two clock inputs do not depend on whether one or the
other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.

Using the logic above, the clocks depend on how the IRQs are wired
up... really?  Can you see from my description above why that is
screwed?  What bearing does the IRQ have on the wiring of the
clock inputs?

And, by doing this aren't you embedding into the DT description
something specific to the Linux implementation for this device -
namely the decision by you that the IRQs determine how the clocks
get used?

So... NAK.

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-21 19:35     ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: pawel.moll, Arnd Bergmann, devicetree-discuss, linux-kernel,
	Rob Herring, john.stultz, haojian.zhuang, tglx, linus.walleij,
	linux-arm-kernel

On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
> +	clk0 = of_clk_get(np, 0);
> +	if (IS_ERR(clk0))
> +		clk0 = NULL;
> +
> +	/* Get the 2nd clock if the timer has 2 timer clocks */
> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
> +		clk1 = of_clk_get(np, 1);
> +		if (IS_ERR(clk1)) {
> +			pr_err("sp804: %s clock not found: %d\n", np->name,
> +				(int)PTR_ERR(clk1));
> +			return;
> +		}
> +	} else
> +		clk1 = clk0;
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (irq <= 0)
> +		return;
> +
> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
> +	if (irq_num == 2)
> +		tmr2_evt = true;
> +
> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
> +				 irq, tmr2_evt ? clk1 : clk0, name);
> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
> +						 name, tmr2_evt ? clk0 : clk1, 1);

This just looks totally screwed to me.

A SP804 cell has two timers, and has one clock input and two clock
enable inputs.  The clock input is common to both timers.  The timers
only count on the rising edge of the clock input when the enable
input is high.  (the APB PCLK also matters too...)

Now, the clock enable inputs are controlled by the SP810 system
controller to achieve different clock rates for each.  So, we *can*
view an SP804 as having two clock inputs.

However, the two clock inputs do not depend on whether one or the
other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.

Using the logic above, the clocks depend on how the IRQs are wired
up... really?  Can you see from my description above why that is
screwed?  What bearing does the IRQ have on the wiring of the
clock inputs?

And, by doing this aren't you embedding into the DT description
something specific to the Linux implementation for this device -
namely the decision by you that the IRQs determine how the clocks
get used?

So... NAK.

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-21 19:35     ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
> +	clk0 = of_clk_get(np, 0);
> +	if (IS_ERR(clk0))
> +		clk0 = NULL;
> +
> +	/* Get the 2nd clock if the timer has 2 timer clocks */
> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
> +		clk1 = of_clk_get(np, 1);
> +		if (IS_ERR(clk1)) {
> +			pr_err("sp804: %s clock not found: %d\n", np->name,
> +				(int)PTR_ERR(clk1));
> +			return;
> +		}
> +	} else
> +		clk1 = clk0;
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (irq <= 0)
> +		return;
> +
> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
> +	if (irq_num == 2)
> +		tmr2_evt = true;
> +
> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
> +				 irq, tmr2_evt ? clk1 : clk0, name);
> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
> +						 name, tmr2_evt ? clk0 : clk1, 1);

This just looks totally screwed to me.

A SP804 cell has two timers, and has one clock input and two clock
enable inputs.  The clock input is common to both timers.  The timers
only count on the rising edge of the clock input when the enable
input is high.  (the APB PCLK also matters too...)

Now, the clock enable inputs are controlled by the SP810 system
controller to achieve different clock rates for each.  So, we *can*
view an SP804 as having two clock inputs.

However, the two clock inputs do not depend on whether one or the
other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.

Using the logic above, the clocks depend on how the IRQs are wired
up... really?  Can you see from my description above why that is
screwed?  What bearing does the IRQ have on the wiring of the
clock inputs?

And, by doing this aren't you embedding into the DT description
something specific to the Linux implementation for this device -
namely the decision by you that the IRQs determine how the clocks
get used?

So... NAK.

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

* Re: [PATCH 11/11] devtree: add binding documentation for sp804
  2013-03-20 22:54   ` Rob Herring
  (?)
@ 2013-03-21 19:36     ` Russell King - ARM Linux
  -1 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, pawel.moll, linus.walleij, Rob Herring,
	john.stultz, haojian.zhuang, tglx

On Wed, Mar 20, 2013 at 05:54:11PM -0500, Rob Herring wrote:
> +Optional properties:
> +- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this
> +	specifies if the irq connection is for timer 1 or timer 2. A value of 1
> +	or 2 should be used.

This fails to mention that it has any bearing on the clocks.

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

* Re: [PATCH 11/11] devtree: add binding documentation for sp804
@ 2013-03-21 19:36     ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: Arnd Bergmann, pawel.moll, devicetree-discuss, linux-kernel,
	Rob Herring, john.stultz, haojian.zhuang, tglx, linus.walleij,
	linux-arm-kernel

On Wed, Mar 20, 2013 at 05:54:11PM -0500, Rob Herring wrote:
> +Optional properties:
> +- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this
> +	specifies if the irq connection is for timer 1 or timer 2. A value of 1
> +	or 2 should be used.

This fails to mention that it has any bearing on the clocks.

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

* [PATCH 11/11] devtree: add binding documentation for sp804
@ 2013-03-21 19:36     ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-21 19:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 20, 2013 at 05:54:11PM -0500, Rob Herring wrote:
> +Optional properties:
> +- arm,sp804-has-irq = <#>: In the case of only 1 timer irq line connected, this
> +	specifies if the irq connection is for timer 1 or timer 2. A value of 1
> +	or 2 should be used.

This fails to mention that it has any bearing on the clocks.

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-22  2:31       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-22  2:31 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, linus.walleij, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On 03/21/2013 02:35 PM, Russell King - ARM Linux wrote:
> On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
>> +	clk0 = of_clk_get(np, 0);
>> +	if (IS_ERR(clk0))
>> +		clk0 = NULL;
>> +
>> +	/* Get the 2nd clock if the timer has 2 timer clocks */
>> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
>> +		clk1 = of_clk_get(np, 1);
>> +		if (IS_ERR(clk1)) {
>> +			pr_err("sp804: %s clock not found: %d\n", np->name,
>> +				(int)PTR_ERR(clk1));
>> +			return;
>> +		}
>> +	} else
>> +		clk1 = clk0;
>> +
>> +	irq = irq_of_parse_and_map(np, 0);
>> +	if (irq <= 0)
>> +		return;
>> +
>> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
>> +	if (irq_num == 2)
>> +		tmr2_evt = true;
>> +
>> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
>> +				 irq, tmr2_evt ? clk1 : clk0, name);
>> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
>> +						 name, tmr2_evt ? clk0 : clk1, 1);
> 
> This just looks totally screwed to me.
> 
> A SP804 cell has two timers, and has one clock input and two clock
> enable inputs.  The clock input is common to both timers.  The timers
> only count on the rising edge of the clock input when the enable
> input is high.  (the APB PCLK also matters too...)
> 
> Now, the clock enable inputs are controlled by the SP810 system
> controller to achieve different clock rates for each.  So, we *can*
> view an SP804 as having two clock inputs.

Exactly. Effectively, the TIMCLKENx are just dividers of the clock input.

> However, the two clock inputs do not depend on whether one or the
> other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
> TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.
> 
> Using the logic above, the clocks depend on how the IRQs are wired
> up... really?  Can you see from my description above why that is
> screwed?  What bearing does the IRQ have on the wiring of the
> clock inputs?

No. I'm simply swapping which timer is used for clksrc vs. clkevt based
on the irq connection DT describes. If only timer 2's irq being hooked
up, then timer 2 is the clkevt. Otherwise I always use timer 1 for the
clkevt because I either have a combined interrupt or timer 1 interrupt
hooked up.

Perhaps re-writing it like this would be more clear:

if (irq_num == 2){
	__sp804_clockevents_init(base + TIMER_2_BASE, irq, clk1, name);
	__sp804_clocksource_and_sched_clock_init(base, name, clk0, 1);
} else {
	__sp804_clockevents_init(base, irq, clk0, name);
	__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
						name, clk1, 1);
}


Rob

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-22  2:31       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-22  2:31 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: pawel.moll-5wv7dgnIgG8,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Herring,
	john.stultz-QSEj5FYQhm4dnm+yROfE0A,
	haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
	tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 03/21/2013 02:35 PM, Russell King - ARM Linux wrote:
> On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
>> +	clk0 = of_clk_get(np, 0);
>> +	if (IS_ERR(clk0))
>> +		clk0 = NULL;
>> +
>> +	/* Get the 2nd clock if the timer has 2 timer clocks */
>> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
>> +		clk1 = of_clk_get(np, 1);
>> +		if (IS_ERR(clk1)) {
>> +			pr_err("sp804: %s clock not found: %d\n", np->name,
>> +				(int)PTR_ERR(clk1));
>> +			return;
>> +		}
>> +	} else
>> +		clk1 = clk0;
>> +
>> +	irq = irq_of_parse_and_map(np, 0);
>> +	if (irq <= 0)
>> +		return;
>> +
>> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
>> +	if (irq_num == 2)
>> +		tmr2_evt = true;
>> +
>> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
>> +				 irq, tmr2_evt ? clk1 : clk0, name);
>> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
>> +						 name, tmr2_evt ? clk0 : clk1, 1);
> 
> This just looks totally screwed to me.
> 
> A SP804 cell has two timers, and has one clock input and two clock
> enable inputs.  The clock input is common to both timers.  The timers
> only count on the rising edge of the clock input when the enable
> input is high.  (the APB PCLK also matters too...)
> 
> Now, the clock enable inputs are controlled by the SP810 system
> controller to achieve different clock rates for each.  So, we *can*
> view an SP804 as having two clock inputs.

Exactly. Effectively, the TIMCLKENx are just dividers of the clock input.

> However, the two clock inputs do not depend on whether one or the
> other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
> TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.
> 
> Using the logic above, the clocks depend on how the IRQs are wired
> up... really?  Can you see from my description above why that is
> screwed?  What bearing does the IRQ have on the wiring of the
> clock inputs?

No. I'm simply swapping which timer is used for clksrc vs. clkevt based
on the irq connection DT describes. If only timer 2's irq being hooked
up, then timer 2 is the clkevt. Otherwise I always use timer 1 for the
clkevt because I either have a combined interrupt or timer 1 interrupt
hooked up.

Perhaps re-writing it like this would be more clear:

if (irq_num == 2){
	__sp804_clockevents_init(base + TIMER_2_BASE, irq, clk1, name);
	__sp804_clocksource_and_sched_clock_init(base, name, clk0, 1);
} else {
	__sp804_clockevents_init(base, irq, clk0, name);
	__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
						name, clk1, 1);
}


Rob

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-22  2:31       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-22  2:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/21/2013 02:35 PM, Russell King - ARM Linux wrote:
> On Wed, Mar 20, 2013 at 05:54:03PM -0500, Rob Herring wrote:
>> +	clk0 = of_clk_get(np, 0);
>> +	if (IS_ERR(clk0))
>> +		clk0 = NULL;
>> +
>> +	/* Get the 2nd clock if the timer has 2 timer clocks */
>> +	if (of_count_phandle_with_args(np, "clocks", "#clock-cells") == 3) {
>> +		clk1 = of_clk_get(np, 1);
>> +		if (IS_ERR(clk1)) {
>> +			pr_err("sp804: %s clock not found: %d\n", np->name,
>> +				(int)PTR_ERR(clk1));
>> +			return;
>> +		}
>> +	} else
>> +		clk1 = clk0;
>> +
>> +	irq = irq_of_parse_and_map(np, 0);
>> +	if (irq <= 0)
>> +		return;
>> +
>> +	of_property_read_u32(np, "arm,sp804-has-irq", &irq_num);
>> +	if (irq_num == 2)
>> +		tmr2_evt = true;
>> +
>> +	__sp804_clockevents_init(base + (tmr2_evt ? TIMER_2_BASE : 0),
>> +				 irq, tmr2_evt ? clk1 : clk0, name);
>> +	__sp804_clocksource_and_sched_clock_init(base + (tmr2_evt ? 0 : TIMER_2_BASE),
>> +						 name, tmr2_evt ? clk0 : clk1, 1);
> 
> This just looks totally screwed to me.
> 
> A SP804 cell has two timers, and has one clock input and two clock
> enable inputs.  The clock input is common to both timers.  The timers
> only count on the rising edge of the clock input when the enable
> input is high.  (the APB PCLK also matters too...)
> 
> Now, the clock enable inputs are controlled by the SP810 system
> controller to achieve different clock rates for each.  So, we *can*
> view an SP804 as having two clock inputs.

Exactly. Effectively, the TIMCLKENx are just dividers of the clock input.

> However, the two clock inputs do not depend on whether one or the
> other has an IRQ or not.  Timer 1 is always clocked by TIMCLK &
> TIMCLKEN1.  Timer 2 is always clocked by TIMCLK & TIMCLKEN2.
> 
> Using the logic above, the clocks depend on how the IRQs are wired
> up... really?  Can you see from my description above why that is
> screwed?  What bearing does the IRQ have on the wiring of the
> clock inputs?

No. I'm simply swapping which timer is used for clksrc vs. clkevt based
on the irq connection DT describes. If only timer 2's irq being hooked
up, then timer 2 is the clkevt. Otherwise I always use timer 1 for the
clkevt because I either have a combined interrupt or timer 1 interrupt
hooked up.

Perhaps re-writing it like this would be more clear:

if (irq_num == 2){
	__sp804_clockevents_init(base + TIMER_2_BASE, irq, clk1, name);
	__sp804_clocksource_and_sched_clock_init(base, name, clk0, 1);
} else {
	__sp804_clockevents_init(base, irq, clk0, name);
	__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
						name, clk1, 1);
}


Rob

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

* Re: [PATCH 02/11] ARM: remove extra timer-sp control register clearing
  2013-03-21 19:23     ` Russell King - ARM Linux
@ 2013-03-22  2:36       ` Rob Herring
  -1 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-22  2:36 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, linus.walleij, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On 03/21/2013 02:23 PM, Russell King - ARM Linux wrote:
> On Wed, Mar 20, 2013 at 05:54:02PM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> The timer-sp initialization code clears the control register before
>> initializing the timers, so every platform doing this is redundant.
>>
>> For unused timers, we should not care what state they are in.
> 
> NAK.  We do care what state they're in.  What if they have their interrupt
> enable bit set, and IRQ is shared with the clock event timer?
> 
> No, this patch is just wrong.

Okay, I can have the timer init function clear the register in the case
that even when the timer is unused.

Rob


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

* [PATCH 02/11] ARM: remove extra timer-sp control register clearing
@ 2013-03-22  2:36       ` Rob Herring
  0 siblings, 0 replies; 67+ messages in thread
From: Rob Herring @ 2013-03-22  2:36 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/21/2013 02:23 PM, Russell King - ARM Linux wrote:
> On Wed, Mar 20, 2013 at 05:54:02PM -0500, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> The timer-sp initialization code clears the control register before
>> initializing the timers, so every platform doing this is redundant.
>>
>> For unused timers, we should not care what state they are in.
> 
> NAK.  We do care what state they're in.  What if they have their interrupt
> enable bit set, and IRQ is shared with the clock event timer?
> 
> No, this patch is just wrong.

Okay, I can have the timer init function clear the register in the case
that even when the timer is unused.

Rob

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

* Re: [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
  2013-03-22  2:31       ` Rob Herring
@ 2013-03-22 11:49         ` Russell King - ARM Linux
  -1 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-22 11:49 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-arm-kernel, linux-kernel, devicetree-discuss,
	Arnd Bergmann, linus.walleij, haojian.zhuang, pawel.moll,
	john.stultz, tglx, Rob Herring

On Thu, Mar 21, 2013 at 09:31:01PM -0500, Rob Herring wrote:
> Perhaps re-writing it like this would be more clear:
> 
> if (irq_num == 2){
> 	__sp804_clockevents_init(base + TIMER_2_BASE, irq, clk1, name);
> 	__sp804_clocksource_and_sched_clock_init(base, name, clk0, 1);
> } else {
> 	__sp804_clockevents_init(base, irq, clk0, name);
> 	__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
> 						name, clk1, 1);
> }

Yes, that is definitely much clearer than the original patch.

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

* [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init
@ 2013-03-22 11:49         ` Russell King - ARM Linux
  0 siblings, 0 replies; 67+ messages in thread
From: Russell King - ARM Linux @ 2013-03-22 11:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 21, 2013 at 09:31:01PM -0500, Rob Herring wrote:
> Perhaps re-writing it like this would be more clear:
> 
> if (irq_num == 2){
> 	__sp804_clockevents_init(base + TIMER_2_BASE, irq, clk1, name);
> 	__sp804_clocksource_and_sched_clock_init(base, name, clk0, 1);
> } else {
> 	__sp804_clockevents_init(base, irq, clk0, name);
> 	__sp804_clocksource_and_sched_clock_init(base + TIMER_2_BASE,
> 						name, clk1, 1);
> }

Yes, that is definitely much clearer than the original patch.

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

end of thread, other threads:[~2013-03-22 11:49 UTC | newest]

Thread overview: 67+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-20 22:54 [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support Rob Herring
2013-03-20 22:54 ` Rob Herring
2013-03-20 22:54 ` [PATCH 01/11] OF: add empty of_device_is_available for !OF Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 14:18   ` Mark Rutland
2013-03-21 14:18     ` Mark Rutland
2013-03-21 14:18     ` Mark Rutland
2013-03-21 14:26     ` Rob Herring
2013-03-21 14:26       ` Rob Herring
2013-03-21 14:26       ` Rob Herring
2013-03-20 22:54 ` [PATCH 02/11] ARM: remove extra timer-sp control register clearing Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 17:58   ` Linus Walleij
2013-03-21 17:58     ` Linus Walleij
2013-03-21 18:03     ` Rob Herring
2013-03-21 18:03       ` Rob Herring
2013-03-21 18:03       ` Rob Herring
2013-03-21 19:23   ` Russell King - ARM Linux
2013-03-21 19:23     ` Russell King - ARM Linux
2013-03-22  2:36     ` Rob Herring
2013-03-22  2:36       ` Rob Herring
2013-03-20 22:54 ` [PATCH 03/11] ARM: timer-sp: convert to use CLKSRC_OF init Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 18:02   ` Linus Walleij
2013-03-21 18:02     ` Linus Walleij
2013-03-21 19:35   ` Russell King - ARM Linux
2013-03-21 19:35     ` Russell King - ARM Linux
2013-03-21 19:35     ` Russell King - ARM Linux
2013-03-22  2:31     ` Rob Herring
2013-03-22  2:31       ` Rob Herring
2013-03-22  2:31       ` Rob Herring
2013-03-22 11:49       ` Russell King - ARM Linux
2013-03-22 11:49         ` Russell King - ARM Linux
2013-03-20 22:54 ` [PATCH 04/11] ARM: highbank: use OF init for sp804 timer Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54 ` [PATCH 05/11] ARM: vexpress: remove sp804 OF init Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54 ` [PATCH 06/11] ARM: dts: vexpress: disable CA9 core tile sp804 timer Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54 ` [PATCH 07/11] ARM: versatile: add versatile dtbs to dtbs target Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54 ` [PATCH 08/11] ARM: versatile: use OF init for sp804 timer Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-20 22:54 ` [PATCH 09/11] ARM: integrator-cp: convert use CLKSRC_OF for timer init Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 18:07   ` Linus Walleij
2013-03-21 18:07     ` Linus Walleij
2013-03-20 22:54 ` [PATCH 10/11] ARM: move sp804 and integrator timers to drivers/clocksource Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 18:15   ` Linus Walleij
2013-03-21 18:15     ` Linus Walleij
2013-03-21 18:15     ` Linus Walleij
2013-03-20 22:54 ` [PATCH 11/11] devtree: add binding documentation for sp804 Rob Herring
2013-03-20 22:54   ` Rob Herring
2013-03-21 19:36   ` Russell King - ARM Linux
2013-03-21 19:36     ` Russell King - ARM Linux
2013-03-21 19:36     ` Russell King - ARM Linux
2013-03-21 13:24 ` [PATCH 00/11] sp804 and integrator timer CLKSRC_OF support Arnd Bergmann
2013-03-21 13:24   ` Arnd Bergmann
2013-03-21 13:24   ` Arnd Bergmann
2013-03-21 14:06   ` Rob Herring
2013-03-21 14:06     ` Rob Herring
2013-03-21 14:06     ` Rob Herring

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.