linux/arch/arm/kernel
Russell King 767bf7e7a1 ARM: fix broken hibernation
Normally, when a CPU wants to clear a cache line to zero in the external
L2 cache, it would generate bus cycles to write each word as it would do
with any other data access.

However, a Cortex A9 connected to a L2C-310 has a specific feature where
the CPU can detect this operation, and signal that it wants to zero an
entire cache line.  This feature, known as Full Line of Zeros (FLZ),
involves a non-standard AXI signalling mechanism which only the L2C-310
can properly interpret.

There are separate enable bits in both the L2C-310 and the Cortex A9 -
the L2C-310 needs to be enabled and have the FLZ enable bit set in the
auxiliary control register before the Cortex A9 has this feature
enabled.

Unfortunately, the suspend code was not respecting this - it's not
obvious from the code:

swsusp_arch_suspend()
 cpu_suspend() /* saves the Cortex A9 auxiliary control register */
  arch_save_image()
  soft_restart() /* turns off FLZ in Cortex A9, and disables L2C */
   cpu_resume() /* restores the Cortex A9 registers, inc auxcr */

At this point, we end up with the L2C disabled, but the Cortex A9 with
FLZ enabled - which means any memset() or zeroing of a full cache line
will fail to take effect.

A similar issue exists in the resume path, but it's slightly more
complex:

swsusp_arch_suspend()
 cpu_suspend() /* saves the Cortex A9 auxiliary control register */
  arch_save_image() /* image with A9 auxcr saved */
...
swsusp_arch_resume()
 call_with_stack()
  arch_restore_image() /* restores image with A9 auxcr saved above */
  soft_restart() /* turns off FLZ in Cortex A9, and disables L2C */
   cpu_resume() /* restores the Cortex A9 registers, inc auxcr */

Again, here we end up with the L2C disabled, but Cortex A9 FLZ enabled.

There's no need to turn off the L2C in either of these two paths; there
are benefits from not doing so - for example, the page copies will be
faster with the L2C enabled.

Hence, fix this by providing a variant of soft_restart() which can be
used without turning the L2 cache controller off, and use it in both
of these paths to keep the L2C enabled across the respective resume
transitions.

