linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC/PATCH 0/3] 32k timer patches
@ 2010-03-31 11:13 Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 1/3] omap: fix clocksource_32k to start from zero Felipe Balbi
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Felipe Balbi @ 2010-03-31 11:13 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi

The following patches convert 32k-sync timer into a platform_driver
and also remove dead code from timer32k.c

If anyone has a good idea on how to fix-up timer-gp.c, I'll be
glad to hear. Currently I can't move it to platform_driver
because it's used the system timer during machine start so I can't
find a proper location to register the platform_device. If we don't
register a system timer, we will loop forever trying to calibrate
the delay loop.

The patches were boot tested on rx51 and compile tested with
omap_h2_1610_defconfig.

Aaro Koskinen (1):
  omap: fix clocksource_32k to start from zero

Felipe Balbi (2):
  arm: omap1: remove dead code from timer32k.c
  arm: omap1/2/3/4: convert clocksource to a platform_driver

 arch/arm/mach-omap1/devices.c        |   24 ++++
 arch/arm/mach-omap1/timer32k.c       |   15 --
 arch/arm/mach-omap2/clock2420_data.c |    2 +-
 arch/arm/mach-omap2/clock2430_data.c |    2 +-
 arch/arm/mach-omap2/clock3xxx_data.c |    2 +-
 arch/arm/mach-omap2/devices.c        |   38 +++++
 arch/arm/plat-omap/Makefile          |    4 +-
 arch/arm/plat-omap/common.c          |  149 --------------------
 arch/arm/plat-omap/timer-32k-sync.c  |  250 ++++++++++++++++++++++++++++++++++
 9 files changed, 317 insertions(+), 169 deletions(-)
 create mode 100644 arch/arm/plat-omap/timer-32k-sync.c


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

* [RFC/PATCH 1/3] omap: fix clocksource_32k to start from zero
  2010-03-31 11:13 [RFC/PATCH 0/3] 32k timer patches Felipe Balbi
@ 2010-03-31 11:13 ` Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
  2 siblings, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2010-03-31 11:13 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Aaro Koskinen

From: Aaro Koskinen <aaro.koskinen@nokia.com>

When the 32k sync timer is used for sched_clock(), it should count
time from the kernel boot (clocksource init) instead of the last HW
reset. Otherwise printk.time values will jump suddenly during the boot:

	[    0.000000] calling  omap2_clk_arch_init+0x0/0x138 @ 1
	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned -22 after 0 usecs
	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned with error code -22
	[    0.000000] calling  omap_init_clocksource_32k+0x0/0x98 @ 1
	[  508.697937] initcall omap_init_clocksource_32k+0x0/0x98 returned 0 after 0 usecs
	[  508.697967] calling  omap_init_devices+0x0/0x38 @ 1
	[  508.698425] initcall omap_init_devices+0x0/0x38 returned 0 after 0 usecs

This will confuse tools such as scripts/bootgraph.pl.

Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/plat-omap/common.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 088c1a0..01cbb48 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -100,10 +100,17 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 #include <linux/clocksource.h>
 
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
 #ifdef CONFIG_ARCH_OMAP16XX
 static cycle_t omap16xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
 #else
 #define omap16xx_32k_read	NULL
@@ -112,7 +119,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2420
 static cycle_t omap2420_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2420_32k_read	NULL
@@ -121,7 +128,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2430
 static cycle_t omap2430_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2430_32k_read	NULL
@@ -130,7 +137,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP3
 static cycle_t omap34xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap34xx_32k_read	NULL
@@ -139,7 +146,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP4
 static cycle_t omap44xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap44xx_32k_read	NULL
@@ -227,6 +234,8 @@ static int __init omap_init_clocksource_32k(void)
 		clocksource_32k.mult = clocksource_hz2mult(32768,
 					    clocksource_32k.shift);
 
+		offset_32k = clocksource_32k.read(&clocksource_32k);
+
 		if (clocksource_register(&clocksource_32k))
 			printk(err, clocksource_32k.name);
 	}
-- 
1.7.0.rc0.33.g7c3932


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

* [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c
  2010-03-31 11:13 [RFC/PATCH 0/3] 32k timer patches Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 1/3] omap: fix clocksource_32k to start from zero Felipe Balbi
@ 2010-03-31 11:13 ` Felipe Balbi
  2010-04-06 21:30   ` Kevin Hilman
  2010-03-31 11:13 ` [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
  2 siblings, 1 reply; 16+ messages in thread
From: Felipe Balbi @ 2010-03-31 11:13 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi

Trivial patch, no functional changes

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---
 arch/arm/mach-omap1/timer32k.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 9ad1185..20cfbcc 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
  * ---------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
 /* 16xx specific defines */
 #define OMAP1_32K_TIMER_BASE		0xfffb9000
 #define OMAP1_32K_TIMER_CR		0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
 	.set_mode	= omap_32k_timer_set_mode,
 };
 
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = &clockevent_32k_timer;
-- 
1.7.0.rc0.33.g7c3932


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

