summaryrefslogtreecommitdiffstats
path: root/arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch
diff options
context:
space:
mode:
authorPeter Robinson <pbrobinson@gmail.com>2019-02-17 14:11:06 +0000
committerPeter Robinson <pbrobinson@gmail.com>2019-02-17 14:11:06 +0000
commite603107af63bd40304d5eab3b1cdf374eeb349d1 (patch)
tree94611d74d124df9bf41731c18bbb5090e2252ec6 /arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch
parent473f80087b12e8787f1ac5bb1c959ac7eaaaedc6 (diff)
downloadkernel-e603107af63bd40304d5eab3b1cdf374eeb349d1.tar.gz
kernel-e603107af63bd40304d5eab3b1cdf374eeb349d1.tar.xz
kernel-e603107af63bd40304d5eab3b1cdf374eeb349d1.zip
arm: omap4: fix some cpuidle/display issues
Diffstat (limited to 'arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch')
-rw-r--r--arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch75
1 files changed, 75 insertions, 0 deletions
diff --git a/arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch b/arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch
new file mode 100644
index 000000000..8a2e8751b
--- /dev/null
+++ b/arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch
@@ -0,0 +1,75 @@
+From 50d6b3cf9403879911e06d69c7ef41e43f8f7b4b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Wed, 12 Dec 2018 11:49:47 +0000
+Subject: ARM: OMAP2+: fix lack of timer interrupts on CPU1 after hotplug
+
+If we have a kernel configured for periodic timer interrupts, and we
+have cpuidle enabled, then we end up with CPU1 losing timer interupts
+after a hotplug.
+
+This can manifest itself in RCU stall warnings, or userspace becoming
+unresponsive.
+
+The problem is that the kernel initially wants to use the TWD timer
+for interrupts, but the TWD loses context when we enter the C3 cpuidle
+state. Nothing reprograms the TWD after idle.
+
+We have solved this in the past by switching to broadcast timer ticks,
+and cpuidle44xx switches to that mode at boot time. However, there is
+nothing to switch from periodic mode local timers after a hotplug
+operation.
+
+We call tick_broadcast_enter() in omap_enter_idle_coupled(), which one
+would expect would take care of the issue, but internally this only
+deals with one-shot local timers - tick_broadcast_enable() on the other
+hand only deals with periodic local timers. So, we need to call both.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+[tony@atomide.com: just standardized the subject line]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+---
+ arch/arm/mach-omap2/cpuidle44xx.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
+index a8b291f00109..dae514c8276a 100644
+--- a/arch/arm/mach-omap2/cpuidle44xx.c
++++ b/arch/arm/mach-omap2/cpuidle44xx.c
+@@ -152,6 +152,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
+ mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
+ (cx->mpu_logic_state == PWRDM_POWER_OFF);
+
++ /* Enter broadcast mode for periodic timers */
++ tick_broadcast_enable();
++
++ /* Enter broadcast mode for one-shot timers */
+ tick_broadcast_enter();
+
+ /*
+@@ -218,15 +222,6 @@ fail:
+ return index;
+ }
+
+-/*
+- * For each cpu, setup the broadcast timer because local timers
+- * stops for the states above C1.
+- */
+-static void omap_setup_broadcast_timer(void *arg)
+-{
+- tick_broadcast_enable();
+-}
+-
+ static struct cpuidle_driver omap4_idle_driver = {
+ .name = "omap4_idle",
+ .owner = THIS_MODULE,
+@@ -319,8 +314,5 @@ int __init omap4_idle_init(void)
+ if (!cpu_clkdm[0] || !cpu_clkdm[1])
+ return -ENODEV;
+
+- /* Configure the broadcast timer on each cpu */
+- on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
+-
+ return cpuidle_register(idle_driver, cpu_online_mask);
+ }
+--
+cgit 1.2-0.3.lf.el7