Fixes: 8ef418c717 ("ARM: l2c: trial at enabling some Cortex-A9 optimisations")
Reported-by: Sean Cross <xobs@kosagi.com>
Tested-by: Sean Cross <xobs@kosagi.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
2015-04-02 09:50:10 +01:00
..
.gitignore
arch_timer.c
armksyms.c ARM: 8151/1: add missing exports for asm functions required by get_user macro 2014-09-16 16:09:30 +01:00
arthur.c
asm-offsets.c ARM: Blacklist GCC 4.8.0 to GCC 4.8.2 - PR58854 2014-10-19 09:20:52 +01:00
atags_compat.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
atags_parse.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
atags_proc.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
atags.h
bios32.c ARM: 8293/1: kernel: fix pci_mmap_page_range() offset calculation 2015-02-23 14:43:58 +00:00
calls.S ARM: wire up execveat syscall 2015-01-07 20:31:54 +00:00
cpuidle.c
crash_dump.c ARM: 8012/1: kdump: Avoid overflow when converting pfn to physaddr 2014-04-07 12:10:00 +01:00
debug.S ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+ 2014-07-18 12:29:04 +01:00
devtree.c arm: Add devicetree fixup machine function 2014-07-29 21:26:49 -06:00
dma-isa.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
dma.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
early_printk.c
elf.c
entry-armv.S ARM: 8322/1: keep .text and .fixup regions closer together 2015-03-29 23:11:56 +01:00
entry-common.S ARM: move ftrace assembly code to separate file 2014-11-21 15:25:01 +00:00
entry-ftrace.S ARM: move ftrace assembly code to separate file 2014-11-21 15:25:01 +00:00
entry-header.S ARM: 8266/1: Remove early stack deallocation from restore_user_regs 2015-01-12 19:26:57 +00:00
entry-v7m.S ARM: 8295/1: fix v7M build for !CONFIG_PRINTK 2015-01-29 15:23:12 +00:00
fiq.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
fiqasm.S ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+ 2014-07-18 12:29:04 +01:00
ftrace.c ARM: kprobes: enable OPTPROBES for ARM 32 2015-01-13 16:10:17 +00:00
head-common.S ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+ 2014-07-18 12:29:04 +01:00
head-nommu.S ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+ 2014-07-18 12:29:04 +01:00
head.S ARM: 8314/1: replace PROCINFO embedded branch with relative offset 2015-03-28 15:46:14 +00:00
hibernate.c ARM: fix broken hibernation 2015-04-02 09:50:10 +01:00
hw_breakpoint.c ARM: removing support for etb/etm in "arch/arm/kernel/" 2014-11-07 15:19:33 -08:00
hyp-stub.S Here are the PPC and ARM changes for KVM, which I separated because 2014-08-07 11:35:30 -07:00
insn.c
io.c ARM: io.c: clean up EXPORT_SYMBOL()s 2014-11-21 15:25:02 +00:00
irq.c ARM: 8261/1: l2c: Get outer cache .write_sec callback from mach_desc only if not NULL 2015-01-16 14:35:33 +00:00
isa.c arm: convert use of typedef ctl_table to struct ctl_table 2014-06-06 16:08:15 -07:00
iwmmxt.S ARM: 8221/1: PJ4: allow building in Thumb-2 mode 2014-12-03 16:08:00 +00:00
jump_label.c ARM: kprobes: enable OPTPROBES for ARM 32 2015-01-13 16:10:17 +00:00
kgdb.c ARM: probes: move all probe code to dedicate directory 2015-01-09 09:36:50 +00:00
machine_kexec.c Merge branch 'devel-stable' into for-next 2014-12-05 16:30:54 +00:00
Makefile ARM: 8307/1: psci: move psci firmware calls out of line 2015-03-29 23:11:17 +01:00
module.c ARM: 8219/1: handle interworking and out-of-range relocations separately 2015-02-23 14:43:58 +00:00
opcodes.c
patch.c ARM: probes: move all probe code to dedicate directory 2015-01-09 09:36:50 +00:00
perf_callchain.c arm: perf: factor out callchain code 2014-10-30 12:16:58 +00:00
perf_event_cpu.c ARM: make of_device_ids const 2015-02-19 09:44:25 +01:00
perf_event_v6.c arm: perf: kill get_hw_events() 2014-10-30 12:17:00 +00:00
perf_event_v7.c arm: perf: kill get_hw_events() 2014-10-30 12:17:00 +00:00
perf_event_xscale.c arm: perf: kill get_hw_events() 2014-10-30 12:17:00 +00:00
perf_event.c ARM: 8255/1: perf: Prevent wraparound during overflow 2015-01-12 19:28:46 +00:00
perf_regs.c perf: Move task_pt_regs sampling into arch code 2015-01-09 11:12:28 +01:00
pj4-cp0.c ARM: 8040/1: pj4: properly detect existence of iWMMXt coprocessor 2014-04-25 12:07:34 +01:00
process.c ARM: fix broken hibernation 2015-04-02 09:50:10 +01:00
psci_smp.c ARM: Check if a CPU has gone offline 2014-05-15 10:16:30 -04:00
psci-call.S ARM: 8307/1: psci: move psci firmware calls out of line 2015-03-29 23:11:17 +01:00
psci.c ARM: 8307/1: psci: move psci firmware calls out of line 2015-03-29 23:11:17 +01:00
ptrace.c Merge git://git.infradead.org/users/eparis/audit 2014-10-19 16:25:56 -07:00
reboot.h ARM: fix broken hibernation 2015-04-02 09:50:10 +01:00
relocate_kernel.S ARM: convert all "mov.* pc, reg" to "bx reg" for ARMv6+ 2014-07-18 12:29:04 +01:00
return_address.c ARM: 8328/1: remove empty preprocessor #else branch 2015-03-28 16:54:53 +00:00
setup.c ARM: 8319/1: advertise availability of v8 Crypto instructions 2015-03-28 15:46:15 +00:00
signal.c all arches, signal: move restart_block to struct task_struct 2015-02-12 18:54:12 -08:00
sigreturn_codes.S ARM: 7895/1: signal: fix armv7-m build issue in sigreturn_codes.S 2013-11-30 22:21:00 +00:00
sleep.S ARM: 8324/1: move cpu_resume() to .text section 2015-03-29 23:11:57 +01:00
smp_scu.c ARM: 8122/1: smp_scu: enable SCU standby support 2014-08-02 08:51:53 +01:00
smp_tlb.c ARM: 8111/1: Enable erratum 798181 for Broadcom Brahma-B15 2014-07-24 14:40:26 +01:00
smp_twd.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
smp.c Revert "ARM: 7830/1: delay: don't bother reporting bogomips in /proc/cpuinfo" 2015-01-04 11:39:59 -08:00
stacktrace.c ARM: 8172/1: Use current_stack_pointer in save_stack_trace_tsk 2014-11-13 23:58:03 +00:00
suspend.c ARM: 8248/1: pm: remove outdated comment 2015-01-21 15:58:57 +00:00
swp_emulate.c ARM: 8322/1: keep .text and .fixup regions closer together 2015-03-29 23:11:56 +01:00
sys_arm.c
sys_oabi-compat.c separate kernel- and userland-side msghdr 2014-11-19 16:22:59 -05:00
tcm.c ARM: add permission annotations to MT_MEMORY* mapping types 2013-12-11 09:53:14 +00:00
thumbee.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
time.c ARM: 8072/1: time: Make use of arm_get_current_stackframe 2014-07-18 12:29:14 +01:00
topology.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00
traps.c Merge branches 'fixes', 'misc', 'pm' and 'sa1100' into for-next 2014-12-05 16:30:47 +00:00
unwind.c ARM: 8176/1: Use current_stack_pointer in unwind_backtrace 2014-11-13 23:58:09 +00:00
v7m.c
vmlinux.lds.S ARM: 8322/1: keep .text and .fixup regions closer together 2015-03-29 23:11:56 +01:00
xscale-cp0.c ARM: convert printk(KERN_* to pr_* 2014-11-21 15:24:50 +00:00