提交 193c3cc1 编写于 作者: R Russell King 提交者: Russell King

[ARM] Fix timer damage from d3d74453

Move the xtime write mode seqlock into timer_tick(), so it only
surrounds the call to do_timer().

This avoids a deadlock in update_process_times() ...
hrtimer_get_softirq_time() which tries to get a read mode seqlock
on xtime, thereby preventing booting.
Signed-off-by: NRussell King <rmk+kernel@arm.linux.org.uk>
上级 6232be32
...@@ -325,7 +325,9 @@ void timer_tick(void) ...@@ -325,7 +325,9 @@ void timer_tick(void)
profile_tick(CPU_PROFILING); profile_tick(CPU_PROFILING);
do_leds(); do_leds();
do_set_rtc(); do_set_rtc();
write_seqlock(&xtime_lock);
do_timer(1); do_timer(1);
write_sequnlock(&xtime_lock);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs())); update_process_times(user_mode(get_irq_regs()));
#endif #endif
......
...@@ -130,13 +130,9 @@ static irqreturn_t ...@@ -130,13 +130,9 @@ static irqreturn_t
aaec2000_timer_interrupt(int irq, void *dev_id) aaec2000_timer_interrupt(int irq, void *dev_id)
{ {
/* TODO: Check timer accuracy */ /* TODO: Check timer accuracy */
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
TIMER1_CLEAR = 1; TIMER1_CLEAR = 1;
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -50,9 +50,7 @@ static unsigned long clps711x_gettimeoffset(void) ...@@ -50,9 +50,7 @@ static unsigned long clps711x_gettimeoffset(void)
static irqreturn_t static irqreturn_t
p720t_timer_interrupt(int irq, void *dev_id) p720t_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -298,8 +298,6 @@ extern unsigned long ioc_timer_gettimeoffset(void); ...@@ -298,8 +298,6 @@ extern unsigned long ioc_timer_gettimeoffset(void);
static irqreturn_t static irqreturn_t
clps7500_timer_interrupt(int irq, void *dev_id) clps7500_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
/* Why not using do_leds interface?? */ /* Why not using do_leds interface?? */
...@@ -313,8 +311,6 @@ clps7500_timer_interrupt(int irq, void *dev_id) ...@@ -313,8 +311,6 @@ clps7500_timer_interrupt(int irq, void *dev_id)
} }
} }
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -178,8 +178,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) ...@@ -178,8 +178,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
{ {
u32 count; u32 count;
write_seqlock(&xtime_lock);
/* latch and read timer 1 */ /* latch and read timer 1 */
__raw_writeb(0x40, PIT_CTRL); __raw_writeb(0x40, PIT_CTRL);
count = __raw_readb(PIT_T1); count = __raw_readb(PIT_T1);
...@@ -192,8 +190,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id) ...@@ -192,8 +190,6 @@ ebsa110_timer_interrupt(int irq, void *dev_id)
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -99,8 +99,6 @@ static unsigned int last_jiffy_time; ...@@ -99,8 +99,6 @@ static unsigned int last_jiffy_time;
static int ep93xx_timer_interrupt(int irq, void *dev_id) static int ep93xx_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
__raw_writel(1, EP93XX_TIMER1_CLEAR); __raw_writel(1, EP93XX_TIMER1_CLEAR);
while ((signed long) while ((signed long)
(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time) (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
...@@ -109,8 +107,6 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id) ...@@ -109,8 +107,6 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id)
timer_tick(); timer_tick();
} }
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -30,14 +30,10 @@ static unsigned long timer1_gettimeoffset (void) ...@@ -30,14 +30,10 @@ static unsigned long timer1_gettimeoffset (void)
static irqreturn_t static irqreturn_t
timer1_interrupt(int irq, void *dev_id) timer1_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
*CSR_TIMER1_CLR = 0; *CSR_TIMER1_CLR = 0;
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -64,9 +64,7 @@ static unsigned long isa_gettimeoffset(void) ...@@ -64,9 +64,7 @@ static unsigned long isa_gettimeoffset(void)
static irqreturn_t static irqreturn_t
isa_timer_interrupt(int irq, void *dev_id) isa_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -29,13 +29,9 @@ ...@@ -29,13 +29,9 @@
static irqreturn_t static irqreturn_t
h7201_timer_interrupt(int irq, void *dev_id) h7201_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -113,9 +113,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc) ...@@ -113,9 +113,7 @@ h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc)
mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT); mask = CPU_REG (TIMER_VIRT, TIMER_TOPSTAT);
if ( mask & TSTAT_T0INT ) { if ( mask & TSTAT_T0INT ) {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
if( mask == TSTAT_T0INT ) if( mask == TSTAT_T0INT )
return; return;
} }
......
...@@ -250,8 +250,6 @@ unsigned long integrator_gettimeoffset(void) ...@@ -250,8 +250,6 @@ unsigned long integrator_gettimeoffset(void)
static irqreturn_t static irqreturn_t
integrator_timer_interrupt(int irq, void *dev_id) integrator_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
/* /*
* clear the interrupt * clear the interrupt
*/ */
...@@ -259,8 +257,6 @@ integrator_timer_interrupt(int irq, void *dev_id) ...@@ -259,8 +257,6 @@ integrator_timer_interrupt(int irq, void *dev_id)
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -206,8 +206,6 @@ unsigned long ixp2000_gettimeoffset (void) ...@@ -206,8 +206,6 @@ unsigned long ixp2000_gettimeoffset (void)
static int ixp2000_timer_interrupt(int irq, void *dev_id) static int ixp2000_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
/* clear timer 1 */ /* clear timer 1 */
ixp2000_reg_wrb(IXP2000_T1_CLR, 1); ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
...@@ -217,8 +215,6 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id) ...@@ -217,8 +215,6 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id)
next_jiffy_time -= ticks_per_jiffy; next_jiffy_time -= ticks_per_jiffy;
} }
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -70,10 +70,7 @@ static unsigned long ks8695_gettimeoffset (void) ...@@ -70,10 +70,7 @@ static unsigned long ks8695_gettimeoffset (void)
*/ */
static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id) static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -41,13 +41,9 @@ ...@@ -41,13 +41,9 @@
static irqreturn_t static irqreturn_t
lh7a40x_timer_interrupt(int irq, void *dev_id) lh7a40x_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
TIMER_EOI = 0; TIMER_EOI = 0;
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -45,8 +45,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) ...@@ -45,8 +45,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
{ {
unsigned int next_match; unsigned int next_match;
write_seqlock(&xtime_lock);
if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) { if (__raw_readl(MXC_GPT_GPTSR) & GPTSR_OF1) {
do { do {
timer_tick(); timer_tick();
...@@ -57,8 +55,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) ...@@ -57,8 +55,6 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
__raw_readl(MXC_GPT_GPTCNT)) <= 0); __raw_readl(MXC_GPT_GPTCNT)) <= 0);
} }
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -33,12 +33,8 @@ ...@@ -33,12 +33,8 @@
static irqreturn_t static irqreturn_t
netx_timer_interrupt(int irq, void *dev_id) netx_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
/* acknowledge interrupt */ /* acknowledge interrupt */
writel(COUNTER_BIT(0), NETX_GPIO_IRQ); writel(COUNTER_BIT(0), NETX_GPIO_IRQ);
......
...@@ -40,13 +40,9 @@ static inline void omap2_gp_timer_start(unsigned long load_val) ...@@ -40,13 +40,9 @@ static inline void omap2_gp_timer_start(unsigned long load_val)
static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW); omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -51,8 +51,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) ...@@ -51,8 +51,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
{ {
if (__raw_readl(HSTIM_INT) & MATCH0_INT) { if (__raw_readl(HSTIM_INT) & MATCH0_INT) {
write_seqlock(&xtime_lock);
do { do {
timer_tick(); timer_tick();
...@@ -73,8 +71,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id) ...@@ -73,8 +71,6 @@ static irqreturn_t pnx4008_timer_interrupt(int irq, void *dev_id)
} while ((signed) } while ((signed)
(__raw_readl(HSTIM_MATCH0) - (__raw_readl(HSTIM_MATCH0) -
__raw_readl(HSTIM_COUNTER)) < 0); __raw_readl(HSTIM_COUNTER)) < 0);
write_sequnlock(&xtime_lock);
} }
return IRQ_HANDLED; return IRQ_HANDLED;
......
...@@ -530,8 +530,6 @@ static unsigned long realview_gettimeoffset(void) ...@@ -530,8 +530,6 @@ static unsigned long realview_gettimeoffset(void)
*/ */
static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
// ...clear the interrupt // ...clear the interrupt
writel(1, TIMER0_VA_BASE + TIMER_INTCLR); writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
...@@ -542,8 +540,6 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id) ...@@ -542,8 +540,6 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id)
update_process_times(user_mode(get_irq_regs())); update_process_times(user_mode(get_irq_regs()));
#endif #endif
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -62,8 +62,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) ...@@ -62,8 +62,6 @@ sa1100_timer_interrupt(int irq, void *dev_id)
{ {
unsigned int next_match; unsigned int next_match;
write_seqlock(&xtime_lock);
#ifdef CONFIG_NO_IDLE_HZ #ifdef CONFIG_NO_IDLE_HZ
if (match_posponed) { if (match_posponed) {
match_posponed = 0; match_posponed = 0;
...@@ -85,8 +83,6 @@ sa1100_timer_interrupt(int irq, void *dev_id) ...@@ -85,8 +83,6 @@ sa1100_timer_interrupt(int irq, void *dev_id)
next_match = (OSMR0 += LATCH); next_match = (OSMR0 += LATCH);
} while ((signed long)(next_match - OSCR) <= 0); } while ((signed long)(next_match - OSCR) <= 0);
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
...@@ -82,9 +82,7 @@ static void __init shark_map_io(void) ...@@ -82,9 +82,7 @@ static void __init shark_map_io(void)
static irqreturn_t static irqreturn_t
shark_timer_interrupt(int irq, void *dev_id) shark_timer_interrupt(int irq, void *dev_id)
{ {
write_seqlock(&xtime_lock);
timer_tick(); timer_tick();
write_sequnlock(&xtime_lock);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册