diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2013-06-12 07:30:27 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-06-20 08:52:23 -0400 |
commit | 8b6fd652641e5ab1892d092e73e83d49291ed638 (patch) | |
tree | 3ef2acb3f277c0f5ade0f844ec752fd9bd3b1b08 /drivers | |
parent | 0abb6aeacc20822cd7baee82fd3b61169ca3f32e (diff) |
irqchip: gic: call gic_cpu_init() as well in CPU_STARTING_FROZEN case
Commit c011470 (irqchip: gic: Perform the gic_secondary_init() call via
CPU notifier) moves gic_secondary_init() that used to be called in
.smp_secondary_init hook into a notifier call. But it changes the
system behavior a little bit. Before the commit, gic_cpu_init()
is called not only when kernel brings up the secondary cores but also
when system resuming procedure hot-plugs the cores back to kernel.
While after the commit, the function will not be called in the latter
case, where the 'action' will not be CPU_STARTING but
CPU_STARTING_FROZEN. This behavior difference at least causes the
following suspend/resume regression on imx6q.
$ echo mem > /sys/power/state
PM: Syncing filesystems ... done.
PM: Preparing system for mem sleep
mmc1: card e624 removed
Freezing user space processes ... (elapsed 0.01 seconds) done.
Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
PM: Entering mem sleep
PM: suspend of devices complete after 5.930 msecs
PM: suspend devices took 0.010 seconds
PM: late suspend of devices complete after 0.343 msecs
PM: noirq suspend of devices complete after 0.828 msecs
Disabling non-boot CPUs ...
CPU1: shutdown
CPU2: shutdown
CPU3: shutdown
Enabling non-boot CPUs ...
CPU1: Booted secondary processor
INFO: rcu_sched detected stalls on CPUs/tasks: { 1 2 3} (detected by 0, t=2102 jiffies, g=4294967169, c=4294967168, q=17)
Task dump for CPU 1:
swapper/1 R running 0 0 1 0x00000000
Backtrace:
[<bf895ff4>] (0xbf895ff4) from [<00000000>] ( (null))
Backtrace aborted due to bad frame pointer <8007ccdc>
Task dump for CPU 2:
swapper/2 R running 0 0 1 0x00000000
Backtrace:
[<8075dbdc>] (0x8075dbdc) from [<00000000>] ( (null))
Backtrace aborted due to bad frame pointer <00000002>
Task dump for CPU 3:
swapper/3 R running 0 0 1 0x00000000
Backtrace:
[<8075dbdc>] (0x8075dbdc) from [<00000000>] ( (null))
Fix the regression by checking 'action' being CPU_STARTING_FROZEN to
have gic_cpu_init() called for secondary cores when system resumes.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Joseph Lo <josephl@nvidia.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/irqchip/irq-gic.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 1760ceb68b7b..19ceaa60e0f4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c | |||
@@ -705,7 +705,7 @@ static int gic_irq_domain_xlate(struct irq_domain *d, | |||
705 | static int __cpuinit gic_secondary_init(struct notifier_block *nfb, | 705 | static int __cpuinit gic_secondary_init(struct notifier_block *nfb, |
706 | unsigned long action, void *hcpu) | 706 | unsigned long action, void *hcpu) |
707 | { | 707 | { |
708 | if (action == CPU_STARTING) | 708 | if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) |
709 | gic_cpu_init(&gic_data[0]); | 709 | gic_cpu_init(&gic_data[0]); |
710 | return NOTIFY_OK; | 710 | return NOTIFY_OK; |
711 | } | 711 | } |