Loading arch/arm/kernel/irq.c +2 −2 Original line number Diff line number Diff line Loading @@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) #ifdef CONFIG_NO_IDLE_HZ if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { write_seqlock(&xtime_lock); spin_lock(&system_timer->dyn_tick->lock); if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) system_timer->dyn_tick->handler(irq, 0, regs); write_sequnlock(&xtime_lock); spin_unlock(&system_timer->dyn_tick->lock); } #endif Loading arch/arm/kernel/time.c +17 −7 Original line number Diff line number Diff line Loading @@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void) int ret = -ENODEV; if (dyn_tick) { write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags); ret = 0; if (!(dyn_tick->state & DYN_TICK_ENABLED)) { ret = dyn_tick->enable(); Loading @@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void) if (ret == 0) dyn_tick->state |= DYN_TICK_ENABLED; } write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags); } return ret; Loading @@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void) int ret = -ENODEV; if (dyn_tick) { write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags); ret = 0; if (dyn_tick->state & DYN_TICK_ENABLED) { ret = dyn_tick->disable(); Loading @@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void) if (ret == 0) dyn_tick->state &= ~DYN_TICK_ENABLED; } write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags); } return ret; Loading @@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void) void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; unsigned long next, seq; unsigned long next, seq, flags; if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { if (!dyn_tick) return; spin_lock_irqsave(&dyn_tick->lock, flags); if (dyn_tick->state & DYN_TICK_ENABLED) { next = next_timer_interrupt(); do { seq = read_seqbegin(&xtime_lock); dyn_tick->reprogram(next_timer_interrupt() - jiffies); dyn_tick->reprogram(next - jiffies); } while (read_seqretry(&xtime_lock, seq)); } spin_unlock_irqrestore(&dyn_tick->lock, flags); } static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) Loading Loading @@ -499,5 +504,10 @@ void __init time_init(void) if (system_timer->offset == NULL) system_timer->offset = dummy_gettimeoffset; system_timer->init(); #ifdef CONFIG_NO_IDLE_HZ if (system_timer->dyn_tick) system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED; #endif } include/asm-arm/mach/time.h +1 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ struct sys_timer { #define DYN_TICK_ENABLED (1 << 1) struct dyn_tick_timer { spinlock_t lock; unsigned int state; /* Current state */ int (*enable)(void); /* Enables dynamic tick */ int (*disable)(void); /* Disables dynamic tick */ Loading Loading
arch/arm/kernel/irq.c +2 −2 Original line number Diff line number Diff line Loading @@ -342,10 +342,10 @@ __do_irq(unsigned int irq, struct irqaction *action, struct pt_regs *regs) #ifdef CONFIG_NO_IDLE_HZ if (!(action->flags & SA_TIMER) && system_timer->dyn_tick != NULL) { write_seqlock(&xtime_lock); spin_lock(&system_timer->dyn_tick->lock); if (system_timer->dyn_tick->state & DYN_TICK_ENABLED) system_timer->dyn_tick->handler(irq, 0, regs); write_sequnlock(&xtime_lock); spin_unlock(&system_timer->dyn_tick->lock); } #endif Loading
arch/arm/kernel/time.c +17 −7 Original line number Diff line number Diff line Loading @@ -379,7 +379,7 @@ static int timer_dyn_tick_enable(void) int ret = -ENODEV; if (dyn_tick) { write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags); ret = 0; if (!(dyn_tick->state & DYN_TICK_ENABLED)) { ret = dyn_tick->enable(); Loading @@ -387,7 +387,7 @@ static int timer_dyn_tick_enable(void) if (ret == 0) dyn_tick->state |= DYN_TICK_ENABLED; } write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags); } return ret; Loading @@ -400,7 +400,7 @@ static int timer_dyn_tick_disable(void) int ret = -ENODEV; if (dyn_tick) { write_seqlock_irqsave(&xtime_lock, flags); spin_lock_irqsave(&dyn_tick->lock, flags); ret = 0; if (dyn_tick->state & DYN_TICK_ENABLED) { ret = dyn_tick->disable(); Loading @@ -408,7 +408,7 @@ static int timer_dyn_tick_disable(void) if (ret == 0) dyn_tick->state &= ~DYN_TICK_ENABLED; } write_sequnlock_irqrestore(&xtime_lock, flags); spin_unlock_irqrestore(&dyn_tick->lock, flags); } return ret; Loading @@ -422,15 +422,20 @@ static int timer_dyn_tick_disable(void) void timer_dyn_reprogram(void) { struct dyn_tick_timer *dyn_tick = system_timer->dyn_tick; unsigned long next, seq; unsigned long next, seq, flags; if (dyn_tick && (dyn_tick->state & DYN_TICK_ENABLED)) { if (!dyn_tick) return; spin_lock_irqsave(&dyn_tick->lock, flags); if (dyn_tick->state & DYN_TICK_ENABLED) { next = next_timer_interrupt(); do { seq = read_seqbegin(&xtime_lock); dyn_tick->reprogram(next_timer_interrupt() - jiffies); dyn_tick->reprogram(next - jiffies); } while (read_seqretry(&xtime_lock, seq)); } spin_unlock_irqrestore(&dyn_tick->lock, flags); } static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) Loading Loading @@ -499,5 +504,10 @@ void __init time_init(void) if (system_timer->offset == NULL) system_timer->offset = dummy_gettimeoffset; system_timer->init(); #ifdef CONFIG_NO_IDLE_HZ if (system_timer->dyn_tick) system_timer->dyn_tick->lock = SPIN_LOCK_UNLOCKED; #endif }
include/asm-arm/mach/time.h +1 −0 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ struct sys_timer { #define DYN_TICK_ENABLED (1 << 1) struct dyn_tick_timer { spinlock_t lock; unsigned int state; /* Current state */ int (*enable)(void); /* Enables dynamic tick */ int (*disable)(void); /* Disables dynamic tick */ Loading