* [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-31 11:13 [RFC/PATCH 0/3] 32k timer patches Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 1/3] omap: fix clocksource_32k to start from zero Felipe Balbi
  2010-03-31 11:13 ` [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c Felipe Balbi
@ 2010-03-31 11:13 ` Felipe Balbi
  2010-04-06 21:37   ` Kevin Hilman
  2 siblings, 1 reply; 16+ messages in thread
From: Felipe Balbi @ 2010-03-31 11:13 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi

Convert the omap32k clocksource driver into a platform_driver
and while at that, also remove the ifdeferry around the code.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---
 arch/arm/mach-omap1/devices.c        |   24 ++++
 arch/arm/mach-omap2/clock2420_data.c |    2 +-
 arch/arm/mach-omap2/clock2430_data.c |    2 +-
 arch/arm/mach-omap2/clock3xxx_data.c |    2 +-
 arch/arm/mach-omap2/devices.c        |   38 +++++
 arch/arm/plat-omap/Makefile          |    4 +-
 arch/arm/plat-omap/common.c          |  158 ---------------------
 arch/arm/plat-omap/timer-32k-sync.c  |  250 ++++++++++++++++++++++++++++++++++
 8 files changed, 317 insertions(+), 163 deletions(-)
 create mode 100644 arch/arm/plat-omap/timer-32k-sync.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..2e7dbdc 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -28,6 +28,29 @@
 
 /*-------------------------------------------------------------------------*/
 
+#define OMAP16XX_TIMER_32K_BASE		0xfffbc400
+
+static struct resource omap_32k_resources[] = {
+	{
+		.start		= OMAP16XX_TIMER_32K_BASE,
+		.end		= SZ_4K,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_32k_device = {
+	.name			= "omap-32k-sync-timer",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(omap_32k_resources),
+	.resource		= omap_32k_resources,
+};
+
+static void omap_init_32k(void)
+{
+       if (cpu_is_omap16xx())
+	       (void) platform_device_register(&omap_32k_device);
+};
+
 #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
 
 #define	OMAP_RTC_BASE		0xfffb4800
@@ -295,6 +318,7 @@ static int __init omap1_init_devices(void)
 	 * in alphabetical order so they're easier to sort through.
 	 */
 
+	omap_init_32k();
 	omap_init_mbox();
 	omap_init_rtc();
 	omap_init_spi100k();
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index d932b14..1f6e89d 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1806,7 +1806,7 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_242X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
+	CLK("omap-32k-sync-timer",	"ick",	&sync_32k_ick,	CK_242X),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
 	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
 	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 0438b6e..59ac891 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1900,7 +1900,7 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
+	CLK("omap-32k-sync-timer",	"ick",	&sync_32k_ick,	CK_243X),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
 	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
 	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index d5153b6..785c732 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3414,7 +3414,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
 	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
+	CLK("omap-32k-sync-timer",	"ick", &omap_32ksync_ick, CK_3XXX),
 	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
 	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 23e4d77..2c4ff31 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -29,6 +29,43 @@
 
 #include "mux.h"
 
+static struct resource omap_32k_resources[] = {
+	{
+		.start		= -EINVAL,	/* gets changed later */
+		.end		= -EINVAL,	/* gets changed later */
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_32k_device = {
+	.name			= "omap-32k-sync-timer",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(omap_32k_resources),
+	.resource		= omap_32k_resources,
+};
+
+static void omap_init_32k(void)
+{
+	if (cpu_is_omap2420()) {
+		omap_32k_resources[0].start = OMAP2420_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP2420_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap2430()) {
+		omap_32k_resources[0].start = OMAP2430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP2430_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap34xx()) {
+		omap_32k_resources[0].start = OMAP3430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP3430_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap44xx()) {
+		omap_32k_resources[0].start = OMAP4430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP4430_32KSYNCT_BASE + SZ_4K;
+	} else {	/* not supported */
+		return;
+	}
+
+
+	(void) platform_device_register(&omap_32k_device);
+};
+
 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
 static struct resource cam_resources[] = {
@@ -794,6 +831,7 @@ static int __init omap2_init_devices(void)
 	 * in alphabetical order so they're easier to sort through.
 	 */
 	omap_hsmmc_reset();
+	omap_init_32k();
 	omap_init_camera();
 	omap_init_mbox();
 	omap_init_mcspi();
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 98f0191..9c9cf31 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
-	 usb.o fb.o io.o
+	 usb.o fb.o io.o timer-32k-sync.o
 obj-m :=
 obj-n :=
 obj-  :=
@@ -30,4 +30,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
 # OMAP mailbox framework
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
-obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
\ No newline at end of file
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 01cbb48..4be635a 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -87,164 +87,6 @@ const void *omap_get_var_config(u16 tag, size_t *len)
 }
 EXPORT_SYMBOL(omap_get_var_config);
 
-/*
- * 32KHz clocksource ... always available, on pretty most chips except
- * OMAP 730 and 1510.  Other timers could be used as clocksources, with
- * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
- * but systems won't necessarily want to spend resources that way.
- */
-
-#define OMAP16XX_TIMER_32K_SYNCHRONIZED		0xfffbc410
-
-#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
-
-#include <linux/clocksource.h>
-
-/*
- * offset_32k holds the init time counter value. It is then subtracted
- * from every counter read to achieve a counter that counts time from the
- * kernel boot (needed for sched_clock()).
- */
-static u32 offset_32k __read_mostly;
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t omap16xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
-}
-#else
-#define omap16xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2420
-static cycle_t omap2420_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2420_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
-static cycle_t omap2430_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2430_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-static cycle_t omap34xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap34xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static cycle_t omap44xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap44xx_32k_read	NULL
-#endif
-
-/*
- * Kernel assumes that sched_clock can be called early but may not have
- * things ready yet.
- */
-static cycle_t omap_32k_read_dummy(struct clocksource *cs)
-{
-	return 0;
-}
-
-static struct clocksource clocksource_32k = {
-	.name		= "32k_counter",
-	.rating		= 250,
-	.read		= omap_32k_read_dummy,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= 10,
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Returns current time from boot in nsecs. It's OK for this to wrap
- * around for now, as it's just a relative time stamp.
- */
-unsigned long long sched_clock(void)
-{
-	return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
-				  clocksource_32k.mult, clocksource_32k.shift);
-}
-
-/**
- * read_persistent_clock -  Return time from a persistent clock.
- *
- * Reads the time from a source which isn't disabled during PM, the
- * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
- */
-static struct timespec persistent_ts;
-static cycles_t cycles, last_cycles;
-void read_persistent_clock(struct timespec *ts)
-{
-	unsigned long long nsecs;
-	cycles_t delta;
-	struct timespec *tsp = &persistent_ts;
-
-	last_cycles = cycles;
-	cycles = clocksource_32k.read(&clocksource_32k);
-	delta = cycles - last_cycles;
-
-	nsecs = clocksource_cyc2ns(delta,
-				   clocksource_32k.mult, clocksource_32k.shift);
-
-	timespec_add_ns(tsp, nsecs);
-	*ts = *tsp;
-}
-
-static int __init omap_init_clocksource_32k(void)
-{
-	static char err[] __initdata = KERN_ERR
-			"%s: can't register clocksource!\n";
-
-	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-		struct clk *sync_32k_ick;
-
-		if (cpu_is_omap16xx())
-			clocksource_32k.read = omap16xx_32k_read;
-		else if (cpu_is_omap2420())
-			clocksource_32k.read = omap2420_32k_read;
-		else if (cpu_is_omap2430())
-			clocksource_32k.read = omap2430_32k_read;
-		else if (cpu_is_omap34xx())
-			clocksource_32k.read = omap34xx_32k_read;
-		else if (cpu_is_omap44xx())
-			clocksource_32k.read = omap44xx_32k_read;
-		else
-			return -ENODEV;
-
-		sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-		if (sync_32k_ick)
-			clk_enable(sync_32k_ick);
-
-		clocksource_32k.mult = clocksource_hz2mult(32768,
-					    clocksource_32k.shift);
-
-		offset_32k = clocksource_32k.read(&clocksource_32k);
-
-		if (clocksource_register(&clocksource_32k))
-			printk(err, clocksource_32k.name);
-	}
-	return 0;
-}
-arch_initcall(omap_init_clocksource_32k);
-
-#endif	/* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
-
 /* Global address base setup code */
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
diff --git a/arch/arm/plat-omap/timer-32k-sync.c b/arch/arm/plat-omap/timer-32k-sync.c
new file mode 100644
index 0000000..33e1f82
--- /dev/null
+++ b/arch/arm/plat-omap/timer-32k-sync.c
@@ -0,0 +1,250 @@
+/*
+ * timer-32k-sync.c -- OMAP 32k Sync Timer Clocksource Driver
+ *
+ * Copyright (C) 2005-2010 Tony Lindgren <tony@atomide.com>
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.com>
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * 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/kernel.h>
+#include <linux/time.h>
+#include <linux/clocksource.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+struct omap_32k_sync_device {
+	struct timespec		persistent_ts;
+	struct clocksource	cs;
+	cycles_t		cycles;
+	cycles_t		last_cycles;
+
+	struct device		*dev;
+	struct clk		*ick;
+	void __iomem		*base;
+
+	/*
+	 * offset_32k holds the init time counter value. It is then subtracted
+	 * from every counter read to achieve a counter that counts time from the
+	 * kernel boot (needed for sched_clock()).
+	 */
+	u32			offset_32k __read_mostly;
+};
+
+#define to_omap_32k(cs)	(container_of(cs, struct omap_32k_sync_device, cs))
+
+static struct omap_32k_sync_device	*thecs;
+
+static inline u32 omap_32k_sync_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_32k_sync_32k_read(struct clocksource *cs)
+{
+	struct omap_32k_sync_device	*omap = to_omap_32k(cs);
+
+	return omap_32k_sync_readl(omap->base, 0x10) - omap->offset_32k;
+}
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+	struct omap_32k_sync_device	*omap = thecs;
+
+	if (!omap)
+		return 0;
+
+	return clocksource_cyc2ns(omap->cs.read(&omap->cs),
+			omap->cs.mult, omap->cs.shift);
+}
+
+/**
+ * read_persistent_clock -  Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer.  Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+void read_persistent_clock(struct timespec *ts)
+{
+	struct omap_32k_sync_device	*omap = thecs;
+	unsigned long long	nsecs;
+	cycles_t		delta;
+	struct timespec		*tsp;
+
+	if (!omap) {
+		ts->tv_sec = 0;
+		ts->tv_nsec = 0;
+		return;
+	}
+
+	tsp = &omap->persistent_ts;
+
+	omap->last_cycles = omap->cycles;
+	omap->cycles = omap->cs.read(&omap->cs);
+	delta = omap->cycles - omap->last_cycles;
+
+	nsecs = clocksource_cyc2ns(delta,
+			omap->cs.mult, omap->cs.shift);
+
+	timespec_add_ns(tsp, nsecs);
+	*ts = *tsp;
+}
+
+static int __init omap_32k_sync_probe(struct platform_device *pdev)
+{
+	struct omap_32k_sync_device		*omap;
+	struct resource			*res;
+	struct clk			*ick;
+
+	int				ret;
+
+	void __iomem			*base;
+
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		dev_dbg(&pdev->dev, "unable to allocate memory\n");
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "couldn't get resource\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	base = ioremap(res->start, resource_size(res));
+	if (!base) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	ick = clk_get(&pdev->dev, "ick");
+	if (IS_ERR(ick)) {
+		dev_dbg(&pdev->dev, "couldn't get clock\n");
+		ret = PTR_ERR(ick);
+		goto err3;
+	}
+
+	ret = clk_enable(ick);
+	if (ret) {
+		dev_dbg(&pdev->dev, "couldn't enable clock\n");
+		goto err4;
+	}
+
+	omap->base	= base;
+	omap->dev	= &pdev->dev;
+	omap->ick	= ick;
+
+	omap->cs.name	= "timer-32k";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_32k_sync_32k_read;
+	omap->cs.mask	= CLOCKSOURCE_MASK(32);
+	omap->cs.shift	= 10;
+	omap->cs.flags	= CLOCK_SOURCE_IS_CONTINUOUS;
+	omap->cs.mult	= clocksource_hz2mult(32768, omap->cs.shift);
+
+	platform_set_drvdata(pdev, omap);
+
+	ret = clocksource_register(&omap->cs);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to register clocksource\n");
+		goto err5;
+	}
+
+	/* initialize our offset */
+	omap->offset_32k	=  omap_32k_sync_32k_read(&omap->cs);
+
+	/*
+	 * REVISIT for now we need to keep a global static pointer
+	 * to this clocksource instance. Would it make any sense
+	 * to provide a get_clocksource() to fetch the clocksource
+	 * we just registered ?
+	 */
+	thecs = omap;
+
+	return 0;
+
+err5:
+	clk_disable(ick);
+
+err4:
+	clk_put(ick);
+
+err3:
+	iounmap(base);
+
+err2:
+err1:
+	kfree(omap);
+
+err0:
+	return ret;
+}
+
+static int __exit omap_32k_sync_remove(struct platform_device *pdev)
+{
+	struct omap_32k_sync_device	*omap = platform_get_drvdata(pdev);
+
+	clocksource_unregister(&omap->cs);
+	clk_disable(omap->ick);
+	clk_put(omap->ick);
+	iounmap(omap->base);
+	kfree(omap);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static void omap_32k_sync_shutdown(struct platform_device *pdev)
+{
+	struct omap_32k_sync_device	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_32k_sync_driver = {
+	.remove		= __exit_p(omap_32k_sync_remove),
+	.shutdown	= omap_32k_sync_shutdown,
+	.driver		= {
+		.name	= "omap-32k-sync-timer",
+	},
+};
+
+static int __init omap_32k_sync_init(void)
+{
+	return platform_driver_probe(&omap_32k_sync_driver, omap_32k_sync_probe);
+}
+arch_initcall(omap_32k_sync_init);
+
+static void __exit omap_32k_sync_exit(void)
+{
+	platform_driver_unregister(&omap_32k_sync_driver);
+}
+module_exit(omap_32k_sync_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.0.rc0.33.g7c3932


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

* Re: [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c
  2010-03-31 11:13 ` [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c Felipe Balbi
@ 2010-04-06 21:30   ` Kevin Hilman
  0 siblings, 0 replies; 16+ messages in thread
From: Kevin Hilman @ 2010-04-06 21:30 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Tony Lindgren, Linux OMAP Mailing List

Felipe Balbi <felipe.balbi@nokia.com> writes:

> Trivial patch, no functional changes
>
> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>

Acked-by: Kevin Hilman <khilman@deeprootsystems.com>

> ---
>  arch/arm/mach-omap1/timer32k.c |   15 ---------------
>  1 files changed, 0 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
> index 9ad1185..20cfbcc 100644
> --- a/arch/arm/mach-omap1/timer32k.c
> +++ b/arch/arm/mach-omap1/timer32k.c
> @@ -68,12 +68,6 @@ struct sys_timer omap_timer;
>   * ---------------------------------------------------------------------------
>   */
>  
> -#if defined(CONFIG_ARCH_OMAP16XX)
> -#define TIMER_32K_SYNCHRONIZED		0xfffbc410
> -#else
> -#error OMAP 32KHz timer does not currently work on 15XX!
> -#endif
> -
>  /* 16xx specific defines */
>  #define OMAP1_32K_TIMER_BASE		0xfffb9000
>  #define OMAP1_32K_TIMER_CR		0x08
> @@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
>  	.set_mode	= omap_32k_timer_set_mode,
>  };
>  
> -/*
> - * The 32KHz synchronized timer is an additional timer on 16xx.
> - * It is always running.
> - */
> -static inline unsigned long omap_32k_sync_timer_read(void)
> -{
> -	return omap_readl(TIMER_32K_SYNCHRONIZED);
> -}
> -
>  static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
>  {
>  	struct clock_event_device *evt = &clockevent_32k_timer;
> -- 
> 1.7.0.rc0.33.g7c3932
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-31 11:13 ` [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
@ 2010-04-06 21:37   ` Kevin Hilman
  2010-04-07  7:21     ` Felipe Balbi
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2010-04-06 21:37 UTC (permalink / raw)
  To: Felipe Balbi, Benoit Cousson; +Cc: Tony Lindgren, Linux OMAP Mailing List

Felipe Balbi <felipe.balbi@nokia.com> writes:

> Convert the omap32k clocksource driver into a platform_driver
> and while at that, also remove the ifdeferry around the code.
>
> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>

This looks mostly good to me.  One cosmetic request.

There is some standardized naming happening for devices based on
Benoits work of auto-generating hwmod data.  As part of this, this
device will now be called counter_32k instead of '32k sync timer'
since it's just a simple counter and nobody really knew what the 'sync'
was intended to mean.  To that end, renaming things to use counter_32k
instead of sync timer would be helpful.

[...]

>  
> +static struct resource omap_32k_resources[] = {
> +	{
> +		.start		= -EINVAL,	/* gets changed later */
> +		.end		= -EINVAL,	/* gets changed later */

It's more common to just not assign these and leave them as zero.

> +		.flags		= IORESOURCE_MEM,
> +	},
> +};

Kevin

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

* Re: [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-04-06 21:37   ` Kevin Hilman
@ 2010-04-07  7:21     ` Felipe Balbi
  2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
                         ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Felipe Balbi @ 2010-04-07  7:21 UTC (permalink / raw)
  To: ext Kevin Hilman
  Cc: Balbi Felipe (Nokia-D/Helsinki),
	Benoit Cousson, Tony Lindgren, Linux OMAP Mailing List

On Tue, Apr 06, 2010 at 11:37:08PM +0200, ext Kevin Hilman wrote:
>There is some standardized naming happening for devices based on
>Benoits work of auto-generating hwmod data.  As part of this, this
>device will now be called counter_32k instead of '32k sync timer'
>since it's just a simple counter and nobody really knew what the 'sync'
>was intended to mean.  To that end, renaming things to use counter_32k
>instead of sync timer would be helpful.

I'll do that soon.

>It's more common to just not assign these and leave them as zero.

will fix this too.

-- 
balbi

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

* [PATCH 1/3] omap: fix clocksource_32k to start from zero
  2010-04-07  7:21     ` Felipe Balbi
@ 2010-04-07  9:57       ` felipe.balbi
  2010-04-07 10:02         ` Felipe Balbi
  2010-04-22 23:49         ` [APPLIED] " Tony Lindgren
  2010-04-07  9:57       ` [PATCH 2/3] arm: omap1: remove dead code from timer32k.c felipe.balbi
  2010-04-07  9:57       ` [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver felipe.balbi
  2 siblings, 2 replies; 16+ messages in thread
From: felipe.balbi @ 2010-04-07  9:57 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Linux OMAP Mailing List, Aaro Koskinen

From: Aaro Koskinen <aaro.koskinen@nokia.com>

When the 32k sync timer is used for sched_clock(), it should count
time from the kernel boot (clocksource init) instead of the last HW
reset. Otherwise printk.time values will jump suddenly during the boot:

	[    0.000000] calling  omap2_clk_arch_init+0x0/0x138 @ 1
	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned -22 after 0 usecs
	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned with error code -22
	[    0.000000] calling  omap_init_clocksource_32k+0x0/0x98 @ 1
	[  508.697937] initcall omap_init_clocksource_32k+0x0/0x98 returned 0 after 0 usecs
	[  508.697967] calling  omap_init_devices+0x0/0x38 @ 1
	[  508.698425] initcall omap_init_devices+0x0/0x38 returned 0 after 0 usecs

This will confuse tools such as scripts/bootgraph.pl.

Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/plat-omap/common.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 088c1a0..01cbb48 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -100,10 +100,17 @@ EXPORT_SYMBOL(omap_get_var_config);
 
 #include <linux/clocksource.h>
 
+/*
+ * offset_32k holds the init time counter value. It is then subtracted
+ * from every counter read to achieve a counter that counts time from the
+ * kernel boot (needed for sched_clock()).
+ */
+static u32 offset_32k __read_mostly;
+
 #ifdef CONFIG_ARCH_OMAP16XX
 static cycle_t omap16xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
+	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
 }
 #else
 #define omap16xx_32k_read	NULL
@@ -112,7 +119,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2420
 static cycle_t omap2420_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2420_32k_read	NULL
@@ -121,7 +128,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP2430
 static cycle_t omap2430_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap2430_32k_read	NULL
@@ -130,7 +137,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP3
 static cycle_t omap34xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap34xx_32k_read	NULL
@@ -139,7 +146,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
 #ifdef CONFIG_ARCH_OMAP4
 static cycle_t omap44xx_32k_read(struct clocksource *cs)
 {
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
+	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
 }
 #else
 #define omap44xx_32k_read	NULL
@@ -227,6 +234,8 @@ static int __init omap_init_clocksource_32k(void)
 		clocksource_32k.mult = clocksource_hz2mult(32768,
 					    clocksource_32k.shift);
 
+		offset_32k = clocksource_32k.read(&clocksource_32k);
+
 		if (clocksource_register(&clocksource_32k))
 			printk(err, clocksource_32k.name);
 	}
-- 
1.7.0.rc0.33.g7c3932


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

* [PATCH 2/3] arm: omap1: remove dead code from timer32k.c
  2010-04-07  7:21     ` Felipe Balbi
  2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
@ 2010-04-07  9:57       ` felipe.balbi
  2010-04-22 23:49         ` [APPLIED] " Tony Lindgren
  2010-04-07  9:57       ` [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver felipe.balbi
  2 siblings, 1 reply; 16+ messages in thread
From: felipe.balbi @ 2010-04-07  9:57 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Linux OMAP Mailing List, Felipe Balbi

From: Felipe Balbi <felipe.balbi@nokia.com>

Trivial patch, no functional changes

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---
 arch/arm/mach-omap1/timer32k.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 9ad1185..20cfbcc 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -68,12 +68,6 @@ struct sys_timer omap_timer;
  * ---------------------------------------------------------------------------
  */
 
-#if defined(CONFIG_ARCH_OMAP16XX)
-#define TIMER_32K_SYNCHRONIZED		0xfffbc410
-#else
-#error OMAP 32KHz timer does not currently work on 15XX!
-#endif
-
 /* 16xx specific defines */
 #define OMAP1_32K_TIMER_BASE		0xfffb9000
 #define OMAP1_32K_TIMER_CR		0x08
@@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
 	.set_mode	= omap_32k_timer_set_mode,
 };
 
-/*
- * The 32KHz synchronized timer is an additional timer on 16xx.
- * It is always running.
- */
-static inline unsigned long omap_32k_sync_timer_read(void)
-{
-	return omap_readl(TIMER_32K_SYNCHRONIZED);
-}
-
 static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = &clockevent_32k_timer;
-- 
1.7.0.rc0.33.g7c3932


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

* [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver
  2010-04-07  7:21     ` Felipe Balbi
  2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
  2010-04-07  9:57       ` [PATCH 2/3] arm: omap1: remove dead code from timer32k.c felipe.balbi
@ 2010-04-07  9:57       ` felipe.balbi
  2010-04-07 16:08         ` Kevin Hilman
  2 siblings, 1 reply; 16+ messages in thread
From: felipe.balbi @ 2010-04-07  9:57 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: Linux OMAP Mailing List, Felipe Balbi

From: Felipe Balbi <felipe.balbi@nokia.com>

Convert the omap32k clocksource driver into a platform_driver
and while at that, also remove the ifdeferry around the code.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---
 arch/arm/mach-omap1/devices.c        |   24 ++++
 arch/arm/mach-omap2/clock2420_data.c |    2 +-
 arch/arm/mach-omap2/clock2430_data.c |    2 +-
 arch/arm/mach-omap2/clock3xxx_data.c |    2 +-
 arch/arm/mach-omap2/devices.c        |   35 +++++
 arch/arm/plat-omap/Makefile          |    4 +-
 arch/arm/plat-omap/common.c          |  158 ---------------------
 arch/arm/plat-omap/counter-32k.c     |  250 ++++++++++++++++++++++++++++++++++
 8 files changed, 314 insertions(+), 163 deletions(-)
 create mode 100644 arch/arm/plat-omap/counter-32k.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..4393b45 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -28,6 +28,29 @@
 
 /*-------------------------------------------------------------------------*/
 
+#define OMAP16XX_TIMER_32K_BASE		0xfffbc400
+
+static struct resource omap_32k_resources[] = {
+	{
+		.start		= OMAP16XX_TIMER_32K_BASE,
+		.end		= SZ_4K,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_32k_device = {
+	.name			= "omap-counter-32k",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(omap_32k_resources),
+	.resource		= omap_32k_resources,
+};
+
+static void omap_init_32k(void)
+{
+       if (cpu_is_omap16xx())
+	       (void) platform_device_register(&omap_32k_device);
+};
+
 #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
 
 #define	OMAP_RTC_BASE		0xfffb4800
@@ -295,6 +318,7 @@ static int __init omap1_init_devices(void)
 	 * in alphabetical order so they're easier to sort through.
 	 */
 
+	omap_init_32k();
 	omap_init_mbox();
 	omap_init_rtc();
 	omap_init_spi100k();
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index d932b14..a4747ad 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1806,7 +1806,7 @@ static struct omap_clk omap2420_clks[] = {
 	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_242X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
+	CLK("omap-counter-32k",	"ick",	&sync_32k_ick,	CK_242X),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
 	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
 	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 0438b6e..479ab53 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1900,7 +1900,7 @@ static struct omap_clk omap2430_clks[] = {
 	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
 	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
 	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X),
-	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
+	CLK("omap-counter-32k",	"ick",	&sync_32k_ick,	CK_243X),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
 	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
 	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index d5153b6..5d6f00d 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3414,7 +3414,7 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
 	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
 	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
-	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
+	CLK("omap-counter-32k",	"ick", &omap_32ksync_ick, CK_3XXX),
 	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
 	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
 	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 23e4d77..a403041 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -29,6 +29,40 @@
 
 #include "mux.h"
 
+static struct resource omap_32k_resources[] = {
+	{
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_32k_device = {
+	.name			= "omap-counter-32k",
+	.id			= -1,
+	.num_resources		= ARRAY_SIZE(omap_32k_resources),
+	.resource		= omap_32k_resources,
+};
+
+static void omap_init_32k(void)
+{
+	if (cpu_is_omap2420()) {
+		omap_32k_resources[0].start = OMAP2420_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP2420_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap2430()) {
+		omap_32k_resources[0].start = OMAP2430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP2430_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap34xx()) {
+		omap_32k_resources[0].start = OMAP3430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP3430_32KSYNCT_BASE + SZ_4K;
+	} else if (cpu_is_omap44xx()) {
+		omap_32k_resources[0].start = OMAP4430_32KSYNCT_BASE;
+		omap_32k_resources[0].end = OMAP4430_32KSYNCT_BASE + SZ_4K;
+	} else {	/* not supported */
+		return;
+	}
+
+	(void) platform_device_register(&omap_32k_device);
+};
+
 #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
 
 static struct resource cam_resources[] = {
@@ -794,6 +828,7 @@ static int __init omap2_init_devices(void)
 	 * in alphabetical order so they're easier to sort through.
 	 */
 	omap_hsmmc_reset();
+	omap_init_32k();
 	omap_init_camera();
 	omap_init_mbox();
 	omap_init_mcspi();
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 98f0191..11dfcf0 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
-	 usb.o fb.o io.o
+	 usb.o fb.o io.o counter-32k.o
 obj-m :=
 obj-n :=
 obj-  :=
@@ -30,4 +30,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
 # OMAP mailbox framework
 obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
 
-obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
\ No newline at end of file
+obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 01cbb48..4be635a 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -87,164 +87,6 @@ const void *omap_get_var_config(u16 tag, size_t *len)
 }
 EXPORT_SYMBOL(omap_get_var_config);
 
-/*
- * 32KHz clocksource ... always available, on pretty most chips except
- * OMAP 730 and 1510.  Other timers could be used as clocksources, with
- * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
- * but systems won't necessarily want to spend resources that way.
- */
-
-#define OMAP16XX_TIMER_32K_SYNCHRONIZED		0xfffbc410
-
-#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
-
-#include <linux/clocksource.h>
-
-/*
- * offset_32k holds the init time counter value. It is then subtracted
- * from every counter read to achieve a counter that counts time from the
- * kernel boot (needed for sched_clock()).
- */
-static u32 offset_32k __read_mostly;
-
-#ifdef CONFIG_ARCH_OMAP16XX
-static cycle_t omap16xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
-}
-#else
-#define omap16xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2420
-static cycle_t omap2420_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2420_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
-static cycle_t omap2430_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap2430_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-static cycle_t omap34xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap34xx_32k_read	NULL
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-static cycle_t omap44xx_32k_read(struct clocksource *cs)
-{
-	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
-}
-#else
-#define omap44xx_32k_read	NULL
-#endif
-
-/*
- * Kernel assumes that sched_clock can be called early but may not have
- * things ready yet.
- */
-static cycle_t omap_32k_read_dummy(struct clocksource *cs)
-{
-	return 0;
-}
-
-static struct clocksource clocksource_32k = {
-	.name		= "32k_counter",
-	.rating		= 250,
-	.read		= omap_32k_read_dummy,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= 10,
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Returns current time from boot in nsecs. It's OK for this to wrap
- * around for now, as it's just a relative time stamp.
- */
-unsigned long long sched_clock(void)
-{
-	return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
-				  clocksource_32k.mult, clocksource_32k.shift);
-}
-
-/**
- * read_persistent_clock -  Return time from a persistent clock.
- *
- * Reads the time from a source which isn't disabled during PM, the
- * 32k sync timer.  Convert the cycles elapsed since last read into
- * nsecs and adds to a monotonically increasing timespec.
- */
-static struct timespec persistent_ts;
-static cycles_t cycles, last_cycles;
-void read_persistent_clock(struct timespec *ts)
-{
-	unsigned long long nsecs;
-	cycles_t delta;
-	struct timespec *tsp = &persistent_ts;
-
-	last_cycles = cycles;
-	cycles = clocksource_32k.read(&clocksource_32k);
-	delta = cycles - last_cycles;
-
-	nsecs = clocksource_cyc2ns(delta,
-				   clocksource_32k.mult, clocksource_32k.shift);
-
-	timespec_add_ns(tsp, nsecs);
-	*ts = *tsp;
-}
-
-static int __init omap_init_clocksource_32k(void)
-{
-	static char err[] __initdata = KERN_ERR
-			"%s: can't register clocksource!\n";
-
-	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
-		struct clk *sync_32k_ick;
-
-		if (cpu_is_omap16xx())
-			clocksource_32k.read = omap16xx_32k_read;
-		else if (cpu_is_omap2420())
-			clocksource_32k.read = omap2420_32k_read;
-		else if (cpu_is_omap2430())
-			clocksource_32k.read = omap2430_32k_read;
-		else if (cpu_is_omap34xx())
-			clocksource_32k.read = omap34xx_32k_read;
-		else if (cpu_is_omap44xx())
-			clocksource_32k.read = omap44xx_32k_read;
-		else
-			return -ENODEV;
-
-		sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
-		if (sync_32k_ick)
-			clk_enable(sync_32k_ick);
-
-		clocksource_32k.mult = clocksource_hz2mult(32768,
-					    clocksource_32k.shift);
-
-		offset_32k = clocksource_32k.read(&clocksource_32k);
-
-		if (clocksource_register(&clocksource_32k))
-			printk(err, clocksource_32k.name);
-	}
-	return 0;
-}
-arch_initcall(omap_init_clocksource_32k);
-
-#endif	/* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
-
 /* Global address base setup code */
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
diff --git a/arch/arm/plat-omap/counter-32k.c b/arch/arm/plat-omap/counter-32k.c
new file mode 100644
index 0000000..fdb8a85
--- /dev/null
+++ b/arch/arm/plat-omap/counter-32k.c
@@ -0,0 +1,250 @@
+/*
+ * counter-32k.c -- OMAP 32k Sync Timer Clocksource Driver
+ *
+ * Copyright (C) 2005-2010 Tony Lindgren <tony@atomide.com>
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.com>
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * 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/kernel.h>
+#include <linux/time.h>
+#include <linux/clocksource.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+struct omap_counter_32k_device {
+	struct timespec		persistent_ts;
+	struct clocksource	cs;
+	cycles_t		cycles;
+	cycles_t		last_cycles;
+
+	struct device		*dev;
+	struct clk		*ick;
+	void __iomem		*base;
+
+	/*
+	 * offset_32k holds the init time counter value. It is then subtracted
+	 * from every counter read to achieve a counter that counts time from the
+	 * kernel boot (needed for sched_clock()).
+	 */
+	u32			offset_32k __read_mostly;
+};
+
+#define to_omap_32k(cs)	(container_of(cs, struct omap_counter_32k_device, cs))
+
+static struct omap_counter_32k_device	*thecs;
+
+static inline u32 omap_counter_32k_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_counter_32k_32k_read(struct clocksource *cs)
+{
+	struct omap_counter_32k_device	*omap = to_omap_32k(cs);
+
+	return omap_counter_32k_readl(omap->base, 0x10) - omap->offset_32k;
+}
+
+/*
+ * Returns current time from boot in nsecs. It's OK for this to wrap
+ * around for now, as it's just a relative time stamp.
+ */
+unsigned long long sched_clock(void)
+{
+	struct omap_counter_32k_device	*omap = thecs;
+
+	if (!omap)
+		return 0;
+
+	return clocksource_cyc2ns(omap->cs.read(&omap->cs),
+			omap->cs.mult, omap->cs.shift);
+}
+
+/**
+ * read_persistent_clock -  Return time from a persistent clock.
+ *
+ * Reads the time from a source which isn't disabled during PM, the
+ * 32k sync timer.  Convert the cycles elapsed since last read into
+ * nsecs and adds to a monotonically increasing timespec.
+ */
+void read_persistent_clock(struct timespec *ts)
+{
+	struct omap_counter_32k_device	*omap = thecs;
+	unsigned long long	nsecs;
+	cycles_t		delta;
+	struct timespec		*tsp;
+
+	if (!omap) {
+		ts->tv_sec = 0;
+		ts->tv_nsec = 0;
+		return;
+	}
+
+	tsp = &omap->persistent_ts;
+
+	omap->last_cycles = omap->cycles;
+	omap->cycles = omap->cs.read(&omap->cs);
+	delta = omap->cycles - omap->last_cycles;
+
+	nsecs = clocksource_cyc2ns(delta,
+			omap->cs.mult, omap->cs.shift);
+
+	timespec_add_ns(tsp, nsecs);
+	*ts = *tsp;
+}
+
+static int __init omap_counter_32k_probe(struct platform_device *pdev)
+{
+	struct omap_counter_32k_device		*omap;
+	struct resource			*res;
+	struct clk			*ick;
+
+	int				ret;
+
+	void __iomem			*base;
+
+	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
+	if (!omap) {
+		dev_dbg(&pdev->dev, "unable to allocate memory\n");
+		ret = -ENOMEM;
+		goto err0;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_dbg(&pdev->dev, "couldn't get resource\n");
+		ret = -ENODEV;
+		goto err1;
+	}
+
+	base = ioremap(res->start, resource_size(res));
+	if (!base) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
+	ick = clk_get(&pdev->dev, "ick");
+	if (IS_ERR(ick)) {
+		dev_dbg(&pdev->dev, "couldn't get clock\n");
+		ret = PTR_ERR(ick);
+		goto err3;
+	}
+
+	ret = clk_enable(ick);
+	if (ret) {
+		dev_dbg(&pdev->dev, "couldn't enable clock\n");
+		goto err4;
+	}
+
+	omap->base	= base;
+	omap->dev	= &pdev->dev;
+	omap->ick	= ick;
+
+	omap->cs.name	= "counter-32k";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_counter_32k_32k_read;
+	omap->cs.mask	= CLOCKSOURCE_MASK(32);
+	omap->cs.shift	= 10;
+	omap->cs.flags	= CLOCK_SOURCE_IS_CONTINUOUS;
+	omap->cs.mult	= clocksource_hz2mult(32768, omap->cs.shift);
+
+	platform_set_drvdata(pdev, omap);
+
+	ret = clocksource_register(&omap->cs);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to register clocksource\n");
+		goto err5;
+	}
+
+	/* initialize our offset */
+	omap->offset_32k	=  omap_counter_32k_32k_read(&omap->cs);
+
+	/*
+	 * REVISIT for now we need to keep a global static pointer
+	 * to this clocksource instance. Would it make any sense
+	 * to provide a get_clocksource() to fetch the clocksource
+	 * we just registered ?
+	 */
+	thecs = omap;
+
+	return 0;
+
+err5:
+	clk_disable(ick);
+
+err4:
+	clk_put(ick);
+
+err3:
+	iounmap(base);
+
+err2:
+err1:
+	kfree(omap);
+
+err0:
+	return ret;
+}
+
+static int __exit omap_counter_32k_remove(struct platform_device *pdev)
+{
+	struct omap_counter_32k_device	*omap = platform_get_drvdata(pdev);
+
+	clocksource_unregister(&omap->cs);
+	clk_disable(omap->ick);
+	clk_put(omap->ick);
+	iounmap(omap->base);
+	kfree(omap);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static void omap_counter_32k_shutdown(struct platform_device *pdev)
+{
+	struct omap_counter_32k_device	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_counter_32k_driver = {
+	.remove		= __exit_p(omap_counter_32k_remove),
+	.shutdown	= omap_counter_32k_shutdown,
+	.driver		= {
+		.name	= "omap-counter-32k",
+	},
+};
+
+static int __init omap_counter_32k_init(void)
+{
+	return platform_driver_probe(&omap_counter_32k_driver, omap_counter_32k_probe);
+}
+arch_initcall(omap_counter_32k_init);
+
+static void __exit omap_counter_32k_exit(void)
+{
+	platform_driver_unregister(&omap_counter_32k_driver);
+}
+module_exit(omap_counter_32k_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.0.rc0.33.g7c3932


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

* Re: [PATCH 1/3] omap: fix clocksource_32k to start from zero
  2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
@ 2010-04-07 10:02         ` Felipe Balbi
  2010-04-22 23:49         ` [APPLIED] " Tony Lindgren
  1 sibling, 0 replies; 16+ messages in thread
From: Felipe Balbi @ 2010-04-07 10:02 UTC (permalink / raw)
  To: Balbi Felipe (Nokia-D/Helsinki)
  Cc: Kevin Hilman, Linux OMAP Mailing List, Koskinen Aaro (Nokia-D/Helsinki)

Hi,

On Wed, Apr 07, 2010 at 11:57:22AM +0200, Balbi Felipe (Nokia-D/Helsinki) wrote:
>From: Aaro Koskinen <aaro.koskinen@nokia.com>
>
>When the 32k sync timer is used for sched_clock(), it should count
>time from the kernel boot (clocksource init) instead of the last HW
>reset. Otherwise printk.time values will jump suddenly during the boot:
>
>	[    0.000000] calling  omap2_clk_arch_init+0x0/0x138 @ 1
>	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned -22 after 0 usecs
>	[    0.000000] initcall omap2_clk_arch_init+0x0/0x138 returned with error code -22
>	[    0.000000] calling  omap_init_clocksource_32k+0x0/0x98 @ 1
>	[  508.697937] initcall omap_init_clocksource_32k+0x0/0x98 returned 0 after 0 usecs
>	[  508.697967] calling  omap_init_devices+0x0/0x38 @ 1
>	[  508.698425] initcall omap_init_devices+0x0/0x38 returned 0 after 0 usecs
>
>This will confuse tools such as scripts/bootgraph.pl.
>
>Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
>Acked-by: Kevin Hilman <khilman@deeprootsystems.com>

these 3 patches are also available at:

http://gitorious.org/usb/usb/commits/clksource

to pull in the patches use:

git pull git://gitorious.org/usb/usb.git clksource

-- 
balbi

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

* Re: [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver
  2010-04-07  9:57       ` [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver felipe.balbi
@ 2010-04-07 16:08         ` Kevin Hilman
  2010-04-07 17:34           ` Felipe Balbi
  0 siblings, 1 reply; 16+ messages in thread
From: Kevin Hilman @ 2010-04-07 16:08 UTC (permalink / raw)
  To: felipe.balbi; +Cc: Linux OMAP Mailing List

felipe.balbi@nokia.com writes:

> From: Felipe Balbi <felipe.balbi@nokia.com>
>
> Convert the omap32k clocksource driver into a platform_driver
> and while at that, also remove the ifdeferry around the code.
>
> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>

I'm OK with this for now.  Ideally, this would be further converted to
use hwmod + omap_device to automatcially created the platform_devices
for you.

Kevin

> ---
>  arch/arm/mach-omap1/devices.c        |   24 ++++
>  arch/arm/mach-omap2/clock2420_data.c |    2 +-
>  arch/arm/mach-omap2/clock2430_data.c |    2 +-
>  arch/arm/mach-omap2/clock3xxx_data.c |    2 +-
>  arch/arm/mach-omap2/devices.c        |   35 +++++
>  arch/arm/plat-omap/Makefile          |    4 +-
>  arch/arm/plat-omap/common.c          |  158 ---------------------
>  arch/arm/plat-omap/counter-32k.c     |  250 ++++++++++++++++++++++++++++++++++
>  8 files changed, 314 insertions(+), 163 deletions(-)
>  create mode 100644 arch/arm/plat-omap/counter-32k.c
>
> diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
> index 379100c..4393b45 100644
> --- a/arch/arm/mach-omap1/devices.c
> +++ b/arch/arm/mach-omap1/devices.c
> @@ -28,6 +28,29 @@
>  
>  /*-------------------------------------------------------------------------*/
>  
> +#define OMAP16XX_TIMER_32K_BASE		0xfffbc400
> +
> +static struct resource omap_32k_resources[] = {
> +	{
> +		.start		= OMAP16XX_TIMER_32K_BASE,
> +		.end		= SZ_4K,
> +		.flags		= IORESOURCE_MEM,
> +	},
> +};
> +
> +static struct platform_device omap_32k_device = {
> +	.name			= "omap-counter-32k",
> +	.id			= -1,
> +	.num_resources		= ARRAY_SIZE(omap_32k_resources),
> +	.resource		= omap_32k_resources,
> +};
> +
> +static void omap_init_32k(void)
> +{
> +       if (cpu_is_omap16xx())
> +	       (void) platform_device_register(&omap_32k_device);
> +};
> +
>  #if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE)
>  
>  #define	OMAP_RTC_BASE		0xfffb4800
> @@ -295,6 +318,7 @@ static int __init omap1_init_devices(void)
>  	 * in alphabetical order so they're easier to sort through.
>  	 */
>  
> +	omap_init_32k();
>  	omap_init_mbox();
>  	omap_init_rtc();
>  	omap_init_spi100k();
> diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
> index d932b14..a4747ad 100644
> --- a/arch/arm/mach-omap2/clock2420_data.c
> +++ b/arch/arm/mach-omap2/clock2420_data.c
> @@ -1806,7 +1806,7 @@ static struct omap_clk omap2420_clks[] = {
>  	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_242X),
>  	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_242X),
>  	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_242X),
> -	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_242X),
> +	CLK("omap-counter-32k",	"ick",	&sync_32k_ick,	CK_242X),
>  	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_242X),
>  	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_242X),
>  	CLK("omap24xxcam", "fck",	&cam_fck,	CK_242X),
> diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
> index 0438b6e..479ab53 100644
> --- a/arch/arm/mach-omap2/clock2430_data.c
> +++ b/arch/arm/mach-omap2/clock2430_data.c
> @@ -1900,7 +1900,7 @@ static struct omap_clk omap2430_clks[] = {
>  	CLK(NULL,	"gpios_fck",	&gpios_fck,	CK_243X),
>  	CLK("omap_wdt",	"ick",		&mpu_wdt_ick,	CK_243X),
>  	CLK("omap_wdt",	"fck",		&mpu_wdt_fck,	CK_243X),
> -	CLK(NULL,	"sync_32k_ick",	&sync_32k_ick,	CK_243X),
> +	CLK("omap-counter-32k",	"ick",	&sync_32k_ick,	CK_243X),
>  	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_243X),
>  	CLK(NULL,	"omapctrl_ick",	&omapctrl_ick,	CK_243X),
>  	CLK(NULL,	"icr_ick",	&icr_ick,	CK_243X),
> diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
> index d5153b6..5d6f00d 100644
> --- a/arch/arm/mach-omap2/clock3xxx_data.c
> +++ b/arch/arm/mach-omap2/clock3xxx_data.c
> @@ -3414,7 +3414,7 @@ static struct omap_clk omap3xxx_clks[] = {
>  	CLK("omap_wdt",	"ick",		&wdt2_ick,	CK_3XXX),
>  	CLK(NULL,	"wdt1_ick",	&wdt1_ick,	CK_3XXX),
>  	CLK(NULL,	"gpio1_ick",	&gpio1_ick,	CK_3XXX),
> -	CLK(NULL,	"omap_32ksync_ick", &omap_32ksync_ick, CK_3XXX),
> +	CLK("omap-counter-32k",	"ick", &omap_32ksync_ick, CK_3XXX),
>  	CLK(NULL,	"gpt12_ick",	&gpt12_ick,	CK_3XXX),
>  	CLK(NULL,	"gpt1_ick",	&gpt1_ick,	CK_3XXX),
>  	CLK(NULL,	"per_96m_fck",	&per_96m_fck,	CK_3XXX),
> diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
> index 23e4d77..a403041 100644
> --- a/arch/arm/mach-omap2/devices.c
> +++ b/arch/arm/mach-omap2/devices.c
> @@ -29,6 +29,40 @@
>  
>  #include "mux.h"
>  
> +static struct resource omap_32k_resources[] = {
> +	{
> +		.flags		= IORESOURCE_MEM,
> +	},
> +};
> +
> +static struct platform_device omap_32k_device = {
> +	.name			= "omap-counter-32k",
> +	.id			= -1,
> +	.num_resources		= ARRAY_SIZE(omap_32k_resources),
> +	.resource		= omap_32k_resources,
> +};
> +
> +static void omap_init_32k(void)
> +{
> +	if (cpu_is_omap2420()) {
> +		omap_32k_resources[0].start = OMAP2420_32KSYNCT_BASE;
> +		omap_32k_resources[0].end = OMAP2420_32KSYNCT_BASE + SZ_4K;
> +	} else if (cpu_is_omap2430()) {
> +		omap_32k_resources[0].start = OMAP2430_32KSYNCT_BASE;
> +		omap_32k_resources[0].end = OMAP2430_32KSYNCT_BASE + SZ_4K;
> +	} else if (cpu_is_omap34xx()) {
> +		omap_32k_resources[0].start = OMAP3430_32KSYNCT_BASE;
> +		omap_32k_resources[0].end = OMAP3430_32KSYNCT_BASE + SZ_4K;
> +	} else if (cpu_is_omap44xx()) {
> +		omap_32k_resources[0].start = OMAP4430_32KSYNCT_BASE;
> +		omap_32k_resources[0].end = OMAP4430_32KSYNCT_BASE + SZ_4K;
> +	} else {	/* not supported */
> +		return;
> +	}
> +
> +	(void) platform_device_register(&omap_32k_device);
> +};
> +
>  #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
>  
>  static struct resource cam_resources[] = {
> @@ -794,6 +828,7 @@ static int __init omap2_init_devices(void)
>  	 * in alphabetical order so they're easier to sort through.
>  	 */
>  	omap_hsmmc_reset();
> +	omap_init_32k();
>  	omap_init_camera();
>  	omap_init_mbox();
>  	omap_init_mcspi();
> diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
> index 98f0191..11dfcf0 100644
> --- a/arch/arm/plat-omap/Makefile
> +++ b/arch/arm/plat-omap/Makefile
> @@ -4,7 +4,7 @@
>  
>  # Common support
>  obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
> -	 usb.o fb.o io.o
> +	 usb.o fb.o io.o counter-32k.o
>  obj-m :=
>  obj-n :=
>  obj-  :=
> @@ -30,4 +30,4 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
>  # OMAP mailbox framework
>  obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox.o
>  
> -obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
> \ No newline at end of file
> +obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
> diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
> index 01cbb48..4be635a 100644
> --- a/arch/arm/plat-omap/common.c
> +++ b/arch/arm/plat-omap/common.c
> @@ -87,164 +87,6 @@ const void *omap_get_var_config(u16 tag, size_t *len)
>  }
>  EXPORT_SYMBOL(omap_get_var_config);
>  
> -/*
> - * 32KHz clocksource ... always available, on pretty most chips except
> - * OMAP 730 and 1510.  Other timers could be used as clocksources, with
> - * higher resolution in free-running counter modes (e.g. 12 MHz xtal),
> - * but systems won't necessarily want to spend resources that way.
> - */
> -
> -#define OMAP16XX_TIMER_32K_SYNCHRONIZED		0xfffbc410
> -
> -#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
> -
> -#include <linux/clocksource.h>
> -
> -/*
> - * offset_32k holds the init time counter value. It is then subtracted
> - * from every counter read to achieve a counter that counts time from the
> - * kernel boot (needed for sched_clock()).
> - */
> -static u32 offset_32k __read_mostly;
> -
> -#ifdef CONFIG_ARCH_OMAP16XX
> -static cycle_t omap16xx_32k_read(struct clocksource *cs)
> -{
> -	return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
> -}
> -#else
> -#define omap16xx_32k_read	NULL
> -#endif
> -
> -#ifdef CONFIG_ARCH_OMAP2420
> -static cycle_t omap2420_32k_read(struct clocksource *cs)
> -{
> -	return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
> -}
> -#else
> -#define omap2420_32k_read	NULL
> -#endif
> -
> -#ifdef CONFIG_ARCH_OMAP2430
> -static cycle_t omap2430_32k_read(struct clocksource *cs)
> -{
> -	return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
> -}
> -#else
> -#define omap2430_32k_read	NULL
> -#endif
> -
> -#ifdef CONFIG_ARCH_OMAP3
> -static cycle_t omap34xx_32k_read(struct clocksource *cs)
> -{
> -	return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
> -}
> -#else
> -#define omap34xx_32k_read	NULL
> -#endif
> -
> -#ifdef CONFIG_ARCH_OMAP4
> -static cycle_t omap44xx_32k_read(struct clocksource *cs)
> -{
> -	return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
> -}
> -#else
> -#define omap44xx_32k_read	NULL
> -#endif
> -
> -/*
> - * Kernel assumes that sched_clock can be called early but may not have
> - * things ready yet.
> - */
> -static cycle_t omap_32k_read_dummy(struct clocksource *cs)
> -{
> -	return 0;
> -}
> -
> -static struct clocksource clocksource_32k = {
> -	.name		= "32k_counter",
> -	.rating		= 250,
> -	.read		= omap_32k_read_dummy,
> -	.mask		= CLOCKSOURCE_MASK(32),
> -	.shift		= 10,
> -	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
> -};
> -
> -/*
> - * Returns current time from boot in nsecs. It's OK for this to wrap
> - * around for now, as it's just a relative time stamp.
> - */
> -unsigned long long sched_clock(void)
> -{
> -	return clocksource_cyc2ns(clocksource_32k.read(&clocksource_32k),
> -				  clocksource_32k.mult, clocksource_32k.shift);
> -}
> -
> -/**
> - * read_persistent_clock -  Return time from a persistent clock.
> - *
> - * Reads the time from a source which isn't disabled during PM, the
> - * 32k sync timer.  Convert the cycles elapsed since last read into
> - * nsecs and adds to a monotonically increasing timespec.
> - */
> -static struct timespec persistent_ts;
> -static cycles_t cycles, last_cycles;
> -void read_persistent_clock(struct timespec *ts)
> -{
> -	unsigned long long nsecs;
> -	cycles_t delta;
> -	struct timespec *tsp = &persistent_ts;
> -
> -	last_cycles = cycles;
> -	cycles = clocksource_32k.read(&clocksource_32k);
> -	delta = cycles - last_cycles;
> -
> -	nsecs = clocksource_cyc2ns(delta,
> -				   clocksource_32k.mult, clocksource_32k.shift);
> -
> -	timespec_add_ns(tsp, nsecs);
> -	*ts = *tsp;
> -}
> -
> -static int __init omap_init_clocksource_32k(void)
> -{
> -	static char err[] __initdata = KERN_ERR
> -			"%s: can't register clocksource!\n";
> -
> -	if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
> -		struct clk *sync_32k_ick;
> -
> -		if (cpu_is_omap16xx())
> -			clocksource_32k.read = omap16xx_32k_read;
> -		else if (cpu_is_omap2420())
> -			clocksource_32k.read = omap2420_32k_read;
> -		else if (cpu_is_omap2430())
> -			clocksource_32k.read = omap2430_32k_read;
> -		else if (cpu_is_omap34xx())
> -			clocksource_32k.read = omap34xx_32k_read;
> -		else if (cpu_is_omap44xx())
> -			clocksource_32k.read = omap44xx_32k_read;
> -		else
> -			return -ENODEV;
> -
> -		sync_32k_ick = clk_get(NULL, "omap_32ksync_ick");
> -		if (sync_32k_ick)
> -			clk_enable(sync_32k_ick);
> -
> -		clocksource_32k.mult = clocksource_hz2mult(32768,
> -					    clocksource_32k.shift);
> -
> -		offset_32k = clocksource_32k.read(&clocksource_32k);
> -
> -		if (clocksource_register(&clocksource_32k))
> -			printk(err, clocksource_32k.name);
> -	}
> -	return 0;
> -}
> -arch_initcall(omap_init_clocksource_32k);
> -
> -#endif	/* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
> -
>  /* Global address base setup code */
>  
>  #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
> diff --git a/arch/arm/plat-omap/counter-32k.c b/arch/arm/plat-omap/counter-32k.c
> new file mode 100644
> index 0000000..fdb8a85
> --- /dev/null
> +++ b/arch/arm/plat-omap/counter-32k.c
> @@ -0,0 +1,250 @@
> +/*
> + * counter-32k.c -- OMAP 32k Sync Timer Clocksource Driver
> + *
> + * Copyright (C) 2005-2010 Tony Lindgren <tony@atomide.com>
> + * Copyright (C) 2010 Nokia Corporation
> + * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.com>
> + * Copyright (C) 2009 Texas Instruments
> + * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
> + *
> + * 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/kernel.h>
> +#include <linux/time.h>
> +#include <linux/clocksource.h>
> +#include <linux/platform_device.h>
> +#include <linux/clk.h>
> +#include <linux/err.h>
> +
> +struct omap_counter_32k_device {
> +	struct timespec		persistent_ts;
> +	struct clocksource	cs;
> +	cycles_t		cycles;
> +	cycles_t		last_cycles;
> +
> +	struct device		*dev;
> +	struct clk		*ick;
> +	void __iomem		*base;
> +
> +	/*
> +	 * offset_32k holds the init time counter value. It is then subtracted
> +	 * from every counter read to achieve a counter that counts time from the
> +	 * kernel boot (needed for sched_clock()).
> +	 */
> +	u32			offset_32k __read_mostly;
> +};
> +
> +#define to_omap_32k(cs)	(container_of(cs, struct omap_counter_32k_device, cs))
> +
> +static struct omap_counter_32k_device	*thecs;
> +
> +static inline u32 omap_counter_32k_readl(const void __iomem *base, unsigned offset)
> +{
> +	return __raw_readl(base + offset);
> +}
> +
> +static cycle_t omap_counter_32k_32k_read(struct clocksource *cs)
> +{
> +	struct omap_counter_32k_device	*omap = to_omap_32k(cs);
> +
> +	return omap_counter_32k_readl(omap->base, 0x10) - omap->offset_32k;
> +}
> +
> +/*
> + * Returns current time from boot in nsecs. It's OK for this to wrap
> + * around for now, as it's just a relative time stamp.
> + */
> +unsigned long long sched_clock(void)
> +{
> +	struct omap_counter_32k_device	*omap = thecs;
> +
> +	if (!omap)
> +		return 0;
> +
> +	return clocksource_cyc2ns(omap->cs.read(&omap->cs),
> +			omap->cs.mult, omap->cs.shift);
> +}
> +
> +/**
> + * read_persistent_clock -  Return time from a persistent clock.
> + *
> + * Reads the time from a source which isn't disabled during PM, the
> + * 32k sync timer.  Convert the cycles elapsed since last read into
> + * nsecs and adds to a monotonically increasing timespec.
> + */
> +void read_persistent_clock(struct timespec *ts)
> +{
> +	struct omap_counter_32k_device	*omap = thecs;
> +	unsigned long long	nsecs;
> +	cycles_t		delta;
> +	struct timespec		*tsp;
> +
> +	if (!omap) {
> +		ts->tv_sec = 0;
> +		ts->tv_nsec = 0;
> +		return;
> +	}
> +
> +	tsp = &omap->persistent_ts;
> +
> +	omap->last_cycles = omap->cycles;
> +	omap->cycles = omap->cs.read(&omap->cs);
> +	delta = omap->cycles - omap->last_cycles;
> +
> +	nsecs = clocksource_cyc2ns(delta,
> +			omap->cs.mult, omap->cs.shift);
> +
> +	timespec_add_ns(tsp, nsecs);
> +	*ts = *tsp;
> +}
> +
> +static int __init omap_counter_32k_probe(struct platform_device *pdev)
> +{
> +	struct omap_counter_32k_device		*omap;
> +	struct resource			*res;
> +	struct clk			*ick;
> +
> +	int				ret;
> +
> +	void __iomem			*base;
> +
> +	omap = kzalloc(sizeof(*omap), GFP_KERNEL);
> +	if (!omap) {
> +		dev_dbg(&pdev->dev, "unable to allocate memory\n");
> +		ret = -ENOMEM;
> +		goto err0;
> +	}
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_dbg(&pdev->dev, "couldn't get resource\n");
> +		ret = -ENODEV;
> +		goto err1;
> +	}
> +
> +	base = ioremap(res->start, resource_size(res));
> +	if (!base) {
> +		dev_dbg(&pdev->dev, "ioremap failed\n");
> +		ret = -ENOMEM;
> +		goto err2;
> +	}
> +
> +	ick = clk_get(&pdev->dev, "ick");
> +	if (IS_ERR(ick)) {
> +		dev_dbg(&pdev->dev, "couldn't get clock\n");
> +		ret = PTR_ERR(ick);
> +		goto err3;
> +	}
> +
> +	ret = clk_enable(ick);
> +	if (ret) {
> +		dev_dbg(&pdev->dev, "couldn't enable clock\n");
> +		goto err4;
> +	}
> +
> +	omap->base	= base;
> +	omap->dev	= &pdev->dev;
> +	omap->ick	= ick;
> +
> +	omap->cs.name	= "counter-32k";
> +	omap->cs.rating	= 250;
> +	omap->cs.read	= omap_counter_32k_32k_read;
> +	omap->cs.mask	= CLOCKSOURCE_MASK(32);
> +	omap->cs.shift	= 10;
> +	omap->cs.flags	= CLOCK_SOURCE_IS_CONTINUOUS;
> +	omap->cs.mult	= clocksource_hz2mult(32768, omap->cs.shift);
> +
> +	platform_set_drvdata(pdev, omap);
> +
> +	ret = clocksource_register(&omap->cs);
> +	if (ret) {
> +		dev_dbg(&pdev->dev, "failed to register clocksource\n");
> +		goto err5;
> +	}
> +
> +	/* initialize our offset */
> +	omap->offset_32k	=  omap_counter_32k_32k_read(&omap->cs);
> +
> +	/*
> +	 * REVISIT for now we need to keep a global static pointer
> +	 * to this clocksource instance. Would it make any sense
> +	 * to provide a get_clocksource() to fetch the clocksource
> +	 * we just registered ?
> +	 */
> +	thecs = omap;
> +
> +	return 0;
> +
> +err5:
> +	clk_disable(ick);
> +
> +err4:
> +	clk_put(ick);
> +
> +err3:
> +	iounmap(base);
> +
> +err2:
> +err1:
> +	kfree(omap);
> +
> +err0:
> +	return ret;
> +}
> +
> +static int __exit omap_counter_32k_remove(struct platform_device *pdev)
> +{
> +	struct omap_counter_32k_device	*omap = platform_get_drvdata(pdev);
> +
> +	clocksource_unregister(&omap->cs);
> +	clk_disable(omap->ick);
> +	clk_put(omap->ick);
> +	iounmap(omap->base);
> +	kfree(omap);
> +	platform_set_drvdata(pdev, NULL);
> +
> +	return 0;
> +}
> +
> +static void omap_counter_32k_shutdown(struct platform_device *pdev)
> +{
> +	struct omap_counter_32k_device	*omap = platform_get_drvdata(pdev);
> +
> +	clk_disable(omap->ick);
> +}
> +
> +static struct platform_driver omap_counter_32k_driver = {
> +	.remove		= __exit_p(omap_counter_32k_remove),
> +	.shutdown	= omap_counter_32k_shutdown,
> +	.driver		= {
> +		.name	= "omap-counter-32k",
> +	},
> +};
> +
> +static int __init omap_counter_32k_init(void)
> +{
> +	return platform_driver_probe(&omap_counter_32k_driver, omap_counter_32k_probe);
> +}
> +arch_initcall(omap_counter_32k_init);
> +
> +static void __exit omap_counter_32k_exit(void)
> +{
> +	platform_driver_unregister(&omap_counter_32k_driver);
> +}
> +module_exit(omap_counter_32k_exit);
> +
> +MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.7.0.rc0.33.g7c3932

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

* Re: [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver
  2010-04-07 16:08         ` Kevin Hilman
@ 2010-04-07 17:34           ` Felipe Balbi
  2010-06-11 15:24             ` Shilimkar, Santosh
  0 siblings, 1 reply; 16+ messages in thread
From: Felipe Balbi @ 2010-04-07 17:34 UTC (permalink / raw)
  To: ext Kevin Hilman; +Cc: Balbi Felipe (Nokia-D/Helsinki), Linux OMAP Mailing List

On Wed, Apr 07, 2010 at 06:08:13PM +0200, ext Kevin Hilman wrote:
>felipe.balbi@nokia.com writes:
>
>> From: Felipe Balbi <felipe.balbi@nokia.com>
>>
>> Convert the omap32k clocksource driver into a platform_driver
>> and while at that, also remove the ifdeferry around the code.
>>
>> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
>
>I'm OK with this for now.  Ideally, this would be further converted to
>use hwmod + omap_device to automatcially created the platform_devices
>for you.

Yeah. I was asking Paul about it today. I can send as a follow up patch 
on next week.

-- 
balbi

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

* [APPLIED] [PATCH 1/3] omap: fix clocksource_32k to start from zero
  2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
  2010-04-07 10:02         ` Felipe Balbi
@ 2010-04-22 23:49         ` Tony Lindgren
  1 sibling, 0 replies; 16+ messages in thread
From: Tony Lindgren @ 2010-04-22 23:49 UTC (permalink / raw)
  To: linux-omap

This patch has been applied to the linux-omap
by youw fwiendly patch wobot.

Branch in linux-omap: omap-fixes

Initial commit ID (Likely to change): 135a57fa43f4f345eb281157d0d4e107b3c74d16

PatchWorks
http://patchwork.kernel.org/patch/90994/

Git (Likely to change, and takes a while to get mirrored)
http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=135a57fa43f4f345eb281157d0d4e107b3c74d16



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

* [APPLIED] [PATCH 2/3] arm: omap1: remove dead code from timer32k.c
  2010-04-07  9:57       ` [PATCH 2/3] arm: omap1: remove dead code from timer32k.c felipe.balbi
@ 2010-04-22 23:49         ` Tony Lindgren
  0 siblings, 0 replies; 16+ messages in thread
From: Tony Lindgren @ 2010-04-22 23:49 UTC (permalink / raw)
  To: linux-omap

This patch has been applied to the linux-omap
by youw fwiendly patch wobot.

Branch in linux-omap: omap-fixes

Initial commit ID (Likely to change): cb7085ea28c95bd7b55e5c37a7e6d3017dcdcc90

PatchWorks
http://patchwork.kernel.org/patch/90993/

Git (Likely to change, and takes a while to get mirrored)
http://git.kernel.org/?p=linux/kernel/git/tmlind/linux-omap-2.6.git;a=commit;h=cb7085ea28c95bd7b55e5c37a7e6d3017dcdcc90



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

* RE: [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver
  2010-04-07 17:34           ` Felipe Balbi
@ 2010-06-11 15:24             ` Shilimkar, Santosh
  0 siblings, 0 replies; 16+ messages in thread
From: Shilimkar, Santosh @ 2010-06-11 15:24 UTC (permalink / raw)
  To: felipe.balbi, ext Kevin Hilman; +Cc: Linux OMAP Mailing List

Felipe,
> -----Original Message-----
> From: linux-omap-owner@vger.kernel.org [mailto:linux-omap-owner@vger.kernel.org] On Behalf Of Felipe
> Balbi
> Sent: Wednesday, April 07, 2010 11:04 PM
> To: ext Kevin Hilman
> Cc: Balbi Felipe (Nokia-D/Helsinki); Linux OMAP Mailing List
> Subject: Re: [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver
> 
> On Wed, Apr 07, 2010 at 06:08:13PM +0200, ext Kevin Hilman wrote:
> >felipe.balbi@nokia.com writes:
> >
> >> From: Felipe Balbi <felipe.balbi@nokia.com>
> >>
> >> Convert the omap32k clocksource driver into a platform_driver
> >> and while at that, also remove the ifdeferry around the code.
> >>
> >> Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
> >
> >I'm OK with this for now.  Ideally, this would be further converted to
> >use hwmod + omap_device to automatcially created the platform_devices
> >for you.
> 
> Yeah. I was asking Paul about it today. I can send as a follow up patch
> on next week.
> 
Is there a newer version of this series already available/posted??
Sorry I missed it.

Regards
Santosh

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

end of thread, other threads:[~2010-06-11 15:24 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-31 11:13 [RFC/PATCH 0/3] 32k timer patches Felipe Balbi
2010-03-31 11:13 ` [RFC/PATCH 1/3] omap: fix clocksource_32k to start from zero Felipe Balbi
2010-03-31 11:13 ` [RFC/PATCH 2/3] arm: omap1: remove dead code from timer32k.c Felipe Balbi
2010-04-06 21:30   ` Kevin Hilman
2010-03-31 11:13 ` [RFC/PATCH 3/3] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
2010-04-06 21:37   ` Kevin Hilman
2010-04-07  7:21     ` Felipe Balbi
2010-04-07  9:57       ` [PATCH 1/3] omap: fix clocksource_32k to start from zero felipe.balbi
2010-04-07 10:02         ` Felipe Balbi
2010-04-22 23:49         ` [APPLIED] " Tony Lindgren
2010-04-07  9:57       ` [PATCH 2/3] arm: omap1: remove dead code from timer32k.c felipe.balbi
2010-04-22 23:49         ` [APPLIED] " Tony Lindgren
2010-04-07  9:57       ` [PATCH 3/3] arm: omap1/2/3/4: convert 32k-sync driver to a platform_driver felipe.balbi
2010-04-07 16:08         ` Kevin Hilman
2010-04-07 17:34           ` Felipe Balbi
2010-06-11 15:24             ` Shilimkar, Santosh

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