[ARM] 2864/1: VST aka CONFIG_NO_IDLE_HZ support for SA11x0
Patch from Nicolas Pitre Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
20e9126808
commit
569d2c34dc
|
@ -365,8 +365,8 @@ config NO_IDLE_HZ
|
||||||
|
|
||||||
Please note that dynamic tick may affect the accuracy of
|
Please note that dynamic tick may affect the accuracy of
|
||||||
timekeeping on some platforms depending on the implementation.
|
timekeeping on some platforms depending on the implementation.
|
||||||
Currently at least OMAP and PXA2xx platforms are known to have
|
Currently at least OMAP, PXA2xx and SA11x0 platforms are known
|
||||||
accurate timekeeping with dynamic tick.
|
to have accurate timekeeping with dynamic tick.
|
||||||
|
|
||||||
config ARCH_DISCONTIGMEM_ENABLE
|
config ARCH_DISCONTIGMEM_ENABLE
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -70,6 +70,11 @@ static unsigned long sa1100_gettimeoffset (void)
|
||||||
return usec;
|
return usec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NO_IDLE_HZ
|
||||||
|
static unsigned long initial_match;
|
||||||
|
static int match_posponed;
|
||||||
|
#endif
|
||||||
|
|
||||||
static irqreturn_t
|
static irqreturn_t
|
||||||
sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +82,13 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
|
|
||||||
write_seqlock(&xtime_lock);
|
write_seqlock(&xtime_lock);
|
||||||
|
|
||||||
|
#ifdef CONFIG_NO_IDLE_HZ
|
||||||
|
if (match_posponed) {
|
||||||
|
match_posponed = 0;
|
||||||
|
OSMR0 = initial_match;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop until we get ahead of the free running timer.
|
* Loop until we get ahead of the free running timer.
|
||||||
* This ensures an exact clock tick count and time accuracy.
|
* This ensures an exact clock tick count and time accuracy.
|
||||||
|
@ -119,6 +131,42 @@ static void __init sa1100_timer_init(void)
|
||||||
OSCR = 0; /* initialize free-running timer, force first match */
|
OSCR = 0; /* initialize free-running timer, force first match */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_NO_IDLE_HZ
|
||||||
|
static int sa1100_dyn_tick_enable_disable(void)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sa1100_dyn_tick_reprogram(unsigned long ticks)
|
||||||
|
{
|
||||||
|
if (ticks > 1) {
|
||||||
|
initial_match = OSMR0;
|
||||||
|
OSMR0 = initial_match + ticks * LATCH;
|
||||||
|
match_posponed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t
|
||||||
|
sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
if (match_posponed) {
|
||||||
|
match_posponed = 0;
|
||||||
|
OSMR0 = initial_match;
|
||||||
|
if ((signed long)(initial_match - OSCR) <= 0)
|
||||||
|
return sa1100_timer_interrupt(irq, dev_id, regs);
|
||||||
|
}
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dyn_tick_timer sa1100_dyn_tick = {
|
||||||
|
.enable = sa1100_dyn_tick_enable_disable,
|
||||||
|
.disable = sa1100_dyn_tick_enable_disable,
|
||||||
|
.reprogram = sa1100_dyn_tick_reprogram,
|
||||||
|
.handler = sa1100_dyn_tick_handler,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
unsigned long osmr[4], oier;
|
unsigned long osmr[4], oier;
|
||||||
|
|
||||||
|
@ -155,4 +203,7 @@ struct sys_timer sa1100_timer = {
|
||||||
.suspend = sa1100_timer_suspend,
|
.suspend = sa1100_timer_suspend,
|
||||||
.resume = sa1100_timer_resume,
|
.resume = sa1100_timer_resume,
|
||||||
.offset = sa1100_gettimeoffset,
|
.offset = sa1100_gettimeoffset,
|
||||||
|
#ifdef CONFIG_NO_IDLE_HZ
|
||||||
|
.dyn_tick = &sa1100_dyn_tick,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue