| From fe69a77b14290d4860fdc4dc8cee17901a574b34 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 30 Mar 2021 18:37:51 +1100 |
| Subject: m68k: mvme147,mvme16x: Don't wipe PCC timer config bits |
| |
| From: Finn Thain <fthain@telegraphics.com.au> |
| |
| [ Upstream commit 43262178c043032e7c42d00de44c818ba05f9967 ] |
| |
| 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: 7529b90d051e ("m68k: mvme147: Handle timer counter overflow") |
| Fixes: 19999a8b8782 ("m68k: mvme16x: Handle timer counter overflow") |
| Reported-and-tested-by: Michael Pavone <pavone@retrodev.com> |
| Signed-off-by: Finn Thain <fthain@telegraphics.com.au> |
| Link: https://lore.kernel.org/r/4fdaa113db089b8fb607f7dd818479f8cdcc4547.1617089871.git.fthain@telegraphics.com.au |
| Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/m68k/include/asm/mvme147hw.h | 3 +++ |
| arch/m68k/mvme147/config.c | 14 ++++++++------ |
| arch/m68k/mvme16x/config.c | 14 ++++++++------ |
| 3 files changed, 19 insertions(+), 12 deletions(-) |
| |
| diff --git a/arch/m68k/include/asm/mvme147hw.h b/arch/m68k/include/asm/mvme147hw.h |
| index 257b29184af9..e28eb1c0e0bf 100644 |
| --- a/arch/m68k/include/asm/mvme147hw.h |
| +++ b/arch/m68k/include/asm/mvme147hw.h |
| @@ -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 |
| diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c |
| index cfdc7f912e14..e1e90c49a496 100644 |
| --- a/arch/m68k/mvme147/config.c |
| +++ b/arch/m68k/mvme147/config.c |
| @@ -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); |
| } |
| diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c |
| index 30357fe4ba6c..b59593c7cfb9 100644 |
| --- a/arch/m68k/mvme16x/config.c |
| +++ b/arch/m68k/mvme16x/config.c |
| @@ -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) |
| -- |
| 2.30.2 |
| |