linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] ARM: S5P: Add high resolution timer support
@ 2011-02-26  2:45 Sangbeom Kim
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch-set adds support for HRT(High Resolution Timer).
In Samsung SoCs, there is many HRT timer sources.
PWM Timer, System Timer, MCT, RTC can be used for that.
In this patches, Only support PWM Timer.
But All kind of pwm timer can be used for clock source.
This patch is tested on SMDKC110, SMDK6450.
APM is only tested on SMDKC110.
Next version will support System Timer, RTC, MCT.

[PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
[PATCH 2/3] ARM: S5P: Update machine initialization for HRT
[PATCH 3/3] ARM: S5P: Update defconfig for HRT support

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26  2:45 [PATCH 0/3] ARM: S5P: Add high resolution timer support Sangbeom Kim
@ 2011-02-26  2:45 ` Sangbeom Kim
  2011-02-26  4:31   ` Kyungmin Park
                     ` (2 more replies)
  2011-02-26  2:45 ` [PATCH 2/3] ARM: S5P: Update machine initialization " Sangbeom Kim
  2011-02-26  2:45 ` [PATCH 3/3] ARM: S5P: Update defconfig for HRT support Sangbeom Kim
  2 siblings, 3 replies; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds support HR-Timer(High Resolution Timer) and dynamic
tick system for S5P SoCs. There are many clock sources for HR-Timer
on S5P SoCs. The PWM timer, RTC, System Timer, and MCT can be used
for clock source.
This patch can only support PWM timer for clocksource of
S5P64x0 and S5PV210.

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/plat-s5p/Makefile                |    1 +
 arch/arm/plat-s5p/include/plat/s5p-time.h |   37 +++
 arch/arm/plat-s5p/s5p-time.c              |  395 +++++++++++++++++++++++++++++
 3 files changed, 433 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-s5p/include/plat/s5p-time.h
 create mode 100644 arch/arm/plat-s5p/s5p-time.c

diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 4bd5cf9..3b8cc2f 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_S5P_GPIO_INT)	+= irq-gpioint.o
 obj-$(CONFIG_S5P_SYSTEM_MMU)	+= sysmmu.o
 obj-$(CONFIG_PM)		+= pm.o
 obj-$(CONFIG_PM)		+= irq-pm.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS) += s5p-time.o
 
 # devices
 
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
new file mode 100644
index 0000000..e478f0c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * Header file for s5p time support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_S5P_TIME_H
+#define __ASM_PLAT_S5P_TIME_H __FILE__
+
+/* S5P HR-Timer Clock mode */
+enum s5p_timer_mode {
+	S5P_PWM0,
+	S5P_PWM1,
+	S5P_PWM2,
+	S5P_PWM3,
+	S5P_PWM4,
+};
+
+struct s5p_timer_source {
+	unsigned int event_id;
+	unsigned int source_id;
+};
+
+#define TCNT_MAX		0xffffffff
+#define NON_PERIODIC		0
+#define PERIODIC		1
+
+extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
+					enum s5p_timer_mode source);
+extern	struct sys_timer s5p_timer;
+#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
new file mode 100644
index 0000000..4691728
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p-time.c
@@ -0,0 +1,395 @@
+/* linux/arch/arm/plat-s5p/s5p-time.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P - Common hr-timer support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+
+#include <asm/smp_twd.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/map.h>
+#include <plat/regs-timer.h>
+#include <plat/s5p-time.h>
+
+static struct clk *tin_event;
+static struct clk *tin_source;
+static struct clk *tdiv_event;
+static struct clk *tdiv_source;
+static struct clk *timerclk;
+static struct s5p_timer_source timer_source;
+static unsigned long clock_count_per_tick;
+static void s5p_timer_resume(void);
+
+static void s5p_time_stop(enum s5p_timer_mode mode)
+{
+	unsigned long tcon;
+
+	tcon = __raw_readl(S3C2410_TCON);
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon &= ~S3C2410_TCON_T0START;
+		break;
+
+	case S5P_PWM1:
+		tcon &= ~S3C2410_TCON_T1START;
+		break;
+
+	case S5P_PWM2:
+		tcon &= ~S3C2410_TCON_T2START;
+		break;
+
+	case S5P_PWM3:
+		tcon &= ~S3C2410_TCON_T3START;
+		break;
+
+	case S5P_PWM4:
+		tcon &= ~S3C2410_TCON_T4START;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", mode);
+		break;
+	}
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
+{
+	unsigned long tcon;
+
+	tcon = __raw_readl(S3C2410_TCON);
+
+	tcnt--;
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon &= ~(0x0f << 0);
+		tcon |= S3C2410_TCON_T0MANUALUPD;
+		break;
+
+	case S5P_PWM1:
+		tcon &= ~(0x0f << 8);
+		tcon |= S3C2410_TCON_T1MANUALUPD;
+		break;
+
+	case S5P_PWM2:
+		tcon &= ~(0x0f << 0x0c);
+		tcon |= S3C2410_TCON_T2MANUALUPD;
+		break;
+
+	case S5P_PWM3:
+		tcon &= ~(0xf << 0x10);
+		tcon |= S3C2410_TCON_T3MANUALUPD;
+		break;
+
+	case S5P_PWM4:
+		tcon &= ~(7 << 0x14);
+		tcon |= S3C2410_TCON_T4MANUALUPD;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", mode);
+		break;
+	}
+
+	__raw_writel(tcnt, S3C2410_TCNTB(mode));
+	__raw_writel(tcnt, S3C2410_TCMPB(mode));
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
+{
+	unsigned long tcon;
+
+	tcon  = __raw_readl(S3C2410_TCON);
+
+	switch (mode) {
+	case S5P_PWM0:
+		tcon |= S3C2410_TCON_T0START;
+		tcon &= ~S3C2410_TCON_T0MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T0RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T0RELOAD;
+		break;
+
+	case S5P_PWM1:
+		tcon |= S3C2410_TCON_T1START;
+		tcon &= ~S3C2410_TCON_T1MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T1RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T1RELOAD;
+		break;
+
+	case S5P_PWM2:
+		tcon |= S3C2410_TCON_T2START;
+		tcon &= ~S3C2410_TCON_T2MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T2RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T2RELOAD;
+		break;
+
+	case S5P_PWM3:
+		tcon |= S3C2410_TCON_T3START;
+		tcon &= ~S3C2410_TCON_T3MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T3RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T3RELOAD;
+		break;
+
+	case S5P_PWM4:
+		tcon |= S3C2410_TCON_T4START;
+		tcon &= ~S3C2410_TCON_T4MANUALUPD;
+
+		if (periodic)
+			tcon |= S3C2410_TCON_T4RELOAD;
+		else
+			tcon &= ~S3C2410_TCON_T4RELOAD;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", mode);
+		break;
+	}
+	__raw_writel(tcon, S3C2410_TCON);
+}
+
+static int s5p_set_next_event(unsigned long cycles,
+				struct clock_event_device *evt)
+{
+	s5p_time_setup(timer_source.event_id, cycles);
+	s5p_time_start(timer_source.event_id, NON_PERIODIC);
+
+	return 0;
+}
+
+static void s5p_set_mode(enum clock_event_mode mode,
+				struct clock_event_device *evt)
+{
+
+	s5p_time_stop(timer_source.event_id);
+
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+		s5p_time_start(timer_source.event_id, PERIODIC);
+		break;
+
+	case CLOCK_EVT_MODE_ONESHOT:
+		break;
+
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		break;
+
+	case CLOCK_EVT_MODE_RESUME:
+		s5p_timer_resume();
+		break;
+	}
+}
+
+static void s5p_timer_resume(void)
+{
+	/* event timer restart */
+	s5p_time_setup(timer_source.event_id, clock_count_per_tick);
+	s5p_time_start(timer_source.event_id, PERIODIC);
+
+	/* source timer restart */
+	s5p_time_setup(timer_source.source_id, TCNT_MAX);
+	s5p_time_start(timer_source.source_id, PERIODIC);
+}
+
+void __init s5p_set_timer_source(enum s5p_timer_mode event,
+				 enum s5p_timer_mode source)
+{
+	timer_source.event_id = event;
+	timer_source.source_id = source;
+}
+
+static struct clock_event_device time_event_device = {
+	.name		= "s5p_event_timer",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 200,
+	.shift		= 32,
+	.set_next_event	= s5p_set_next_event,
+	.set_mode	= s5p_set_mode,
+};
+
+static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = &time_event_device;
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction s5p_clock_event_irq = {
+	.name		= "s5p_time_irq",
+	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+	.handler	= s5p_clock_event_isr,
+};
+
+static void s5p_clockevent_init(void)
+{
+	unsigned long pclk;
+	unsigned long clock_rate;
+	unsigned int irq_number;
+	struct clk *tscaler;
+
+	pclk = clk_get_rate(timerclk);
+
+	tscaler = clk_get_parent(tdiv_event);
+
+	clk_set_rate(tscaler, pclk / 2);
+	clk_set_rate(tdiv_event, pclk / 2);
+	clk_set_parent(tin_event, tdiv_event);
+
+	clock_rate = clk_get_rate(tin_event);
+	clock_count_per_tick = clock_rate / HZ;
+
+	time_event_device.mult =
+		div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
+	time_event_device.max_delta_ns =
+		clockevent_delta2ns(-1, &time_event_device);
+	time_event_device.min_delta_ns =
+		clockevent_delta2ns(1, &time_event_device);
+
+	time_event_device.cpumask = cpumask_of(0);
+	clockevents_register_device(&time_event_device);
+
+	irq_number = timer_source.event_id + IRQ_TIMER0;
+
+	setup_irq(irq_number, &s5p_clock_event_irq);
+}
+
+static cycle_t s5p_timer_read(struct clocksource *cs)
+{
+	unsigned long offset = 0;
+
+	switch (timer_source.source_id) {
+	case S5P_PWM0:
+	case S5P_PWM1:
+	case S5P_PWM2:
+	case S5P_PWM3:
+		offset = (timer_source.source_id * 0x0c) + 0x14;
+	case S5P_PWM4:
+		offset = 0x40;
+		break;
+
+	default:
+		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+		return 0;
+	}
+
+	return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
+}
+
+struct clocksource time_clocksource = {
+	.name		= "s5p_clocksource_timer",
+	.rating		= 250,
+	.read		= s5p_timer_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static void s5p_clocksource_init(void)
+{
+	unsigned long pclk;
+	unsigned long clock_rate;
+
+	pclk = clk_get_rate(timerclk);
+
+	clk_set_rate(tdiv_source, pclk / 2);
+	clk_set_parent(tin_source, tdiv_source);
+
+	clock_rate = clk_get_rate(tin_source);
+
+	s5p_time_setup(timer_source.source_id, TCNT_MAX);
+	s5p_time_start(timer_source.source_id, PERIODIC);
+
+	if (clocksource_register_hz(&time_clocksource, clock_rate))
+		panic("%s: can't register clocksource\n", time_clocksource.name);
+}
+
+static void __init s5p_timer_resources(void)
+{
+	struct platform_device tmpdev;
+
+	tmpdev.dev.bus = &platform_bus_type;
+
+	timerclk = clk_get(NULL, "timers");
+	if (IS_ERR(timerclk))
+		panic("failed to get timers clock for system timer");
+
+	clk_enable(timerclk);
+
+	tmpdev.id = timer_source.event_id;
+	tin_event = clk_get(&tmpdev.dev, "pwm-tin");
+	if (IS_ERR(tin_event)) {
+		clk_put(tin_event);
+		panic("failed to get pwm-tin2 clock for system timer");
+	}
+
+	tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
+	if (IS_ERR(tdiv_event)) {
+		clk_put(tdiv_event);
+		panic("failed to get pwm-tdiv2 clock for system timer");
+	}
+
+	clk_enable(tin_event);
+
+	tmpdev.id = timer_source.source_id;
+	tin_source = clk_get(&tmpdev.dev, "pwm-tin");
+	if (IS_ERR(tin_source)) {
+		clk_put(tin_source);
+		panic("failed to get pwm-tin4 clock for system timer");
+	}
+
+	tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
+	if (IS_ERR(tdiv_source)) {
+		clk_put(tdiv_source);
+		panic("failed to get pwm-tdiv4 clock for system timer");
+	}
+
+	clk_enable(tin_source);
+}
+
+static void __init s5p_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+	twd_base = S5P_VA_TWD;
+#endif
+
+	s5p_timer_resources();
+	s5p_clockevent_init();
+	s5p_clocksource_init();
+}
+
+struct sys_timer s5p_timer = {
+	.init		= s5p_timer_init,
+};
-- 
1.7.1

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

* [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
  2011-02-26  2:45 [PATCH 0/3] ARM: S5P: Add high resolution timer support Sangbeom Kim
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
@ 2011-02-26  2:45 ` Sangbeom Kim
  2011-02-26  4:27   ` Kyungmin Park
  2011-02-26  2:45 ` [PATCH 3/3] ARM: S5P: Update defconfig for HRT support Sangbeom Kim
  2 siblings, 1 reply; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch update mach-s5p64x0 and mach-s5pv210
machine  initialization for hrt support

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/mach-s5p64x0/mach-smdk6440.c |    4 +++-
 arch/arm/mach-s5p64x0/mach-smdk6450.c |    4 +++-
 arch/arm/mach-s5pv210/mach-aquila.c   |    4 +++-
 arch/arm/mach-s5pv210/mach-goni.c     |    4 +++-
 arch/arm/mach-s5pv210/mach-smdkc110.c |    4 +++-
 arch/arm/mach-s5pv210/mach-smdkv210.c |    4 +++-
 arch/arm/mach-s5pv210/mach-torbreck.c |    4 +++-
 7 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index e5beb84..f967736 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -43,6 +43,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <plat/ts.h>
+#include <plat/s5p-time.h>
 
 #define SMDK6440_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
 				S3C2410_UCON_RXILEVEL |		\
@@ -136,6 +137,7 @@ static void __init smdk6440_map_io(void)
 	s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
 	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdk6440_machine_init(void)
@@ -159,5 +161,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
 	.init_irq	= s5p6440_init_irq,
 	.map_io		= smdk6440_map_io,
 	.init_machine	= smdk6440_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 3a20de0..686ec56 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -43,6 +43,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <plat/ts.h>
+#include <plat/s5p-time.h>
 
 #define SMDK6450_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
 				S3C2410_UCON_RXILEVEL |		\
@@ -155,6 +156,7 @@ static void __init smdk6450_map_io(void)
 	s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
 	s3c24xx_init_clocks(19200000);
 	s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdk6450_machine_init(void)
@@ -178,5 +180,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
 	.init_irq	= s5p6450_init_irq,
 	.map_io		= smdk6450_map_io,
 	.init_machine	= smdk6450_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 557add4..fab84f3 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -39,6 +39,7 @@
 #include <plat/fb.h>
 #include <plat/fimc-core.h>
 #include <plat/sdhci.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define AQUILA_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -664,6 +665,7 @@ static void __init aquila_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init aquila_machine_init(void)
@@ -698,5 +700,5 @@ MACHINE_START(AQUILA, "Aquila")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= aquila_map_io,
 	.init_machine	= aquila_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 056f5c7..5eda4a1 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -45,6 +45,7 @@
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/clock.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define GONI_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -823,6 +824,7 @@ static void __init goni_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init goni_machine_init(void)
@@ -873,5 +875,5 @@ MACHINE_START(GONI, "GONI")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= goni_map_io,
 	.init_machine	= goni_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index ce11a02..f304383 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -30,6 +30,7 @@
 #include <plat/ata.h>
 #include <plat/iic.h>
 #include <plat/pm.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKC110_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -111,6 +112,7 @@ static void __init smdkc110_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdkc110_machine_init(void)
@@ -138,5 +140,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= smdkc110_map_io,
 	.init_machine	= smdkc110_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index bc9fdb5..41080bf 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -43,6 +43,7 @@
 #include <plat/keypad.h>
 #include <plat/pm.h>
 #include <plat/fb.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define SMDKV210_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -272,6 +273,7 @@ static void __init smdkv210_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init smdkv210_machine_init(void)
@@ -306,5 +308,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= smdkv210_map_io,
 	.init_machine	= smdkv210_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
index 043c938..b3516a1 100644
--- a/arch/arm/mach-s5pv210/mach-torbreck.c
+++ b/arch/arm/mach-s5pv210/mach-torbreck.c
@@ -27,6 +27,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/iic.h>
+#include <plat/s5p-time.h>
 
 /* Following are default values for UCON, ULCON and UFCON UART registers */
 #define TORBRECK_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
@@ -104,6 +105,7 @@ static void __init torbreck_map_io(void)
 	s5p_init_io(NULL, 0, S5P_VA_CHIPID);
 	s3c24xx_init_clocks(24000000);
 	s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
+	s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
 }
 
 static void __init torbreck_machine_init(void)
@@ -127,5 +129,5 @@ MACHINE_START(TORBRECK, "TORBRECK")
 	.init_irq	= s5pv210_init_irq,
 	.map_io		= torbreck_map_io,
 	.init_machine	= torbreck_machine_init,
-	.timer		= &s3c24xx_timer,
+	.timer		= &s5p_timer,
 MACHINE_END
-- 
1.7.1

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

* [PATCH 3/3] ARM: S5P: Update defconfig for HRT support
  2011-02-26  2:45 [PATCH 0/3] ARM: S5P: Add high resolution timer support Sangbeom Kim
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
  2011-02-26  2:45 ` [PATCH 2/3] ARM: S5P: Update machine initialization " Sangbeom Kim
@ 2011-02-26  2:45 ` Sangbeom Kim
  2 siblings, 0 replies; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-26  2:45 UTC (permalink / raw)
  To: linux-arm-kernel

This patch modify s5pv210_defconfig and s5p64x0_defconfig
for HRT support

Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
---
 arch/arm/Kconfig                   |    4 ++--
 arch/arm/configs/s5p64x0_defconfig |    2 ++
 arch/arm/configs/s5pv210_defconfig |    2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 166efa2..8b959e1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -715,7 +715,7 @@ config ARCH_S5P64X0
 	select GENERIC_GPIO
 	select HAVE_CLK
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-	select ARCH_USES_GETTIMEOFFSET
+	select GENERIC_CLOCKEVENTS
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	help
@@ -753,7 +753,7 @@ config ARCH_S5PV210
 	select HAVE_CLK
 	select ARM_L1_CACHE_SHIFT_6
 	select ARCH_HAS_CPUFREQ
