Messages in this thread | | | Subject | Re: [PATCH 2/2] clocksource/drivers/fttmr010: Be stricter on IRQs | From | Daniel Lezcano <> | Date | Fri, 20 Aug 2021 10:53:22 +0200 |
| |
On 25/07/2021 00:44, Linus Walleij wrote: > Make sure we check that the right interrupt occurred before > calling the event handler for timer 1. Report spurious IRQs > as IRQ_NONE.
Does it not mean there is something wrong with the initial setup ?
> 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"); >
-- <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
Follow Linaro: <http://www.facebook.com/pages/Linaro> Facebook | <http://twitter.com/#!/linaroorg> Twitter | <http://www.linaro.org/linaro-blog/> Blog
| |