public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
@ 2010-03-23 12:12 Felipe Balbi
  2010-03-23 12:23 ` [PATCH v2] " Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-03-23 12:12 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.

Tested on N900.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---

this patch depends on Aaro's offset_32k patch:
http://marc.info/?l=linux-omap&m=126927727024322&w=2

 arch/arm/mach-omap1/devices.c    |   24 ++++
 arch/arm/mach-omap2/devices.c    |   38 ++++++
 arch/arm/plat-omap/Makefile      |    4 +-
 arch/arm/plat-omap/clocksource.c |  247 ++++++++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/common.c      |  158 ------------------------
 5 files changed, 311 insertions(+), 160 deletions(-)
 create mode 100644 arch/arm/plat-omap/clocksource.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..1265cad 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 resources omap_32k_resources[] = {
+	{
+		.start		= OMAP16XX_TIMER_32K_BASE,
+		.end		= SZ_4K,
+		.flags		= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device omap_32k_device = {
+	.name			= "omap-clksrc",
+	.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/devices.c b/arch/arm/mach-omap2/devices.c
index 23e4d77..8f8eb4f 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-clksrc",
+	.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..4630be3 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 clocksource.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/clocksource.c b/arch/arm/plat-omap/clocksource.c
new file mode 100644
index 0000000..e5381e5
--- /dev/null
+++ b/arch/arm/plat-omap/clocksource.c
@@ -0,0 +1,247 @@
+/*
+ * omap.c -- OMAP Clocksource Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.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_clksrc {
+	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_clksrc(cs)	(container_of(cs, struct omap_clksrc, cs))
+
+static struct omap_clksrc	*thecs;
+
+static inline u32 omap_clksrc_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_clksrc_32k_read(struct clocksource *cs)
+{
+	struct omap_clksrc	*omap = to_omap_clksrc(cs);
+
+	return omap_clksrc_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_clksrc	*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_clksrc	*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_clksrc_probe(struct platform_device *pdev)
+{
+	struct omap_clksrc		*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, "omap_32ksync_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	= "32k_counter";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_clksrc_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_clksrc_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_clksrc_remove(struct platform_device *pdev)
+{
+	struct omap_clksrc	*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_clksrc_shutdown(struct platform_device *pdev)
+{
+	struct omap_clksrc	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_clksrc_driver = {
+	.remove		= __exit_p(omap_clksrc_remove),
+	.shutdown	= omap_clksrc_shutdown,
+	.driver		= {
+		.name	= "omap-clksrc",
+	},
+};
+
+static int __init omap_clksrc_init(void)
+{
+	return platform_driver_probe(&omap_clksrc_driver, omap_clksrc_probe);
+}
+arch_initcall(omap_clksrc_init);
+
+static void __exit omap_clksrc_exit(void)
+{
+	platform_driver_unregister(&omap_clksrc_driver);
+}
+module_exit(omap_clksrc_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
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)
-- 
1.7.0.rc0.33.g7c3932


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

* [PATCH v2] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-23 12:12 [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
@ 2010-03-23 12:23 ` Felipe Balbi
  2010-03-23 13:29   ` [PATCH v3] " Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-03-23 12:23 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Aaro Koskinen, Felipe Balbi

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

Tested on N900. Compile tested with omap_h2_1610_defconfig.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---

this patch depends on Aaro's offset_32k patch:
http://marc.info/?l=linux-omap&m=126927727024322&w=2

Changes since v1:

. Aaro noted a few typos which I didn't catch before. Now fixed.

 arch/arm/mach-omap1/devices.c    |   24 ++++
 arch/arm/mach-omap2/devices.c    |   38 ++++++
 arch/arm/plat-omap/Makefile      |    4 +-
 arch/arm/plat-omap/clocksource.c |  247 ++++++++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/common.c      |  158 ------------------------
 5 files changed, 311 insertions(+), 160 deletions(-)
 create mode 100644 arch/arm/plat-omap/clocksource.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..acbf475 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-clksrc",
+	.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/devices.c b/arch/arm/mach-omap2/devices.c
index 23e4d77..8f8eb4f 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-clksrc",
+	.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..4630be3 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 clocksource.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/clocksource.c b/arch/arm/plat-omap/clocksource.c
new file mode 100644
index 0000000..e5381e5
--- /dev/null
+++ b/arch/arm/plat-omap/clocksource.c
@@ -0,0 +1,247 @@
+/*
+ * omap.c -- OMAP Clocksource Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.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_clksrc {
+	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_clksrc(cs)	(container_of(cs, struct omap_clksrc, cs))
+
+static struct omap_clksrc	*thecs;
+
+static inline u32 omap_clksrc_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_clksrc_32k_read(struct clocksource *cs)
+{
+	struct omap_clksrc	*omap = to_omap_clksrc(cs);
+
+	return omap_clksrc_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_clksrc	*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_clksrc	*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_clksrc_probe(struct platform_device *pdev)
+{
+	struct omap_clksrc		*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, "omap_32ksync_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	= "32k_counter";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_clksrc_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_clksrc_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_clksrc_remove(struct platform_device *pdev)
+{
+	struct omap_clksrc	*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_clksrc_shutdown(struct platform_device *pdev)
+{
+	struct omap_clksrc	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_clksrc_driver = {
+	.remove		= __exit_p(omap_clksrc_remove),
+	.shutdown	= omap_clksrc_shutdown,
+	.driver		= {
+		.name	= "omap-clksrc",
+	},
+};
+
+static int __init omap_clksrc_init(void)
+{
+	return platform_driver_probe(&omap_clksrc_driver, omap_clksrc_probe);
+}
+arch_initcall(omap_clksrc_init);
+
+static void __exit omap_clksrc_exit(void)
+{
+	platform_driver_unregister(&omap_clksrc_driver);
+}
+module_exit(omap_clksrc_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
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)
-- 
1.7.0.rc0.33.g7c3932


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

* [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-23 12:23 ` [PATCH v2] " Felipe Balbi
@ 2010-03-23 13:29   ` Felipe Balbi
  2010-03-23 13:42     ` [PATCH] arm: omap1/2/3/4: change sync_32k_ick to ick Felipe Balbi
  2010-03-23 18:07     ` [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver Kevin Hilman
  0 siblings, 2 replies; 12+ messages in thread
From: Felipe Balbi @ 2010-03-23 13:29 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>
---

this patch depends on Aaro's offset_32k patch:
http://marc.info/?l=linux-omap&m=126927727024322&w=2

Changes since v2:

. the clock name was wrong.

The device was still working, probably because bootloader
enables the clock.

 arch/arm/mach-omap1/devices.c    |   24 ++++
 arch/arm/mach-omap2/devices.c    |   38 ++++++
 arch/arm/plat-omap/Makefile      |    4 +-
 arch/arm/plat-omap/clocksource.c |  247 ++++++++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/common.c      |  158 ------------------------
 5 files changed, 311 insertions(+), 160 deletions(-)
 create mode 100644 arch/arm/plat-omap/clocksource.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..acbf475 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-clksrc",
+	.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/devices.c b/arch/arm/mach-omap2/devices.c
index 23e4d77..8f8eb4f 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-clksrc",
+	.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..4630be3 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 clocksource.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/clocksource.c b/arch/arm/plat-omap/clocksource.c
new file mode 100644
index 0000000..9a43b0c
--- /dev/null
+++ b/arch/arm/plat-omap/clocksource.c
@@ -0,0 +1,247 @@
+/*
+ * omap.c -- OMAP Clocksource Driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010 Felipe Balbi <me@felipebalbi.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_clksrc {
+	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_clksrc(cs)	(container_of(cs, struct omap_clksrc, cs))
+
+static struct omap_clksrc	*thecs;
+
+static inline u32 omap_clksrc_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_clksrc_32k_read(struct clocksource *cs)
+{
+	struct omap_clksrc	*omap = to_omap_clksrc(cs);
+
+	return omap_clksrc_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_clksrc	*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_clksrc	*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_clksrc_probe(struct platform_device *pdev)
+{
+	struct omap_clksrc		*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, "sync_32k_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	= "32k_counter";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_clksrc_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_clksrc_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_clksrc_remove(struct platform_device *pdev)
+{
+	struct omap_clksrc	*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_clksrc_shutdown(struct platform_device *pdev)
+{
+	struct omap_clksrc	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_clksrc_driver = {
+	.remove		= __exit_p(omap_clksrc_remove),
+	.shutdown	= omap_clksrc_shutdown,
+	.driver		= {
+		.name	= "omap-clksrc",
+	},
+};
+
+static int __init omap_clksrc_init(void)
+{
+	return platform_driver_probe(&omap_clksrc_driver, omap_clksrc_probe);
+}
+arch_initcall(omap_clksrc_init);
+
+static void __exit omap_clksrc_exit(void)
+{
+	platform_driver_unregister(&omap_clksrc_driver);
+}
+module_exit(omap_clksrc_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
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)
-- 
1.7.0.rc0.33.g7c3932


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

* [PATCH] arm: omap1/2/3/4: change sync_32k_ick to ick
  2010-03-23 13:29   ` [PATCH v3] " Felipe Balbi