-	select ARCH_USES_GETTIMEOFFSET
+	select GENERIC_CLOCKEVENTS
 	select HAVE_S3C2410_I2C if I2C
 	select HAVE_S3C_RTC if RTC_CLASS
 	select HAVE_S3C2410_WATCHDOG if WATCHDOG
diff --git a/arch/arm/configs/s5p64x0_defconfig b/arch/arm/configs/s5p64x0_defconfig
index 2993ecd..ad6b61b 100644
--- a/arch/arm/configs/s5p64x0_defconfig
+++ b/arch/arm/configs/s5p64x0_defconfig
@@ -10,6 +10,8 @@ CONFIG_S3C_BOOT_ERROR_RESET=y
 CONFIG_S3C_LOWLEVEL_UART_PORT=1
 CONFIG_MACH_SMDK6440=y
 CONFIG_MACH_SMDK6450=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_CPU_32v6K=y
 CONFIG_AEABI=y
 CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
index 0488a1e..fa98990 100644
--- a/arch/arm/configs/s5pv210_defconfig
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -13,6 +13,8 @@ CONFIG_MACH_AQUILA=y
 CONFIG_MACH_GONI=y
 CONFIG_MACH_SMDKC110=y
 CONFIG_MACH_SMDKV210=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_PREEMPT=y
 CONFIG_AEABI=y
-- 
1.7.1

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

* [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
  2011-02-26  2:45 ` [PATCH 2/3] ARM: S5P: Update machine initialization " Sangbeom Kim
@ 2011-02-26  4:27   ` Kyungmin Park
  2011-02-28  8:11     ` Sangbeom Kim
  0 siblings, 1 reply; 11+ messages in thread
From: Kyungmin Park @ 2011-02-26  4:27 UTC (permalink / raw)
  To: linux-arm-kernel

Acked-by: Kyungmin Park <kyungmin.park@samsung.com>

It's just curious. Are there any reason to use PWM2 & 4. Theoretically
it's possible to use PWM2 for other purpose as it's connected with
external devices such as haptic or PWM backlight.

But in case of PWM3 doesn't, it's only used for internal purpose. no
external output pin.

I just wonder it.
If you know the history reason, please let me know.

Thank you,
Kyungmin Park

On Sat, Feb 26, 2011 at 11:45 AM, Sangbeom Kim <sbkim73@samsung.com> wrote:
> This patch update mach-s5p64x0 and mach-s5pv210
> machine ?initialization for hrt support
>
> Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
> ---
> ?arch/arm/mach-s5p64x0/mach-smdk6440.c | ? ?4 +++-
> ?arch/arm/mach-s5p64x0/mach-smdk6450.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-aquila.c ? | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-goni.c ? ? | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-smdkc110.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-smdkv210.c | ? ?4 +++-
> ?arch/arm/mach-s5pv210/mach-torbreck.c | ? ?4 +++-
> ?7 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
> index e5beb84..f967736 100644
> --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
> +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
> @@ -43,6 +43,7 @@
> ?#include <plat/pll.h>
> ?#include <plat/adc.h>
> ?#include <plat/ts.h>
> +#include <plat/s5p-time.h>
>
> ?#define SMDK6440_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> @@ -136,6 +137,7 @@ static void __init smdk6440_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> ? ? ? ?s3c24xx_init_clocks(12000000);
> ? ? ? ?s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdk6440_machine_init(void)
> @@ -159,5 +161,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
> ? ? ? ?.init_irq ? ? ? = s5p6440_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdk6440_map_io,
> ? ? ? ?.init_machine ? = smdk6440_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
> index 3a20de0..686ec56 100644
> --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
> +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
> @@ -43,6 +43,7 @@
> ?#include <plat/pll.h>
> ?#include <plat/adc.h>
> ?#include <plat/ts.h>
> +#include <plat/s5p-time.h>
>
> ?#define SMDK6450_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> @@ -155,6 +156,7 @@ static void __init smdk6450_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> ? ? ? ?s3c24xx_init_clocks(19200000);
> ? ? ? ?s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdk6450_machine_init(void)
> @@ -178,5 +180,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
> ? ? ? ?.init_irq ? ? ? = s5p6450_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdk6450_map_io,
> ? ? ? ?.init_machine ? = smdk6450_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
> index 557add4..fab84f3 100644
> --- a/arch/arm/mach-s5pv210/mach-aquila.c
> +++ b/arch/arm/mach-s5pv210/mach-aquila.c
> @@ -39,6 +39,7 @@
> ?#include <plat/fb.h>
> ?#include <plat/fimc-core.h>
> ?#include <plat/sdhci.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define AQUILA_UCON_DEFAULT ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -664,6 +665,7 @@ static void __init aquila_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init aquila_machine_init(void)
> @@ -698,5 +700,5 @@ MACHINE_START(AQUILA, "Aquila")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = aquila_map_io,
> ? ? ? ?.init_machine ? = aquila_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
> index 056f5c7..5eda4a1 100644
> --- a/arch/arm/mach-s5pv210/mach-goni.c
> +++ b/arch/arm/mach-s5pv210/mach-goni.c
> @@ -45,6 +45,7 @@
> ?#include <plat/keypad.h>
> ?#include <plat/sdhci.h>
> ?#include <plat/clock.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define GONI_UCON_DEFAULT ? ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -823,6 +824,7 @@ static void __init goni_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init goni_machine_init(void)
> @@ -873,5 +875,5 @@ MACHINE_START(GONI, "GONI")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = goni_map_io,
> ? ? ? ?.init_machine ? = goni_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
> index ce11a02..f304383 100644
> --- a/arch/arm/mach-s5pv210/mach-smdkc110.c
> +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
> @@ -30,6 +30,7 @@
> ?#include <plat/ata.h>
> ?#include <plat/iic.h>
> ?#include <plat/pm.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define SMDKC110_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -111,6 +112,7 @@ static void __init smdkc110_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdkc110_machine_init(void)
> @@ -138,5 +140,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdkc110_map_io,
> ? ? ? ?.init_machine ? = smdkc110_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
> index bc9fdb5..41080bf 100644
> --- a/arch/arm/mach-s5pv210/mach-smdkv210.c
> +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
> @@ -43,6 +43,7 @@
> ?#include <plat/keypad.h>
> ?#include <plat/pm.h>
> ?#include <plat/fb.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define SMDKV210_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -272,6 +273,7 @@ static void __init smdkv210_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init smdkv210_machine_init(void)
> @@ -306,5 +308,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = smdkv210_map_io,
> ? ? ? ?.init_machine ? = smdkv210_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-s5pv210/mach-torbreck.c
> index 043c938..b3516a1 100644
> --- a/arch/arm/mach-s5pv210/mach-torbreck.c
> +++ b/arch/arm/mach-s5pv210/mach-torbreck.c
> @@ -27,6 +27,7 @@
> ?#include <plat/devs.h>
> ?#include <plat/cpu.h>
> ?#include <plat/iic.h>
> +#include <plat/s5p-time.h>
>
> ?/* Following are default values for UCON, ULCON and UFCON UART registers */
> ?#define TORBRECK_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> @@ -104,6 +105,7 @@ static void __init torbreck_map_io(void)
> ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> ? ? ? ?s3c24xx_init_clocks(24000000);
> ? ? ? ?s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
> + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> ?}
>
> ?static void __init torbreck_machine_init(void)
> @@ -127,5 +129,5 @@ MACHINE_START(TORBRECK, "TORBRECK")
> ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> ? ? ? ?.map_io ? ? ? ? = torbreck_map_io,
> ? ? ? ?.init_machine ? = torbreck_machine_init,
> - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> ?MACHINE_END
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
@ 2011-02-26  4:31   ` Kyungmin Park
  2011-02-26  9:33   ` Linus Walleij
  2011-02-26 14:24   ` Russell King - ARM Linux
  2 siblings, 0 replies; 11+ messages in thread
From: Kyungmin Park @ 2011-02-26  4:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Feb 26, 2011 at 11:45 AM, Sangbeom Kim <sbkim73@samsung.com> wrote:
> This patch adds support HR-Timer(High Resolution Timer) and dynamic
> tick system for S5P SoCs. There are many clock sources for HR-Timer
> on S5P SoCs. The PWM timer, RTC, System Timer, and MCT can be used
> for clock source.
> This patch can only support PWM timer for clocksource of
> S5P64x0 and S5PV210.
>
> Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
> ---
> ?arch/arm/plat-s5p/Makefile ? ? ? ? ? ? ? ?| ? ?1 +
> ?arch/arm/plat-s5p/include/plat/s5p-time.h | ? 37 +++
> ?arch/arm/plat-s5p/s5p-time.c ? ? ? ? ? ? ?| ?395 +++++++++++++++++++++++++++++
> ?3 files changed, 433 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/plat-s5p/include/plat/s5p-time.h
> ?create mode 100644 arch/arm/plat-s5p/s5p-time.c
>
> diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
> index 4bd5cf9..3b8cc2f 100644
> --- a/arch/arm/plat-s5p/Makefile
> +++ b/arch/arm/plat-s5p/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_S5P_GPIO_INT) ? ?+= irq-gpioint.o
> ?obj-$(CONFIG_S5P_SYSTEM_MMU) ? += sysmmu.o
> ?obj-$(CONFIG_PM) ? ? ? ? ? ? ? += pm.o
> ?obj-$(CONFIG_PM) ? ? ? ? ? ? ? += irq-pm.o
> +obj-$(CONFIG_GENERIC_CLOCKEVENTS) += s5p-time.o
>
> ?# devices
>
> diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
> new file mode 100644
> index 0000000..e478f0c
> --- /dev/null
> +++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
> @@ -0,0 +1,37 @@
> +/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
> + *
> + * Copyright 2011 Samsung Electronics Co., Ltd.
> + * ? ? ? ? ? ? http://www.samsung.com/
> + *
> + * Header file for s5p time support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#ifndef __ASM_PLAT_S5P_TIME_H
> +#define __ASM_PLAT_S5P_TIME_H __FILE__
> +
> +/* S5P HR-Timer Clock mode */
> +enum s5p_timer_mode {
> + ? ? ? S5P_PWM0,
> + ? ? ? S5P_PWM1,
> + ? ? ? S5P_PWM2,
> + ? ? ? S5P_PWM3,
> + ? ? ? S5P_PWM4,
> +};
> +
> +struct s5p_timer_source {
> + ? ? ? unsigned int event_id;
> + ? ? ? unsigned int source_id;
> +};
> +
> +#define TCNT_MAX ? ? ? ? ? ? ? 0xffffffff
> +#define NON_PERIODIC ? ? ? ? ? 0
> +#define PERIODIC ? ? ? ? ? ? ? 1
> +
> +extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? enum s5p_timer_mode source);
> +extern struct sys_timer s5p_timer;
> +#endif /* __ASM_PLAT_S5P_TIME_H */
> diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
> new file mode 100644
> index 0000000..4691728
> --- /dev/null
> +++ b/arch/arm/plat-s5p/s5p-time.c
> @@ -0,0 +1,395 @@
> +/* linux/arch/arm/plat-s5p/s5p-time.c
> + *
> + * Copyright (c) 2011 Samsung Electronics Co., Ltd.
> + * ? ? ? ? ? ? http://www.samsung.com/
> + *
> + * S5P - Common hr-timer support
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> +*/
> +
> +#include <linux/sched.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/err.h>
> +#include <linux/clk.h>
> +#include <linux/clockchips.h>
> +#include <linux/platform_device.h>
> +
> +#include <asm/smp_twd.h>
> +#include <asm/mach/time.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +
> +#include <mach/map.h>
> +#include <plat/regs-timer.h>
> +#include <plat/s5p-time.h>
> +
> +static struct clk *tin_event;
> +static struct clk *tin_source;
> +static struct clk *tdiv_event;
> +static struct clk *tdiv_source;
> +static struct clk *timerclk;
> +static struct s5p_timer_source timer_source;
> +static unsigned long clock_count_per_tick;
> +static void s5p_timer_resume(void);
> +
> +static void s5p_time_stop(enum s5p_timer_mode mode)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon = __raw_readl(S3C2410_TCON);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T4START;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", mode);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> + ? ? ? __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon = __raw_readl(S3C2410_TCON);
> +
> + ? ? ? tcnt--;
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 0);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 8);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon &= ~(0x0f << 0x0c);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon &= ~(0xf << 0x10);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? tcon &= ~(7 << 0x14);
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T4MANUALUPD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", mode);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +
> + ? ? ? __raw_writel(tcnt, S3C2410_TCNTB(mode));
> + ? ? ? __raw_writel(tcnt, S3C2410_TCMPB(mode));
> + ? ? ? __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
> +{
> + ? ? ? unsigned long tcon;
> +
> + ? ? ? tcon ?= __raw_readl(S3C2410_TCON);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T0RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T0RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM1:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T1RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T1RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM2:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T2RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T2RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T3RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T3RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T4START;
> + ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T4MANUALUPD;
> +
> + ? ? ? ? ? ? ? if (periodic)
> + ? ? ? ? ? ? ? ? ? ? ? tcon |= S3C2410_TCON_T4RELOAD;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? tcon &= ~S3C2410_TCON_T4RELOAD;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", mode);
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> + ? ? ? __raw_writel(tcon, S3C2410_TCON);
> +}
> +
> +static int s5p_set_next_event(unsigned long cycles,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *evt)
> +{
> + ? ? ? s5p_time_setup(timer_source.event_id, cycles);
> + ? ? ? s5p_time_start(timer_source.event_id, NON_PERIODIC);
> +
> + ? ? ? return 0;
> +}
> +
> +static void s5p_set_mode(enum clock_event_mode mode,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *evt)
> +{
> +
> + ? ? ? s5p_time_stop(timer_source.event_id);
> +
> + ? ? ? switch (mode) {
> + ? ? ? case CLOCK_EVT_MODE_PERIODIC:
> + ? ? ? ? ? ? ? s5p_time_setup(timer_source.event_id, clock_count_per_tick);
> + ? ? ? ? ? ? ? s5p_time_start(timer_source.event_id, PERIODIC);
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case CLOCK_EVT_MODE_ONESHOT:
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case CLOCK_EVT_MODE_UNUSED:
> + ? ? ? case CLOCK_EVT_MODE_SHUTDOWN:
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? case CLOCK_EVT_MODE_RESUME:
> + ? ? ? ? ? ? ? s5p_timer_resume();
> + ? ? ? ? ? ? ? break;
> + ? ? ? }
> +}
> +
> +static void s5p_timer_resume(void)
> +{
> + ? ? ? /* event timer restart */
> + ? ? ? s5p_time_setup(timer_source.event_id, clock_count_per_tick);
> + ? ? ? s5p_time_start(timer_source.event_id, PERIODIC);
> +
> + ? ? ? /* source timer restart */
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +}
> +
> +void __init s5p_set_timer_source(enum s5p_timer_mode event,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?enum s5p_timer_mode source)
> +{
> + ? ? ? timer_source.event_id = event;
> + ? ? ? timer_source.source_id = source;
> +}
> +
> +static struct clock_event_device time_event_device = {
> + ? ? ? .name ? ? ? ? ? = "s5p_event_timer",
> + ? ? ? .features ? ? ? = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> + ? ? ? .rating ? ? ? ? = 200,
> + ? ? ? .shift ? ? ? ? ?= 32,
Please use the new clock event function. I can't remember the exact
function name, but there's function set the proper shift value instead
of hard-coded.
> + ? ? ? .set_next_event = s5p_set_next_event,
> + ? ? ? .set_mode ? ? ? = s5p_set_mode,
> +};
> +
> +static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
> +{
> + ? ? ? struct clock_event_device *evt = &time_event_device;
> +
> + ? ? ? evt->event_handler(evt);
> +
> + ? ? ? return IRQ_HANDLED;
> +}
> +
> +static struct irqaction s5p_clock_event_irq = {
> + ? ? ? .name ? ? ? ? ? = "s5p_time_irq",
> + ? ? ? .flags ? ? ? ? ?= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> + ? ? ? .handler ? ? ? ?= s5p_clock_event_isr,
> +};
> +
> +static void s5p_clockevent_init(void)

