aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mmp
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2011-08-09 14:37:55 -0400
committerEric Miao <eric.y.miao@gmail.com>2011-08-10 22:10:46 -0400
commitaf9dafb1dcf320a46783e09764c758bc4e32ed94 (patch)
tree36cd1fcd0ae97621f6d4d4cb02a94548677d0c8f /arch/arm/mach-mmp
parent71c0c341403cb141e3580817947e56a4386db4c8 (diff)
ARM: mmp: Change the way we use timer 0 as clockevent timer.
Instead of setting up a match interrupt for 'current_time + delta' on ->set_next_event(), program timer 0 to count down from 'delta - 1' and trigger an interrupt when it reaches zero. Signed-off-by: Lennert Buytenhek <buytenh@laptop.org> Acked-by: Haojian Zhuang <haojian.zhuang@gmail.com> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
Diffstat (limited to 'arch/arm/mach-mmp')
-rw-r--r--arch/arm/mach-mmp/time.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index c53715edfa82..4e91ee6e27c8 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -75,28 +75,51 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
75{ 75{
76 struct clock_event_device *c = dev_id; 76 struct clock_event_device *c = dev_id;
77 77
78 /* disable and clear pending interrupt status */ 78 /*
79 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); 79 * Clear pending interrupt status.
80 __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0)); 80 */
81 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
82
83 /*
84 * Disable timer 0.
85 */
86 __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER);
87
81 c->event_handler(c); 88 c->event_handler(c);
89
82 return IRQ_HANDLED; 90 return IRQ_HANDLED;
83} 91}
84 92
85static int timer_set_next_event(unsigned long delta, 93static int timer_set_next_event(unsigned long delta,
86 struct clock_event_device *dev) 94 struct clock_event_device *dev)
87{ 95{
88 unsigned long flags, next; 96 unsigned long flags;
89 97
90 local_irq_save(flags); 98 local_irq_save(flags);
91 99
92 /* clear pending interrupt status and enable */ 100 /*
101 * Disable timer 0.
102 */
103 __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER);
104
105 /*
106 * Clear and enable timer match 0 interrupt.
107 */
93 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); 108 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0));
94 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); 109 __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0));
95 110
96 next = timer_read() + delta; 111 /*
97 __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); 112 * Setup new clockevent timer value.
113 */
114 __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0));
115
116 /*
117 * Enable timer 0.
118 */
119 __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER);
98 120
99 local_irq_restore(flags); 121 local_irq_restore(flags);
122
100 return 0; 123 return 0;
101} 124}
102 125
@@ -152,10 +175,10 @@ static void __init timer_config(void)
152 (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); 175 (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3));
153 __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); 176 __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
154 177
155 /* free-running mode */ 178 /* set timer 0 to periodic mode, and timer 1 to free-running mode */
156 __raw_writel(0x3, TIMERS_VIRT_BASE + TMR_CMR); 179 __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR);
157 180
158 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */ 181 __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */
159 __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ 182 __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */
160 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); 183 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0));
161 184
@@ -163,8 +186,8 @@ static void __init timer_config(void)
163 __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ 186 __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */
164 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); 187 __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1));
165 188
166 /* enable timer counter */ 189 /* enable timer 1 counter */
167 __raw_writel(0x3, TIMERS_VIRT_BASE + TMR_CER); 190 __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER);
168} 191}
169 192
170static struct irqaction timer_irq = { 193static struct irqaction timer_irq = {