@ 2010-03-23 13:42     ` Felipe Balbi
  2010-03-23 18:07     ` [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver Kevin Hilman
  1 sibling, 0 replies; 12+ messages in thread
From: Felipe Balbi @ 2010-03-23 13:42 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: Linux OMAP Mailing List, Felipe Balbi

Use clkdev and forget about clock names.

Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
---

and now make all the clocks with same name

 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/plat-omap/clocksource.c     |    2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index d932b14..0115853 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-clksrc",	"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..d2e1041 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-clksrc",	"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..6bf0f96 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-clksrc",	"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/plat-omap/clocksource.c b/arch/arm/plat-omap/clocksource.c
index 9a43b0c..13ae8da 100644
--- a/arch/arm/plat-omap/clocksource.c
+++ b/arch/arm/plat-omap/clocksource.c
@@ -139,7 +139,7 @@ static int __init omap_clksrc_probe(struct platform_device *pdev)
 		goto err2;
 	}
 
-	ick = clk_get(&pdev->dev, "sync_32k_ick");
+	ick = clk_get(&pdev->dev, "ick");
 	if (IS_ERR(ick)) {
 		dev_dbg(&pdev->dev, "couldn't get clock\n");
 		ret = PTR_ERR(ick);
-- 
1.7.0.rc0.33.g7c3932


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

* Re: [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-23 13:29   ` [PATCH v3] " Felipe Balbi
  2010-03-23 13:42     ` [PATCH] arm: omap1/2/3/4: change sync_32k_ick to ick Felipe Balbi
@ 2010-03-23 18:07     ` Kevin Hilman
  2010-03-24  6:34       ` Felipe Balbi
  1 sibling, 1 reply; 12+ messages in thread
From: Kevin Hilman @ 2010-03-23 18:07 UTC (permalink / raw)
  To: Felipe Balbi; +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>

Looks like a good direction, but it still is rather tied to the 32k
sync timer.  We also have the ability to use a GPtimer as a
clocksource (see the clocksource register in timer-gp.c.)  By default,
we are always using the 32k timer for PM reasons, but we need the ability
to register any timer as clocksource.  This problably means just splitting
a little more the driver part and the device part.

Also, the new clocksource.c file should reference from whence it came.
A lot of that was copy/pasted from the older code so copyrights/author
credits should follow.

Kevin

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

* Re: [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-23 18:07     ` [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver Kevin Hilman
@ 2010-03-24  6:34       ` Felipe Balbi
  2010-03-24  6:54         ` Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-03-24  6:34 UTC (permalink / raw)
  To: ext Kevin Hilman
  Cc: Balbi Felipe (Nokia-D/Helsinki), Tony Lindgren,
	Linux OMAP Mailing List

On Tue, Mar 23, 2010 at 07:07:31PM +0100, ext Kevin Hilman wrote:
>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>
>
>Looks like a good direction, but it still is rather tied to the 32k
>sync timer.  We also have the ability to use a GPtimer as a
>clocksource (see the clocksource register in timer-gp.c.)  By default,
>we are always using the 32k timer for PM reasons, but we need the ability
>to register any timer as clocksource.  This problably means just splitting
>a little more the driver part and the device part.
>
>Also, the new clocksource.c file should reference from whence it came.
>A lot of that was copy/pasted from the older code so copyrights/author
>credits should follow.

all add back the credits, missed that sorry but I believe the gp timer 
part is subject to another patch, no ? Otherwise this will start to 
become one huge unreviewable patch.

-- 
balbi

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

* Re: [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-24  6:34       ` Felipe Balbi
@ 2010-03-24  6:54         ` Felipe Balbi
  2010-03-26  7:21           ` [PATCH] " Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-03-24  6:54 UTC (permalink / raw)
  To: Balbi Felipe (Nokia-D/Helsinki)
  Cc: ext Kevin Hilman, Tony Lindgren, Linux OMAP Mailing List

Hi,

On Wed, Mar 24, 2010 at 07:34:28AM +0100, Balbi Felipe (Nokia-D/Helsinki) wrote:
>all add back the credits, missed that sorry but I believe the gp timer
>part is subject to another patch, no ? Otherwise this will start to
>become one huge unreviewable patch.

and btw, why don't we just register all clocksources and let kernel 
select the best one for us ?

-- 
balbi

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

* [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-24  6:54         ` Felipe Balbi
@ 2010-03-26  7:21           ` Felipe Balbi
  2010-04-05 22:57             ` Kevin Hilman
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-03-26  7:21 UTC (permalink / raw)
  To: Linux OMAP Mailing List, Tony Lindgren; +Cc: 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>
---

Amended both patches into one since there were
different clock names before. Now the change
will still be bisectable.

 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/clocksource.c     |  250 ++++++++++++++++++++++++++++++++++
 arch/arm/plat-omap/common.c          |  158 ---------------------
 8 files changed, 317 insertions(+), 163 deletions(-)
 create mode 100644 arch/arm/plat-omap/clocksource.c

diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c..acbf475 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-clksrc",
+	.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..0115853 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-clksrc",	"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..d2e1041 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-clksrc",	"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..6bf0f96 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-clksrc",	"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..8f8eb4f 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-clksrc",
+	.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..4630be3 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 clocksource.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/clocksource.c b/arch/arm/plat-omap/clocksource.c
new file mode 100644
index 0000000..bf5842a
--- /dev/null
+++ b/arch/arm/plat-omap/clocksource.c
@@ -0,0 +1,250 @@
+/*
+ * clocksource.c -- OMAP 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_clksrc {
+	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_clksrc(cs)	(container_of(cs, struct omap_clksrc, cs))
+
+static struct omap_clksrc	*thecs;
+
+static inline u32 omap_clksrc_readl(const void __iomem *base, unsigned offset)
+{
+	return __raw_readl(base + offset);
+}
+
+static cycle_t omap_clksrc_32k_read(struct clocksource *cs)
+{
+	struct omap_clksrc	*omap = to_omap_clksrc(cs);
+
+	return omap_clksrc_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_clksrc	*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_clksrc	*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_clksrc_probe(struct platform_device *pdev)
+{
+	struct omap_clksrc		*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	= "32k_counter";
+	omap->cs.rating	= 250;
+	omap->cs.read	= omap_clksrc_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_clksrc_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_clksrc_remove(struct platform_device *pdev)
+{
+	struct omap_clksrc	*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_clksrc_shutdown(struct platform_device *pdev)
+{
+	struct omap_clksrc	*omap = platform_get_drvdata(pdev);
+
+	clk_disable(omap->ick);
+}
+
+static struct platform_driver omap_clksrc_driver = {
+	.remove		= __exit_p(omap_clksrc_remove),
+	.shutdown	= omap_clksrc_shutdown,
+	.driver		= {
+		.name	= "omap-clksrc",
+	},
+};
+
+static int __init omap_clksrc_init(void)
+{
+	return platform_driver_probe(&omap_clksrc_driver, omap_clksrc_probe);
+}
+arch_initcall(omap_clksrc_init);
+
+static void __exit omap_clksrc_exit(void)
+{
+	platform_driver_unregister(&omap_clksrc_driver);
+}
+module_exit(omap_clksrc_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_LICENSE("GPL v2");
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)
-- 
1.7.0.rc0.33.g7c3932


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

* Re: [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-03-26  7:21           ` [PATCH] " Felipe Balbi
@ 2010-04-05 22:57             ` Kevin Hilman
  2010-04-06  6:38               ` Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Kevin Hilman @ 2010-04-05 22:57 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: Linux OMAP Mailing List, Tony Lindgren

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>
> ---
>
> Amended both patches into one since there were
> different clock names before. Now the change
> will still be bisectable.


What' you've created is not a generic clocksource driver but one that
can only work with the 32k sync timer.

If you're going to create a generic driver, it should be generic
enough to work with any timer source: 32k, timer GP, off-chip RTC,
etc.  To do this, it would need a generic read function passed in with
the platform_device.

It would also need a more generic way of handling clock names and
frequencies.  Currently the clock rate is hard-coded to 32kHz.
clk_get_rate() should be used in a generic driver.

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        |   38 +++++
>  arch/arm/plat-omap/Makefile          |    4 +-
>  arch/arm/plat-omap/clocksource.c     |  250 ++++++++++++++++++++++++++++++++++
>  arch/arm/plat-omap/common.c          |  158 ---------------------
>  8 files changed, 317 insertions(+), 163 deletions(-)
>  create mode 100644 arch/arm/plat-omap/clocksource.c
>
> diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
> index 379100c..acbf475 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-clksrc",
> +	.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..0115853 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-clksrc",	"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..d2e1041 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-clksrc",	"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..6bf0f96 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-clksrc",	"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..8f8eb4f 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-clksrc",
> +	.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..4630be3 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 clocksource.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/clocksource.c b/arch/arm/plat-omap/clocksource.c
> new file mode 100644
> index 0000000..bf5842a
> --- /dev/null
> +++ b/arch/arm/plat-omap/clocksource.c
> @@ -0,0 +1,250 @@
> +/*
> + * clocksource.c -- OMAP 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_clksrc {
> +	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_clksrc(cs)	(container_of(cs, struct omap_clksrc, cs))
> +
> +static struct omap_clksrc	*thecs;
> +
> +static inline u32 omap_clksrc_readl(const void __iomem *base, unsigned offset)
> +{
> +	return __raw_readl(base + offset);
> +}
> +
> +static cycle_t omap_clksrc_32k_read(struct clocksource *cs)
> +{
> +	struct omap_clksrc	*omap = to_omap_clksrc(cs);
> +
> +	return omap_clksrc_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_clksrc	*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_clksrc	*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_clksrc_probe(struct platform_device *pdev)
> +{
> +	struct omap_clksrc		*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	= "32k_counter";
> +	omap->cs.rating	= 250;
> +	omap->cs.read	= omap_clksrc_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_clksrc_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_clksrc_remove(struct platform_device *pdev)
> +{
> +	struct omap_clksrc	*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_clksrc_shutdown(struct platform_device *pdev)
> +{
> +	struct omap_clksrc	*omap = platform_get_drvdata(pdev);
> +
> +	clk_disable(omap->ick);
> +}
> +
> +static struct platform_driver omap_clksrc_driver = {
> +	.remove		= __exit_p(omap_clksrc_remove),
> +	.shutdown	= omap_clksrc_shutdown,
> +	.driver		= {
> +		.name	= "omap-clksrc",
> +	},
> +};
> +
> +static int __init omap_clksrc_init(void)
> +{
> +	return platform_driver_probe(&omap_clksrc_driver, omap_clksrc_probe);
> +}
> +arch_initcall(omap_clksrc_init);
> +
> +static void __exit omap_clksrc_exit(void)
> +{
> +	platform_driver_unregister(&omap_clksrc_driver);
> +}
> +module_exit(omap_clksrc_exit);
> +
> +MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
> +MODULE_LICENSE("GPL v2");
> 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)
> -- 
> 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] 12+ messages in thread

* Re: [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-04-05 22:57             ` Kevin Hilman
@ 2010-04-06  6:38               ` Felipe Balbi
  2010-04-06 14:43                 ` Kevin Hilman
  0 siblings, 1 reply; 12+ messages in thread
From: Felipe Balbi @ 2010-04-06  6:38 UTC (permalink / raw)
  To: ext Kevin Hilman
  Cc: Balbi Felipe (Nokia-D/Helsinki), Linux OMAP Mailing List,
	Tony Lindgren

Hi,

On Tue, Apr 06, 2010 at 12:57:16AM +0200, ext Kevin Hilman wrote:
>What' you've created is not a generic clocksource driver but one that
>can only work with the 32k sync timer.

so I achieved my goal, which was to convert *32k-sync timer* into a 
platform_driver.

>If you're going to create a generic driver, it should be generic
>enough to work with any timer source: 32k, timer GP, off-chip RTC,
>etc.  To do this, it would need a generic read function passed in with
>the platform_device.

yeah, I don't really see what you're trying to do. IMO we should just 
register all clocksources to the kernel but it doesn't mean they have to 
all come from the same platform_driver. The driver I wrote is for the 
32k-sync timer, gp timers, mpu-timer they all would have to be 
converted.

I really don't see the point in having all clocksources as one unique 
driver since the kernel is (or should be) smart enough to choose the 
best one for us at runtime.

If you really want one driver that would cope with all clocksources, be 
my guest, but IMO, that's not the way to go.

>It would also need a more generic way of handling clock names and
>frequencies.  Currently the clock rate is hard-coded to 32kHz.
>clk_get_rate() should be used in a generic driver.

but that's what 32k-sync timer uses, right ?

for anything else, then it would need more thinking.

-- 
balbi

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

* Re: [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-04-06  6:38               ` Felipe Balbi
@ 2010-04-06 14:43                 ` Kevin Hilman
  2010-04-06 15:26                   ` Felipe Balbi
  0 siblings, 1 reply; 12+ messages in thread
From: Kevin Hilman @ 2010-04-06 14:43 UTC (permalink / raw)
  To: felipe.balbi; +Cc: Linux OMAP Mailing List, Tony Lindgren

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

> Hi,
>
> On Tue, Apr 06, 2010 at 12:57:16AM +0200, ext Kevin Hilman wrote:
>>What' you've created is not a generic clocksource driver but one that
>>can only work with the 32k sync timer.
>
> so I achieved my goal, which was to convert *32k-sync timer* into a
> platform_driver.

OK, then I misunderstood your goal.  Based on $SUBJECT, I thought
you were trying to create a generic clocksource driver.

Sorry for the confusion,

Kevin


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

* Re: [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver
  2010-04-06 14:43                 ` Kevin Hilman
@ 2010-04-06 15:26                   ` Felipe Balbi
  0 siblings, 0 replies; 12+ messages in thread
From: Felipe Balbi @ 2010-04-06 15:26 UTC (permalink / raw)
  To: ext Kevin Hilman
  Cc: Balbi Felipe (Nokia-D/Helsinki), Linux OMAP Mailing List,
	Tony Lindgren

On Tue, Apr 06, 2010 at 04:43:52PM +0200, ext Kevin Hilman wrote:
>> so I achieved my goal, which was to convert *32k-sync timer* into a
>> platform_driver.
>
>OK, then I misunderstood your goal.  Based on $SUBJECT, I thought
>you were trying to create a generic clocksource driver.

ok, so it was my bad on the subject choice, maybe something like "arm: 
omap1/2/3/4: convert 32k-sync timer driver into a platform_driver" 
would've been better.

>Sorry for the confusion,

np. Sorry for the bad $SUBJECT

-- 
balbi

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

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

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-23 12:12 [PATCH] arm: omap1/2/3/4: convert clocksource to a platform_driver Felipe Balbi
2010-03-23 12:23 ` [PATCH v2] " Felipe Balbi
2010-03-23 13:29   ` [PATCH v3] " Felipe Balbi
2010-03-23 13:42     ` [PATCH] arm: omap1/2/3/4: change sync_32k_ick to ick Felipe Balbi
2010-03-23 18:07     ` [PATCH v3] arm: omap1/2/3/4: convert clocksource to a platform_driver Kevin Hilman
2010-03-24  6:34       ` Felipe Balbi
2010-03-24  6:54         ` Felipe Balbi
2010-03-26  7:21           ` [PATCH] " Felipe Balbi
2010-04-05 22:57             ` Kevin Hilman
2010-04-06  6:38               ` Felipe Balbi
2010-04-06 14:43                 ` Kevin Hilman
2010-04-06 15:26                   ` Felipe Balbi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox