diff options
author | Peter Robinson <pbrobinson@gmail.com> | 2019-02-17 14:11:06 +0000 |
---|---|---|
committer | Peter Robinson <pbrobinson@gmail.com> | 2019-02-17 14:11:06 +0000 |
commit | e603107af63bd40304d5eab3b1cdf374eeb349d1 (patch) | |
tree | 94611d74d124df9bf41731c18bbb5090e2252ec6 /arm-omap4-fix-lack-of-time-interupts-after-hotplug.patch | |
parent | 473f80087b12e8787f1ac5bb1c959ac7eaaaedc6 (diff) | |
download | kernel-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.patch | 75 |
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 |