Messages in this thread Patch in this message | | | From | Linus Walleij <> | Subject | [PATCH 2/2] clocksource/drivers/fttmr010: Be stricter on IRQs | Date | Sun, 25 Jul 2021 00:44:24 +0200 |
| |
Make sure we check that the right interrupt occurred before calling the event handler for timer 1. Report spurious IRQs as IRQ_NONE.
Cc: Cédric Le Goater <clg@kaod.org> Cc: Joel Stanley <joel@jms.id.au> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- drivers/clocksource/timer-fttmr010.c | 32 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c index 126fb1f259b2..de29d424ec95 100644 --- a/drivers/clocksource/timer-fttmr010.c +++ b/drivers/clocksource/timer-fttmr010.c @@ -253,20 +253,36 @@ static int fttmr010_timer_set_periodic(struct clock_event_device *evt) */ static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = dev_id; + struct fttmr010 *fttmr010 = dev_id; + struct clock_event_device *evt = &fttmr010->clkevt; + u32 val; + + val = readl(fttmr010->base + TIMER_INTR_STATE); + if (val & (TIMER_1_INT_MATCH1 | TIMER_1_INT_OVERFLOW)) + evt->event_handler(evt); + else + /* Spurious IRQ */ + return IRQ_NONE; - evt->event_handler(evt); return IRQ_HANDLED; } static irqreturn_t ast2600_timer_interrupt(int irq, void *dev_id) { - struct clock_event_device *evt = dev_id; - struct fttmr010 *fttmr010 = to_fttmr010(evt); + struct fttmr010 *fttmr010 = dev_id; + struct clock_event_device *evt = &fttmr010->clkevt; + u32 val; - writel(0x1, fttmr010->base + TIMER_INTR_STATE); + val = readl(fttmr010->base + TIMER_INTR_STATE); + if (val & (TIMER_1_INT_MATCH1 | TIMER_1_INT_OVERFLOW)) { + writel(TIMER_1_INT_MATCH1, fttmr010->base + TIMER_INTR_STATE); + evt->event_handler(evt); + } else { + /* Just clear any spurious IRQs from the block */ + writel(val, fttmr010->base + TIMER_INTR_STATE); + return IRQ_NONE; + } - evt->event_handler(evt); return IRQ_HANDLED; } @@ -384,12 +400,12 @@ static int __init fttmr010_common_init(struct device_node *np, fttmr010->timer_shutdown = ast2600_timer_shutdown; ret = request_irq(irq, ast2600_timer_interrupt, IRQF_TIMER, "FTTMR010-TIMER1", - &fttmr010->clkevt); + fttmr010); } else { fttmr010->timer_shutdown = fttmr010_timer_shutdown; ret = request_irq(irq, fttmr010_timer_interrupt, IRQF_TIMER, "FTTMR010-TIMER1", - &fttmr010->clkevt); + fttmr010); } if (ret) { pr_err("FTTMR010-TIMER1 no IRQ\n"); -- 2.31.1
| |