aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-pxa
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-09-01 07:48:40 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-09-01 07:48:40 -0400
commit5c53ff088cb76dca52bdf2ef36ea63147763f9ea (patch)
treed3d740367c93594860087531124213379e7345e4 /arch/arm/mach-pxa
parent68d9102f76de7a923fb81c8b6de4764f8f50ed17 (diff)
[ARM] 2862/1: VST aka CONFIG_NO_IDLE_HZ support for PXA2xx
Patch from Nicolas Pitre Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-pxa')
-rw-r--r--arch/arm/mach-pxa/time.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 6e5202154f91..72b15e9a373a 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -70,6 +70,11 @@ static unsigned long pxa_gettimeoffset (void)
70 return usec; 70 return usec;
71} 71}
72 72
73#ifdef CONFIG_NO_IDLE_HZ
74static unsigned long initial_match;
75static int match_posponed;
76#endif
77
73static irqreturn_t 78static irqreturn_t
74pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) 79pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
75{ 80{
@@ -77,6 +82,13 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
77 82
78 write_seqlock(&xtime_lock); 83 write_seqlock(&xtime_lock);
79 84
85#ifdef CONFIG_NO_IDLE_HZ
86 if (match_posponed) {
87 match_posponed = 0;
88 OSMR0 = initial_match;
89 }
90#endif
91
80 /* Loop until we get ahead of the free running timer. 92 /* Loop until we get ahead of the free running timer.
81 * This ensures an exact clock tick count and time accuracy. 93 * This ensures an exact clock tick count and time accuracy.
82 * IRQs are disabled inside the loop to ensure coherence between 94 * IRQs are disabled inside the loop to ensure coherence between
@@ -126,6 +138,42 @@ static void __init pxa_timer_init(void)
126 OSCR = 0; /* initialize free-running timer, force first match */ 138 OSCR = 0; /* initialize free-running timer, force first match */
127} 139}
128 140
141#ifdef CONFIG_NO_IDLE_HZ
142static int pxa_dyn_tick_enable_disable(void)
143{
144 /* nothing to do */
145 return 0;
146}
147
148static void pxa_dyn_tick_reprogram(unsigned long ticks)
149{
150 if (ticks > 1) {
151 initial_match = OSMR0;
152 OSMR0 = initial_match + ticks * LATCH;
153 match_posponed = 1;
154 }
155}
156
157static irqreturn_t
158pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
159{
160 if (match_posponed) {
161 match_posponed = 0;
162 OSMR0 = initial_match;
163 if ( (signed long)(initial_match - OSCR) <= 8 )
164 return pxa_timer_interrupt(irq, dev_id, regs);
165 }
166 return IRQ_NONE;
167}
168
169static struct dyn_tick_timer pxa_dyn_tick = {
170 .enable = pxa_dyn_tick_enable_disable,
171 .disable = pxa_dyn_tick_enable_disable,
172 .reprogram = pxa_dyn_tick_reprogram,
173 .handler = pxa_dyn_tick_handler,
174};
175#endif
176
129#ifdef CONFIG_PM 177#ifdef CONFIG_PM
130static unsigned long osmr[4], oier; 178static unsigned long osmr[4], oier;
131 179
@@ -161,4 +209,7 @@ struct sys_timer pxa_timer = {
161 .suspend = pxa_timer_suspend, 209 .suspend = pxa_timer_suspend,
162 .resume = pxa_timer_resume, 210 .resume = pxa_timer_resume,
163 .offset = pxa_gettimeoffset, 211 .offset = pxa_gettimeoffset,
212#ifdef CONFIG_NO_IDLE_HZ
213 .dyn_tick = &pxa_dyn_tick,
214#endif
164}; 215};