Skip to content

Commit

Permalink
ARM: kernel: update cpu_suspend code to use cache LoUIS operations
Browse files Browse the repository at this point in the history
In processors like A15/A7 L2 cache is unified and integrated within the
processor cache hierarchy, so that it is not considered an outer cache
anymore. For processors like A15/A7 flush_cache_all() ends up cleaning
all cache levels up to Level of Coherency (LoC) that includes
the L2 unified cache.

When a single CPU is suspended (CPU idle) a complete L2 clean is not
required, so generic cpu_suspend code must clean the data cache using the
newly introduced cache LoUIS function.

The context and stack pointer (context pointer) are cleaned to main memory
using cache area functions that operate on MVA and guarantee that the data
is written back to main memory (perform cache cleaning up to the Point of
Coherency - PoC) so that the processor can fetch the context when the MMU
is off in the cpu_resume code path.

outer_cache management remains unchanged.

Reviewed-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Tested-by: Shawn Guo <shawn.guo@linaro.org>
  • Loading branch information
Lorenzo Pieralisi committed Sep 25, 2012
1 parent 3287be8 commit dbee0c6
Showing 1 changed file with 16 additions and 1 deletion.
17 changes: 16 additions & 1 deletion arch/arm/kernel/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ extern void cpu_resume_mmu(void);
*/
void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
{
u32 *ctx = ptr;

*save_ptr = virt_to_phys(ptr);

/* This must correspond to the LDM in cpu_resume() assembly */
Expand All @@ -26,7 +28,20 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)

cpu_do_suspend(ptr);

flush_cache_all();
flush_cache_louis();

/*
* flush_cache_louis does not guarantee that
* save_ptr and ptr are cleaned to main memory,
* just up to the Level of Unification Inner Shareable.
* Since the context pointer and context itself
* are to be retrieved with the MMU off that
* data must be cleaned from all cache levels
* to main memory using "area" cache primitives.
*/
__cpuc_flush_dcache_area(ctx, ptrsz);
__cpuc_flush_dcache_area(save_ptr, sizeof(*save_ptr));

outer_clean_range(*save_ptr, *save_ptr + ptrsz);
outer_clean_range(virt_to_phys(save_ptr),
virt_to_phys(save_ptr) + sizeof(*save_ptr));
Expand Down

0 comments on commit dbee0c6

Please sign in to comment.