-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ARM: 8011/1: ARM hibernation / suspend-to-disk
Enable hibernation for ARM architectures and provide ARM architecture specific calls used during hibernation. The swsusp hibernation framework depends on the platform first having functional suspend/resume. Then, in order to enable hibernation on a given platform, a platform_hibernation_ops structure may need to be registered with the system in order to save/restore any SoC-specific / cpu specific state needing (re)init over a suspend-to-disk/resume-from-disk cycle. For example: - "secure" SoCs that have different sets of control registers and/or different CR reg access patterns. - SoCs with L2 caches as the activation sequence there is SoC-dependent; a full off-on cycle for L2 is not done by the hibernation support code. - SoCs requiring steps on wakeup _before_ the "generic" parts done by cpu_suspend / cpu_resume can work correctly. - SoCs having persistent state which is maintained during suspend and resume, but will be lost during the power off cycle after suspend-to-disk. This is a rebase/rework of Frank Hofmann's v5 hibernation patchset. Acked-by: Russ Dill <Russ.Dill@ti.com> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> Signed-off-by: Sebastian Capella <sebastian.capella@linaro.org> Acked-by: Pavel Machek <pavel@ucw.cz> Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> [fixed duplicate virt_to_pfn() definition --rmk] Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
- Loading branch information
Sebastian Capella
authored and
Russell King
committed
Apr 23, 2014
1 parent
44ae903
commit 603fb42
Showing
4 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Hibernation support specific for ARM | ||
* | ||
* Derived from work on ARM hibernation support by: | ||
* | ||
* Ubuntu project, hibernation support for mach-dove | ||
* Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu) | ||
* Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.) | ||
* https://lkml.org/lkml/2010/6/18/4 | ||
* https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html | ||
* https://patchwork.kernel.org/patch/96442/ | ||
* | ||
* Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> | ||
* | ||
* License terms: GNU General Public License (GPL) version 2 | ||
*/ | ||
|
||
#include <linux/mm.h> | ||
#include <linux/suspend.h> | ||
#include <asm/system_misc.h> | ||
#include <asm/idmap.h> | ||
#include <asm/suspend.h> | ||
#include <asm/memory.h> | ||
|
||
extern const void __nosave_begin, __nosave_end; | ||
|
||
int pfn_is_nosave(unsigned long pfn) | ||
{ | ||
unsigned long nosave_begin_pfn = virt_to_pfn(&__nosave_begin); | ||
unsigned long nosave_end_pfn = virt_to_pfn(&__nosave_end - 1); | ||
|
||
return (pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn); | ||
} | ||
|
||
void notrace save_processor_state(void) | ||
{ | ||
WARN_ON(num_online_cpus() != 1); | ||
local_fiq_disable(); | ||
} | ||
|
||
void notrace restore_processor_state(void) | ||
{ | ||
local_fiq_enable(); | ||
} | ||
|
||
/* | ||
* Snapshot kernel memory and reset the system. | ||
* | ||
* swsusp_save() is executed in the suspend finisher so that the CPU | ||
* context pointer and memory are part of the saved image, which is | ||
* required by the resume kernel image to restart execution from | ||
* swsusp_arch_suspend(). | ||
* | ||
* soft_restart is not technically needed, but is used to get success | ||
* returned from cpu_suspend. | ||
* | ||
* When soft reboot completes, the hibernation snapshot is written out. | ||
*/ | ||
static int notrace arch_save_image(unsigned long unused) | ||
{ | ||
int ret; | ||
|
||
ret = swsusp_save(); | ||
if (ret == 0) | ||
soft_restart(virt_to_phys(cpu_resume)); | ||
return ret; | ||
} | ||
|
||
/* | ||
* Save the current CPU state before suspend / poweroff. | ||
*/ | ||
int notrace swsusp_arch_suspend(void) | ||
{ | ||
return cpu_suspend(0, arch_save_image); | ||
} | ||
|
||
/* | ||
* Restore page contents for physical pages that were in use during loading | ||
* hibernation image. Switch to idmap_pgd so the physical page tables | ||
* are overwritten with the same contents. | ||
*/ | ||
static void notrace arch_restore_image(void *unused) | ||
{ | ||
struct pbe *pbe; | ||
|
||
cpu_switch_mm(idmap_pgd, &init_mm); | ||
for (pbe = restore_pblist; pbe; pbe = pbe->next) | ||
copy_page(pbe->orig_address, pbe->address); | ||
|
||
soft_restart(virt_to_phys(cpu_resume)); | ||
} | ||
|
||
static u64 resume_stack[PAGE_SIZE/2/sizeof(u64)] __nosavedata; | ||
|
||
/* | ||
* Resume from the hibernation image. | ||
* Due to the kernel heap / data restore, stack contents change underneath | ||
* and that would make function calls impossible; switch to a temporary | ||
* stack within the nosave region to avoid that problem. | ||
*/ | ||
int swsusp_arch_resume(void) | ||
{ | ||
extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); | ||
call_with_stack(arch_restore_image, 0, | ||
resume_stack + ARRAY_SIZE(resume_stack)); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters