From: Greg Kroah-Hartman Date: Thu, 15 Sep 2016 17:21:40 +0000 (+0200) Subject: 4.7-stable patches X-Git-Tag: v4.4.22~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=efbaddd2edb09290ff2319c616ee688e086bb59d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.7-stable patches added patches: clocksource-drivers-sun4i-clear-interrupts-after-stopping-timer-in-probe-function.patch --- diff --git a/queue-4.7/clocksource-drivers-sun4i-clear-interrupts-after-stopping-timer-in-probe-function.patch b/queue-4.7/clocksource-drivers-sun4i-clear-interrupts-after-stopping-timer-in-probe-function.patch new file mode 100644 index 00000000000..c7f8a3631f5 --- /dev/null +++ b/queue-4.7/clocksource-drivers-sun4i-clear-interrupts-after-stopping-timer-in-probe-function.patch @@ -0,0 +1,62 @@ +From b53e7d000d9e6e9fd2c6eb6b82d2783c67fd599e Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 25 Aug 2016 14:26:59 +0800 +Subject: clocksource/drivers/sun4i: Clear interrupts after stopping timer in probe function + +From: Chen-Yu Tsai + +commit b53e7d000d9e6e9fd2c6eb6b82d2783c67fd599e upstream. + +The bootloader (U-boot) sometimes uses this timer for various delays. +It uses it as a ongoing counter, and does comparisons on the current +counter value. The timer counter is never stopped. + +In some cases when the user interacts with the bootloader, or lets +it idle for some time before loading Linux, the timer may expire, +and an interrupt will be pending. This results in an unexpected +interrupt when the timer interrupt is enabled by the kernel, at +which point the event_handler isn't set yet. This results in a NULL +pointer dereference exception, panic, and no way to reboot. + +Clear any pending interrupts after we stop the timer in the probe +function to avoid this. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Daniel Lezcano +Acked-by: Maxime Ripard +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clocksource/sun4i_timer.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/clocksource/sun4i_timer.c ++++ b/drivers/clocksource/sun4i_timer.c +@@ -123,12 +123,16 @@ static struct clock_event_device sun4i_c + .set_next_event = sun4i_clkevt_next_event, + }; + ++static void sun4i_timer_clear_interrupt(void) ++{ ++ writel(TIMER_IRQ_EN(0), timer_base + TIMER_IRQ_ST_REG); ++} + + static irqreturn_t sun4i_timer_interrupt(int irq, void *dev_id) + { + struct clock_event_device *evt = (struct clock_event_device *)dev_id; + +- writel(0x1, timer_base + TIMER_IRQ_ST_REG); ++ sun4i_timer_clear_interrupt(); + evt->event_handler(evt); + + return IRQ_HANDLED; +@@ -193,6 +197,9 @@ static void __init sun4i_timer_init(stru + /* Make sure timer is stopped before playing with interrupts */ + sun4i_clkevt_time_stop(0); + ++ /* clear timer0 interrupt */ ++ sun4i_timer_clear_interrupt(); ++ + sun4i_clockevent.cpumask = cpu_possible_mask; + sun4i_clockevent.irq = irq; + diff --git a/queue-4.7/series b/queue-4.7/series new file mode 100644 index 00000000000..b5988a897b2 --- /dev/null +++ b/queue-4.7/series @@ -0,0 +1 @@ +clocksource-drivers-sun4i-clear-interrupts-after-stopping-timer-in-probe-function.patch