Commit 43262178 authored by Finn Thain's avatar Finn Thain Committed by Geert Uytterhoeven
Browse files

m68k: mvme147,mvme16x: Don't wipe PCC timer config bits



Don't clear the timer 1 configuration bits when clearing the interrupt flag
and counter overflow. As Michael reported, "This results in no timer
interrupts being delivered after the first. Initialization then hangs
in calibrate_delay as the jiffies counter is not updated."

On mvme16x, enable the timer after requesting the irq, consistent with
mvme147.

Cc: Michael Pavone <pavone@retrodev.com>
Fixes: 7529b90d ("m68k: mvme147: Handle timer counter overflow")
Fixes: 19999a8b ("m68k: mvme16x: Handle timer counter overflow")
Reported-and-tested-by: default avatarMichael Pavone <pavone@retrodev.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Link: https://lore.kernel.org/r/4fdaa113db089b8fb607f7dd818479f8cdcc4547.1617089871.git.fthain@telegraphics.com.au


Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
parent cbfa72b5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,9 @@ struct pcc_regs {
#define PCC_INT_ENAB		0x08

#define PCC_TIMER_INT_CLR	0x80

#define PCC_TIMER_TIC_EN	0x01
#define PCC_TIMER_COC_EN	0x02
#define PCC_TIMER_CLR_OVF	0x04

#define PCC_LEVEL_ABORT		0x07
+8 −6
Original line number Diff line number Diff line
@@ -114,8 +114,10 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
	unsigned long flags;

	local_irq_save(flags);
	m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;
	m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF;
	m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF | PCC_TIMER_COC_EN |
			     PCC_TIMER_TIC_EN;
	m147_pcc->t1_int_cntrl = PCC_INT_ENAB | PCC_TIMER_INT_CLR |
				 PCC_LEVEL_TIMER1;
	clk_total += PCC_TIMER_CYCLES;
	legacy_timer_tick(1);
	local_irq_restore(flags);
@@ -133,10 +135,10 @@ void mvme147_sched_init (void)
	/* Init the clock with a value */
	/* The clock counter increments until 0xFFFF then reloads */
	m147_pcc->t1_preload = PCC_TIMER_PRELOAD;
	m147_pcc->t1_cntrl = 0x0;	/* clear timer */
	m147_pcc->t1_cntrl = 0x3;	/* start timer */
	m147_pcc->t1_int_cntrl = PCC_TIMER_INT_CLR;  /* clear pending ints */
	m147_pcc->t1_int_cntrl = PCC_INT_ENAB|PCC_LEVEL_TIMER1;
	m147_pcc->t1_cntrl = PCC_TIMER_CLR_OVF | PCC_TIMER_COC_EN |
			     PCC_TIMER_TIC_EN;
	m147_pcc->t1_int_cntrl = PCC_INT_ENAB | PCC_TIMER_INT_CLR |
				 PCC_LEVEL_TIMER1;

	clocksource_register_hz(&mvme147_clk, PCC_TIMER_CLOCK_FREQ);
}
+8 −6
Original line number Diff line number Diff line
@@ -366,6 +366,7 @@ static u32 clk_total;
#define PCCTOVR1_COC_EN      0x02
#define PCCTOVR1_OVR_CLR     0x04

#define PCCTIC1_INT_LEVEL    6
#define PCCTIC1_INT_CLR      0x08
#define PCCTIC1_INT_EN       0x10

@@ -374,8 +375,8 @@ static irqreturn_t mvme16x_timer_int (int irq, void *dev_id)
	unsigned long flags;

	local_irq_save(flags);
	out_8(PCCTIC1, in_8(PCCTIC1) | PCCTIC1_INT_CLR);
	out_8(PCCTOVR1, PCCTOVR1_OVR_CLR);
	out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN);
	out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL);
	clk_total += PCC_TIMER_CYCLES;
	legacy_timer_tick(1);
	local_irq_restore(flags);
@@ -389,14 +390,15 @@ void mvme16x_sched_init(void)
    int irq;

    /* Using PCCchip2 or MC2 chip tick timer 1 */
    out_be32(PCCTCNT1, 0);
    out_be32(PCCTCMP1, PCC_TIMER_CYCLES);
    out_8(PCCTOVR1, in_8(PCCTOVR1) | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN);
    out_8(PCCTIC1, PCCTIC1_INT_EN | 6);
    if (request_irq(MVME16x_IRQ_TIMER, mvme16x_timer_int, IRQF_TIMER, "timer",
                    NULL))
	panic ("Couldn't register timer int");

    out_be32(PCCTCNT1, 0);
    out_be32(PCCTCMP1, PCC_TIMER_CYCLES);
    out_8(PCCTOVR1, PCCTOVR1_OVR_CLR | PCCTOVR1_TIC_EN | PCCTOVR1_COC_EN);
    out_8(PCCTIC1, PCCTIC1_INT_EN | PCCTIC1_INT_CLR | PCCTIC1_INT_LEVEL);

    clocksource_register_hz(&mvme16x_clk, PCC_TIMER_CLOCK_FREQ);

    if (brdno == 0x0162 || brdno == 0x172)