Please add __init since it's only used at __init function.
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> + ? ? ? unsigned int irq_number;
> + ? ? ? struct clk *tscaler;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? tscaler = clk_get_parent(tdiv_event);
> +
> + ? ? ? clk_set_rate(tscaler, pclk / 2);
> + ? ? ? clk_set_rate(tdiv_event, pclk / 2);
> + ? ? ? clk_set_parent(tin_event, tdiv_event);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_event);
> + ? ? ? clock_count_per_tick = clock_rate / HZ;
> +
> + ? ? ? time_event_device.mult =
> + ? ? ? ? ? ? ? div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
> + ? ? ? time_event_device.max_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(-1, &time_event_device);
> + ? ? ? time_event_device.min_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(1, &time_event_device);
> +
> + ? ? ? time_event_device.cpumask = cpumask_of(0);
> + ? ? ? clockevents_register_device(&time_event_device);
> +
> + ? ? ? irq_number = timer_source.event_id + IRQ_TIMER0;
> +
> + ? ? ? setup_irq(irq_number, &s5p_clock_event_irq);
> +}
> +
> +static cycle_t s5p_timer_read(struct clocksource *cs)
> +{
> + ? ? ? unsigned long offset = 0;
> +
> + ? ? ? switch (timer_source.source_id) {
> + ? ? ? case S5P_PWM0:
> + ? ? ? case S5P_PWM1:
> + ? ? ? case S5P_PWM2:
> + ? ? ? case S5P_PWM3:
> + ? ? ? ? ? ? ? offset = (timer_source.source_id * 0x0c) + 0x14;
> + ? ? ? case S5P_PWM4:
> + ? ? ? ? ? ? ? offset = 0x40;
> + ? ? ? ? ? ? ? break;
> +
> + ? ? ? default:
> + ? ? ? ? ? ? ? printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? }
> +
> + ? ? ? return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
> +}
> +
> +struct clocksource time_clocksource = {
> + ? ? ? .name ? ? ? ? ? = "s5p_clocksource_timer",
> + ? ? ? .rating ? ? ? ? = 250,
> + ? ? ? .read ? ? ? ? ? = s5p_timer_read,
> + ? ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
> + ? ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static void s5p_clocksource_init(void)
ditto.
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? clk_set_rate(tdiv_source, pclk / 2);
> + ? ? ? clk_set_parent(tin_source, tdiv_source);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_source);
> +
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +
> + ? ? ? if (clocksource_register_hz(&time_clocksource, clock_rate))
> + ? ? ? ? ? ? ? panic("%s: can't register clocksource\n", time_clocksource.name);
> +}
> +
> +static void __init s5p_timer_resources(void)
> +{
> + ? ? ? struct platform_device tmpdev;
> +
> + ? ? ? tmpdev.dev.bus = &platform_bus_type;
> +
> + ? ? ? timerclk = clk_get(NULL, "timers");
> + ? ? ? if (IS_ERR(timerclk))
> + ? ? ? ? ? ? ? panic("failed to get timers clock for system timer");
> +
> + ? ? ? clk_enable(timerclk);
> +
> + ? ? ? tmpdev.id = timer_source.event_id;
> + ? ? ? tin_event = clk_get(&tmpdev.dev, "pwm-tin");
> + ? ? ? if (IS_ERR(tin_event)) {
> + ? ? ? ? ? ? ? clk_put(tin_event);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tin2 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
> + ? ? ? if (IS_ERR(tdiv_event)) {
> + ? ? ? ? ? ? ? clk_put(tdiv_event);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tdiv2 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? clk_enable(tin_event);
> +
> + ? ? ? tmpdev.id = timer_source.source_id;
> + ? ? ? tin_source = clk_get(&tmpdev.dev, "pwm-tin");
> + ? ? ? if (IS_ERR(tin_source)) {
> + ? ? ? ? ? ? ? clk_put(tin_source);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tin4 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
> + ? ? ? if (IS_ERR(tdiv_source)) {
> + ? ? ? ? ? ? ? clk_put(tdiv_source);
> + ? ? ? ? ? ? ? panic("failed to get pwm-tdiv4 clock for system timer");
> + ? ? ? }
> +
> + ? ? ? clk_enable(tin_source);
> +}
> +
> +static void __init s5p_timer_init(void)
> +{
> +#ifdef CONFIG_LOCAL_TIMERS
> + ? ? ? twd_base = S5P_VA_TWD;
> +#endif
> +
> + ? ? ? s5p_timer_resources();
> + ? ? ? s5p_clockevent_init();
> + ? ? ? s5p_clocksource_init();
> +}
> +
> +struct sys_timer s5p_timer = {
> + ? ? ? .init ? ? ? ? ? = s5p_timer_init,
> +};
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
  2011-02-26  4:31   ` Kyungmin Park
@ 2011-02-26  9:33   ` Linus Walleij
  2011-02-28  7:56     ` Sangbeom Kim
  2011-02-26 14:24   ` Russell King - ARM Linux
  2 siblings, 1 reply; 11+ messages in thread
From: Linus Walleij @ 2011-02-26  9:33 UTC (permalink / raw)
  To: linux-arm-kernel

2011/2/26 Sangbeom Kim <sbkim73@samsung.com>:
> (...)
> +static void s5p_clockevent_init(void)
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> + ? ? ? unsigned int irq_number;
> + ? ? ? struct clk *tscaler;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? tscaler = clk_get_parent(tdiv_event);
> +
> + ? ? ? clk_set_rate(tscaler, pclk / 2);
> + ? ? ? clk_set_rate(tdiv_event, pclk / 2);
> + ? ? ? clk_set_parent(tin_event, tdiv_event);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_event);
> + ? ? ? clock_count_per_tick = clock_rate / HZ;
> +
> + ? ? ? time_event_device.mult =
> + ? ? ? ? ? ? ? div_sc(clock_rate, NSEC_PER_SEC, time_event_device.shift);
> + ? ? ? time_event_device.max_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(-1, &time_event_device);
> + ? ? ? time_event_device.min_delta_ns =
> + ? ? ? ? ? ? ? clockevent_delta2ns(1, &time_event_device);

This is a very complicated and inprecise way of doing this nowadays.
Skip hardcoding the shift value and calculating mult like that and use

/* Be able to sleep for atleast 4 seconds (usually more) */
#define EVT_MIN_RANGE 4

clockevents_calc_mult_shift(&time_event_device,
                                    clock_rate, EVT_MIN_RANGE);

> (...)
> +static void s5p_clocksource_init(void)
> +{
> + ? ? ? unsigned long pclk;
> + ? ? ? unsigned long clock_rate;
> +
> + ? ? ? pclk = clk_get_rate(timerclk);
> +
> + ? ? ? clk_set_rate(tdiv_source, pclk / 2);
> + ? ? ? clk_set_parent(tin_source, tdiv_source);
> +
> + ? ? ? clock_rate = clk_get_rate(tin_source);
> +
> + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> +
> + ? ? ? if (clocksource_register_hz(&time_clocksource, clock_rate))
> + ? ? ? ? ? ? ? panic("%s: can't register clocksource\n", time_clocksource.name);
> +}

This is more like it :-)

But you probably also want to add a sched_clock hook for this
platform too, so you get some nice scheduling resolution.

I suggest you look at the simple straight-forward driver
for U300 in arch/arm/mach-u300/timer.c for inspiration.
It's using the same timer that is used for clocksource for
sched_clock().


Yours,
Linus Walleij

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
  2011-02-26  4:31   ` Kyungmin Park
  2011-02-26  9:33   ` Linus Walleij
@ 2011-02-26 14:24   ` Russell King - ARM Linux
  2011-03-01  9:16     ` Sylwester Nawrocki
  2 siblings, 1 reply; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-02-26 14:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Feb 26, 2011 at 11:45:55AM +0900, Sangbeom Kim wrote:
> +static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
> +{
> +	struct clock_event_device *evt = &time_event_device;

	struct clock_event_device *evt = dev_id;

> +
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static struct irqaction s5p_clock_event_irq = {
> +	.name		= "s5p_time_irq",
> +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> +	.handler	= s5p_clock_event_isr,

	.dev_id	 	= &time_event_device,

> +};
...
> +static void __init s5p_timer_resources(void)
> +{
> +	struct platform_device tmpdev;
> +
> +	tmpdev.dev.bus = &platform_bus_type;
> +
> +	timerclk = clk_get(NULL, "timers");
> +	if (IS_ERR(timerclk))
> +		panic("failed to get timers clock for system timer");
> +
> +	clk_enable(timerclk);
> +
> +	tmpdev.id = timer_source.event_id;

So Samsung clock stuff is still being idiotic.  Will this ever be fixed?

> +	tin_event = clk_get(&tmpdev.dev, "pwm-tin");
> +	if (IS_ERR(tin_event)) {
> +		clk_put(tin_event);

Don't clk_put errors.

> +		panic("failed to get pwm-tin2 clock for system timer");
> +	}
> +
> +	tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
> +	if (IS_ERR(tdiv_event)) {
> +		clk_put(tdiv_event);

Ditto.

> +		panic("failed to get pwm-tdiv2 clock for system timer");
> +	}
> +
> +	clk_enable(tin_event);
> +
> +	tmpdev.id = timer_source.source_id;
> +	tin_source = clk_get(&tmpdev.dev, "pwm-tin");
> +	if (IS_ERR(tin_source)) {
> +		clk_put(tin_source);

Ditto.

> +		panic("failed to get pwm-tin4 clock for system timer");
> +	}
> +
> +	tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
> +	if (IS_ERR(tdiv_source)) {
> +		clk_put(tdiv_source);

Ditto.

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26  9:33   ` Linus Walleij
@ 2011-02-28  7:56     ` Sangbeom Kim
  0 siblings, 0 replies; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-28  7:56 UTC (permalink / raw)
  To: linux-arm-kernel

Dear Walleij,

Thanks for your suggest.
I will apply your suggest in the next version.
Thanks & Regards,

S.B. Kim

2011/2/26 Linus Walleij <linux.walleij@linaro.org> wrote:
> -----Original Message-----
> From: linux-samsung-soc-owner at vger.kernel.org [mailto:linux-samsung-soc-
> owner at vger.kernel.org] On Behalf Of Linus Walleij
> Sent: Saturday, February 26, 2011 6:34 PM
> To: Sangbeom Kim
> Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; kgene.kim at samsung.com; ben-linux at fluff.org
> Subject: Re: [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
> 
> 2011/2/26 Sangbeom Kim <sbkim73@samsung.com>:
> > (...)
> > +static void s5p_clockevent_init(void)
> > +{
> > + ? ? ? unsigned long pclk;
> > + ? ? ? unsigned long clock_rate;
> > + ? ? ? unsigned int irq_number;
> > + ? ? ? struct clk *tscaler;
> > +
> > + ? ? ? pclk = clk_get_rate(timerclk);
> > +
> > + ? ? ? tscaler = clk_get_parent(tdiv_event);
> > +
> > + ? ? ? clk_set_rate(tscaler, pclk / 2);
> > + ? ? ? clk_set_rate(tdiv_event, pclk / 2);
> > + ? ? ? clk_set_parent(tin_event, tdiv_event);
> > +
> > + ? ? ? clock_rate = clk_get_rate(tin_event);
> > + ? ? ? clock_count_per_tick = clock_rate / HZ;
> > +
> > + ? ? ? time_event_device.mult =
> > + ? ? ? ? ? ? ? div_sc(clock_rate, NSEC_PER_SEC,
time_event_device.shift);
> > + ? ? ? time_event_device.max_delta_ns =
> > + ? ? ? ? ? ? ? clockevent_delta2ns(-1, &time_event_device);
> > + ? ? ? time_event_device.min_delta_ns =
> > + ? ? ? ? ? ? ? clockevent_delta2ns(1, &time_event_device);
> 
> This is a very complicated and inprecise way of doing this nowadays.
> Skip hardcoding the shift value and calculating mult like that and use
> 
> /* Be able to sleep for atleast 4 seconds (usually more) */
> #define EVT_MIN_RANGE 4
> 
> clockevents_calc_mult_shift(&time_event_device,
>                                     clock_rate, EVT_MIN_RANGE);
> 
> > (...)
> > +static void s5p_clocksource_init(void)
> > +{
> > + ? ? ? unsigned long pclk;
> > + ? ? ? unsigned long clock_rate;
> > +
> > + ? ? ? pclk = clk_get_rate(timerclk);
> > +
> > + ? ? ? clk_set_rate(tdiv_source, pclk / 2);
> > + ? ? ? clk_set_parent(tin_source, tdiv_source);
> > +
> > + ? ? ? clock_rate = clk_get_rate(tin_source);
> > +
> > + ? ? ? s5p_time_setup(timer_source.source_id, TCNT_MAX);
> > + ? ? ? s5p_time_start(timer_source.source_id, PERIODIC);
> > +
> > + ? ? ? if (clocksource_register_hz(&time_clocksource, clock_rate))
> > + ? ? ? ? ? ? ? panic("%s: can't register clocksource\n",
> time_clocksource.name);
> > +}
> 
> This is more like it :-)
> 
> But you probably also want to add a sched_clock hook for this
> platform too, so you get some nice scheduling resolution.
> 
> I suggest you look at the simple straight-forward driver
> for U300 in arch/arm/mach-u300/timer.c for inspiration.
> It's using the same timer that is used for clocksource for
> sched_clock().
> 
> 
> Yours,
> Linus Walleij
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
  2011-02-26  4:27   ` Kyungmin Park
@ 2011-02-28  8:11     ` Sangbeom Kim
  0 siblings, 0 replies; 11+ messages in thread
From: Sangbeom Kim @ 2011-02-28  8:11 UTC (permalink / raw)
  To: linux-arm-kernel

Hi kyungmin,

There is no theoretical reason for Using PWM2, 4.
You can freely use every PWM timer by calling s5p_set_timer_source(..) api.
But I recommend that It would be better timer4 for clocksource.
Because PWM4 doesn't have tout.

Thanks and regards,
S.B. Kim

On Saturday, February 26, 2011 1:27 PM Kyungmin Park
<kyungmin.park@samsung.com> wrote:
> To: Sangbeom Kim
> Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; kgene.kim at samsung.com; ben-linux at fluff.org
> Subject: Re: [PATCH 2/3] ARM: S5P: Update machine initialization for HRT
> 
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> 
> It's just curious. Are there any reason to use PWM2 & 4. Theoretically
> it's possible to use PWM2 for other purpose as it's connected with
> external devices such as haptic or PWM backlight.
> 
> But in case of PWM3 doesn't, it's only used for internal purpose. no
> external output pin.
> 
> I just wonder it.
> If you know the history reason, please let me know.
> 
> Thank you,
> Kyungmin Park
> 
> On Sat, Feb 26, 2011 at 11:45 AM, Sangbeom Kim <sbkim73@samsung.com>
wrote:
> > This patch update mach-s5p64x0 and mach-s5pv210
> > machine ?initialization for hrt support
> >
> > Signed-off-by: Sangbeom Kim <sbkim73@samsung.com>
> > ---
> > ?arch/arm/mach-s5p64x0/mach-smdk6440.c | ? ?4 +++-
> > ?arch/arm/mach-s5p64x0/mach-smdk6450.c | ? ?4 +++-
> > ?arch/arm/mach-s5pv210/mach-aquila.c ? | ? ?4 +++-
> > ?arch/arm/mach-s5pv210/mach-goni.c ? ? | ? ?4 +++-
> > ?arch/arm/mach-s5pv210/mach-smdkc110.c | ? ?4 +++-
> > ?arch/arm/mach-s5pv210/mach-smdkv210.c | ? ?4 +++-
> > ?arch/arm/mach-s5pv210/mach-torbreck.c | ? ?4 +++-
> > ?7 files changed, 21 insertions(+), 7 deletions(-)
> >
> > diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-
> s5p64x0/mach-smdk6440.c
> > index e5beb84..f967736 100644
> > --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
> > +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
> > @@ -43,6 +43,7 @@
> > ?#include <plat/pll.h>
> > ?#include <plat/adc.h>
> > ?#include <plat/ts.h>
> > +#include <plat/s5p-time.h>
> >
> > ?#define SMDK6440_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> > @@ -136,6 +137,7 @@ static void __init smdk6440_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> > ? ? ? ?s3c24xx_init_clocks(12000000);
> > ? ? ? ?s3c24xx_init_uarts(smdk6440_uartcfgs,
> ARRAY_SIZE(smdk6440_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init smdk6440_machine_init(void)
> > @@ -159,5 +161,5 @@ MACHINE_START(SMDK6440, "SMDK6440")
> > ? ? ? ?.init_irq ? ? ? = s5p6440_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = smdk6440_map_io,
> > ? ? ? ?.init_machine ? = smdk6440_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-
> s5p64x0/mach-smdk6450.c
> > index 3a20de0..686ec56 100644
> > --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
> > +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
> > @@ -43,6 +43,7 @@
> > ?#include <plat/pll.h>
> > ?#include <plat/adc.h>
> > ?#include <plat/ts.h>
> > +#include <plat/s5p-time.h>
> >
> > ?#define SMDK6450_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?S3C2410_UCON_RXILEVEL | ? ? ? ? \
> > @@ -155,6 +156,7 @@ static void __init smdk6450_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P64X0_SYS_ID);
> > ? ? ? ?s3c24xx_init_clocks(19200000);
> > ? ? ? ?s3c24xx_init_uarts(smdk6450_uartcfgs,
> ARRAY_SIZE(smdk6450_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init smdk6450_machine_init(void)
> > @@ -178,5 +180,5 @@ MACHINE_START(SMDK6450, "SMDK6450")
> > ? ? ? ?.init_irq ? ? ? = s5p6450_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = smdk6450_map_io,
> > ? ? ? ?.init_machine ? = smdk6450_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-
> s5pv210/mach-aquila.c
> > index 557add4..fab84f3 100644
> > --- a/arch/arm/mach-s5pv210/mach-aquila.c
> > +++ b/arch/arm/mach-s5pv210/mach-aquila.c
> > @@ -39,6 +39,7 @@
> > ?#include <plat/fb.h>
> > ?#include <plat/fimc-core.h>
> > ?#include <plat/sdhci.h>
> > +#include <plat/s5p-time.h>
> >
> > ?/* Following are default values for UCON, ULCON and UFCON UART
> registers */
> > ?#define AQUILA_UCON_DEFAULT ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > @@ -664,6 +665,7 @@ static void __init aquila_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> > ? ? ? ?s3c24xx_init_clocks(24000000);
> > ? ? ? ?s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init aquila_machine_init(void)
> > @@ -698,5 +700,5 @@ MACHINE_START(AQUILA, "Aquila")
> > ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = aquila_map_io,
> > ? ? ? ?.init_machine ? = aquila_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-
> s5pv210/mach-goni.c
> > index 056f5c7..5eda4a1 100644
> > --- a/arch/arm/mach-s5pv210/mach-goni.c
> > +++ b/arch/arm/mach-s5pv210/mach-goni.c
> > @@ -45,6 +45,7 @@
> > ?#include <plat/keypad.h>
> > ?#include <plat/sdhci.h>
> > ?#include <plat/clock.h>
> > +#include <plat/s5p-time.h>
> >
> > ?/* Following are default values for UCON, ULCON and UFCON UART
> registers */
> > ?#define GONI_UCON_DEFAULT ? ? ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > @@ -823,6 +824,7 @@ static void __init goni_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> > ? ? ? ?s3c24xx_init_clocks(24000000);
> > ? ? ? ?s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init goni_machine_init(void)
> > @@ -873,5 +875,5 @@ MACHINE_START(GONI, "GONI")
> > ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = goni_map_io,
> > ? ? ? ?.init_machine ? = goni_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-
> s5pv210/mach-smdkc110.c
> > index ce11a02..f304383 100644
> > --- a/arch/arm/mach-s5pv210/mach-smdkc110.c
> > +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
> > @@ -30,6 +30,7 @@
> > ?#include <plat/ata.h>
> > ?#include <plat/iic.h>
> > ?#include <plat/pm.h>
> > +#include <plat/s5p-time.h>
> >
> > ?/* Following are default values for UCON, ULCON and UFCON UART
> registers */
> > ?#define SMDKC110_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > @@ -111,6 +112,7 @@ static void __init smdkc110_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> > ? ? ? ?s3c24xx_init_clocks(24000000);
> > ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs,
> ARRAY_SIZE(smdkv210_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init smdkc110_machine_init(void)
> > @@ -138,5 +140,5 @@ MACHINE_START(SMDKC110, "SMDKC110")
> > ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = smdkc110_map_io,
> > ? ? ? ?.init_machine ? = smdkc110_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-
> s5pv210/mach-smdkv210.c
> > index bc9fdb5..41080bf 100644
> > --- a/arch/arm/mach-s5pv210/mach-smdkv210.c
> > +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
> > @@ -43,6 +43,7 @@
> > ?#include <plat/keypad.h>
> > ?#include <plat/pm.h>
> > ?#include <plat/fb.h>
> > +#include <plat/s5p-time.h>
> >
> > ?/* Following are default values for UCON, ULCON and UFCON UART
> registers */
> > ?#define SMDKV210_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > @@ -272,6 +273,7 @@ static void __init smdkv210_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> > ? ? ? ?s3c24xx_init_clocks(24000000);
> > ? ? ? ?s3c24xx_init_uarts(smdkv210_uartcfgs,
> ARRAY_SIZE(smdkv210_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init smdkv210_machine_init(void)
> > @@ -306,5 +308,5 @@ MACHINE_START(SMDKV210, "SMDKV210")
> > ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = smdkv210_map_io,
> > ? ? ? ?.init_machine ? = smdkv210_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > diff --git a/arch/arm/mach-s5pv210/mach-torbreck.c b/arch/arm/mach-
> s5pv210/mach-torbreck.c
> > index 043c938..b3516a1 100644
> > --- a/arch/arm/mach-s5pv210/mach-torbreck.c
> > +++ b/arch/arm/mach-s5pv210/mach-torbreck.c
> > @@ -27,6 +27,7 @@
> > ?#include <plat/devs.h>
> > ?#include <plat/cpu.h>
> > ?#include <plat/iic.h>
> > +#include <plat/s5p-time.h>
> >
> > ?/* Following are default values for UCON, ULCON and UFCON UART
> registers */
> > ?#define TORBRECK_UCON_DEFAULT ?(S3C2410_UCON_TXILEVEL | ? ? ? ?\
> > @@ -104,6 +105,7 @@ static void __init torbreck_map_io(void)
> > ? ? ? ?s5p_init_io(NULL, 0, S5P_VA_CHIPID);
> > ? ? ? ?s3c24xx_init_clocks(24000000);
> > ? ? ? ?s3c24xx_init_uarts(torbreck_uartcfgs,
> ARRAY_SIZE(torbreck_uartcfgs));
> > + ? ? ? s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
> > ?}
> >
> > ?static void __init torbreck_machine_init(void)
> > @@ -127,5 +129,5 @@ MACHINE_START(TORBRECK, "TORBRECK")
> > ? ? ? ?.init_irq ? ? ? = s5pv210_init_irq,
> > ? ? ? ?.map_io ? ? ? ? = torbreck_map_io,
> > ? ? ? ?.init_machine ? = torbreck_machine_init,
> > - ? ? ? .timer ? ? ? ? ?= &s3c24xx_timer,
> > + ? ? ? .timer ? ? ? ? ?= &s5p_timer,
> > ?MACHINE_END
> > --
> > 1.7.1
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> > the body of a message to majordomo at vger.kernel.org
> > More majordomo info at ?http://vger.kernel.org/majordomo-info.html
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-
> soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT
  2011-02-26 14:24   ` Russell King - ARM Linux
@ 2011-03-01  9:16     ` Sylwester Nawrocki
  0 siblings, 0 replies; 11+ messages in thread
From: Sylwester Nawrocki @ 2011-03-01  9:16 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 02/26/2011 03:24 PM, Russell King - ARM Linux wrote:
> On Sat, Feb 26, 2011 at 11:45:55AM +0900, Sangbeom Kim wrote:
>> +static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
>> +{
>> +	struct clock_event_device *evt = &time_event_device;
> 
> 	struct clock_event_device *evt = dev_id;
> 
>> +
>> +	evt->event_handler(evt);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static struct irqaction s5p_clock_event_irq = {
>> +	.name		= "s5p_time_irq",
>> +	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
>> +	.handler	= s5p_clock_event_isr,
> 
> 	.dev_id	 	= &time_event_device,
> 
>> +};
> ...
>> +static void __init s5p_timer_resources(void)
>> +{
>> +	struct platform_device tmpdev;
>> +
>> +	tmpdev.dev.bus = &platform_bus_type;
>> +
>> +	timerclk = clk_get(NULL, "timers");
>> +	if (IS_ERR(timerclk))
>> +		panic("failed to get timers clock for system timer");
>> +
>> +	clk_enable(timerclk);
>> +
>> +	tmpdev.id = timer_source.event_id;
> 
> So Samsung clock stuff is still being idiotic.  Will this ever be fixed?
> 

Are there any serious difficulties preventing converting Samsung platforms
to clkdev? I don't seem to be aware of any.
Shortcomings of current clk API appeared few times already, and this one
being a disgraceful example.

>> +	tin_event = clk_get(&tmpdev.dev, "pwm-tin");
>> +	if (IS_ERR(tin_event)) {
>> +		clk_put(tin_event);
> 
> Don't clk_put errors.
> 
>> +		panic("failed to get pwm-tin2 clock for system timer");
>> +	}
>> +
>> +	tdiv_event = clk_get(&tmpdev.dev, "pwm-tdiv");
>> +	if (IS_ERR(tdiv_event)) {
>> +		clk_put(tdiv_event);
> 
> Ditto.
> 
>> +		panic("failed to get pwm-tdiv2 clock for system timer");
>> +	}
>> +
>> +	clk_enable(tin_event);
>> +
>> +	tmpdev.id = timer_source.source_id;
>> +	tin_source = clk_get(&tmpdev.dev, "pwm-tin");
>> +	if (IS_ERR(tin_source)) {
>> +		clk_put(tin_source);
> 
> Ditto.
> 
>> +		panic("failed to get pwm-tin4 clock for system timer");
>> +	}
>> +
>> +	tdiv_source = clk_get(&tmpdev.dev, "pwm-tdiv");
>> +	if (IS_ERR(tdiv_source)) {
>> +		clk_put(tdiv_source);
> 
> Ditto.

-- 
Sylwester Nawrocki
Samsung Poland R&D Center

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

end of thread, other threads:[~2011-03-01  9:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-26  2:45 [PATCH 0/3] ARM: S5P: Add high resolution timer support Sangbeom Kim
2011-02-26  2:45 ` [PATCH 1/3] ARM: S5P: Add s5p_timer support for HRT Sangbeom Kim
2011-02-26  4:31   ` Kyungmin Park
2011-02-26  9:33   ` Linus Walleij
2011-02-28  7:56     ` Sangbeom Kim
2011-02-26 14:24   ` Russell King - ARM Linux
2011-03-01  9:16     ` Sylwester Nawrocki
2011-02-26  2:45 ` [PATCH 2/3] ARM: S5P: Update machine initialization " Sangbeom Kim
2011-02-26  4:27   ` Kyungmin Park
2011-02-28  8:11     ` Sangbeom Kim
2011-02-26  2:45 ` [PATCH 3/3] ARM: S5P: Update defconfig for HRT support Sangbeom Kim

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