[ARM] Fix timer damage from d3d74453c3
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: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
parent
6232be32af
commit
193c3cc125
|
@ -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
|
||||||
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)
|
||||||
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);
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_sequnlock(&xtime_lock);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
timer_tick();
|
timer_tick();
|
||||||
|
|
||||||
write_sequnlock(&xtime_lock);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
timer_tick();
|
timer_tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
write_sequnlock(&xtime_lock);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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 @@
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
timer_tick();
|
timer_tick();
|
||||||
|
|
||||||
write_sequnlock(&xtime_lock);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
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)
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
__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 @@
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
} 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)
|
||||||
*/
|
*/
|
||||||
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)
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user