ARM: pm: convert samsung platforms to generic suspend/resume support
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sun, 6 Feb 2011 17:39:31 +0000 (17:39 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Tue, 22 Feb 2011 17:11:25 +0000 (17:11 +0000)
Tested-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/mach-s3c64xx/sleep.S
arch/arm/mach-s5pv210/sleep.S
arch/arm/plat-s3c24xx/sleep.S
arch/arm/plat-samsung/include/plat/pm.h
arch/arm/plat-samsung/pm.c

index b2ef44317368a6f20d0baf5e005e2983c7b243a1..afe5a762f46e7cc48e4d5b704bf07c8cc04ca514 100644 (file)
         * code after resume.
         *
         * entry:
-        *      r0 = pointer to the save block
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
        stmfd   sp!, { r4 - r12, lr }
-
-       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mrc     p15, 0, r9, c1, c0, 0   @ Control register
-       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-
-       stmia   r0, { r4 - r13 }        @ Save CP registers and SP
-
-       @@ save our state to ram
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        @@ call final suspend code
        ldr     r0, =pm_cpu_sleep
@@ -61,18 +49,6 @@ ENTRY(s3c_cpu_save)
 resume_with_mmu:
        ldmfd   sp!, { r4 - r12, pc }   @ return, from sp from s3c_cpu_save
 
-       .data
-
-       /* the next bit is code, but it requires easy access to the
-        * s3c_sleep_save_phys data before the MMU is switched on, so
-        * we store the code that needs this variable in the .data where
-        * the value can be written to (the .text segment is RO).
-       */
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
        /* Sleep magic, the word before the resume entry point so that the
         * bootloader can check for a resumeable image. */
 
@@ -110,35 +86,4 @@ ENTRY(s3c_cpu_resume)
        orr     r0, r0, #1 << 15                        @ GPN15
        str     r0, [ r3, #S3C64XX_GPNDAT ]
 #endif
-
-       /* __v6_setup from arch/arm/mm/proc-v6.S, ensure that the caches
-        * are thoroughly cleaned just in case the bootloader didn't do it
-        * for us. */
-       mov     r0, #0
-       mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
-       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
-       mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
-       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
-       @@mcr   p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
-       @@mcr   p15, 0, r0, c7, c7, 0           @ Invalidate I + D caches
-
-       ldr     r0, s3c_sleep_save_phys
-       ldmia   r0, { r4 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mcr     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mcr     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mcr     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mcr     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mcr     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-
-       mov     r0, #0                  @ restore copro access controls
-       mcr     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-       mcr     p15, 0, r0, c7, c5, 4
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r9, c1, c0, 0           /* turn mmu back on */
-       nop
-       mov     pc, r2                          /* jump back */
-
-       .end
+       b       cpu_resume
index d4d222b716b434e046ccd274e7b9a8dd01f4484d..a3d649466fb1b8b89086f55939011612e3e8b64e 100644 (file)
        /* s3c_cpu_save
         *
         * entry:
-        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
 
        stmfd   sp!, { r3 - r12, lr }
-
-       mrc     p15, 0, r4, c13, c0, 0  @ FCSE/PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ Translation Table BASE0
-       mrc     p15, 0, r7, c2, c0, 1   @ Translation Table BASE1
-       mrc     p15, 0, r8, c2, c0, 2   @ Translation Table Control
-       mrc     p15, 0, r9, c1, c0, 0   @ Control register
-       mrc     p15, 0, r10, c1, c0, 1  @ Auxiliary control register
-       mrc     p15, 0, r11, c1, c0, 2  @ Co-processor access controls
-       mrc     p15, 0, r12, c10, c2, 0 @ Read PRRR
-       mrc     p15, 0, r3, c10, c2, 1  @ READ NMRR
-
-       stmia   r0, { r3 - r13 }
-
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        ldr     r0, =pm_cpu_sleep
        ldr     r0, [ r0 ]
        mov     pc, r0
 
 resume_with_mmu:
-       /*
-        * After MMU is turned on, restore the previous MMU table.
-        */
-       ldr     r9 , =(PAGE_OFFSET - PHYS_OFFSET)
-       add     r4, r4, r9
-       str     r12, [r4]
-
        ldmfd   sp!, { r3 - r12, pc }
 
        .ltorg
 
-       .data
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
        /* sleep magic, to allow the bootloader to check for an valid
         * image to resume to. Must be the first word before the
         * s3c_cpu_resume entry.
@@ -96,75 +70,4 @@ s3c_sleep_save_phys:
        */
 
 ENTRY(s3c_cpu_resume)
-       mov     r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
-       msr     cpsr_c, r0
-
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @ invalidate TLBs
-       mcr     p15, 0, r1, c7, c5, 0           @ invalidate I Cache
-
-       ldr     r0, s3c_sleep_save_phys         @ address of restore block
-       ldmia   r0, { r3 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0          @ FCSE/PID
-       mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
-
-       mcr     p15, 0, r8, c2, c0, 2           @ Translation Table Control
-       mcr     p15, 0, r7, c2, c0, 1           @ Translation Table BASE1
-       mcr     p15, 0, r6, c2, c0, 0           @ Translation Table BASE0
-
-       mcr     p15, 0, r10, c1, c0, 1          @ Auxiliary control register
-
-       mov     r0, #0
-       mcr     p15, 0, r0, c8, c7, 0           @ Invalidate I & D TLB
-
-       mov     r0, #0                          @ restore copro access
-       mcr     p15, 0, r11, c1, c0, 2          @ Co-processor access
-       mcr     p15, 0, r0, c7, c5, 4
-
-       mcr     p15, 0, r12, c10, c2, 0         @ write PRRR
-       mcr     p15, 0, r3, c10, c2, 1          @ write NMRR
-
-       /*
-        * In Cortex-A8, when MMU is turned on, the pipeline is flushed.
-        * And there are no valid entries in the MMU table at this point.
-        * So before turning on the MMU, the MMU entry for the DRAM address
-        * range is added. After the MMU is turned on, the other entries
-        * in the MMU table will be restored.
-       */
-
-       /* r6 = Translation Table BASE0 */
-       mov     r4, r6
-       mov     r4, r4, LSR #14
-       mov     r4, r4, LSL #14
-
-       /* Load address for adding to MMU table list */
-       ldr     r11, =0xE010F000                @ INFORM0 reg.
-       ldr     r10, [r11, #0]
-       mov     r10, r10, LSR #18
-       bic     r10, r10, #0x3
-       orr     r4, r4, r10
-
-       /* Calculate MMU table entry */
-       mov     r10, r10, LSL #18
-       ldr     r5, =0x40E
-       orr     r10, r10, r5
-
-       /* Back up originally data */
-       ldr     r12, [r4]
-
-       /* Add calculated MMU table entry into MMU table list */
-       str     r10, [r4]
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r9, c1, c0, 0           @ turn on MMU, etc
-
-       nop
-       nop
-       nop
-       nop
-       nop                                     @ second-to-last before mmu
-
-       mov     pc, r2                          @ go back to virtual address
-
-       .ltorg
+       b       cpu_resume
index e73e3b6e88d2dfbb0a97ca074b0d7863f0eec282..fd7032f84ae7623198f97a28fc40854941be61b3 100644 (file)
        /* s3c_cpu_save
         *
         * entry:
-        *      r0 = save address (virtual addr of s3c_sleep_save_phys)
+        *      r1 = v:p offset
        */
 
 ENTRY(s3c_cpu_save)
        stmfd   sp!, { r4 - r12, lr }
-
-       @@ store co-processor registers
-
-       mrc     p15, 0, r4, c13, c0, 0  @ PID
-       mrc     p15, 0, r5, c3, c0, 0   @ Domain ID
-       mrc     p15, 0, r6, c2, c0, 0   @ translation table base address
-       mrc     p15, 0, r7, c1, c0, 0   @ control register
-
-       stmia   r0, { r4 - r13 }
-
-       @@ write our state back to RAM
-       bl      s3c_pm_cb_flushcache
+       ldr     r3, =resume_with_mmu
+       bl      cpu_suspend
 
        @@ jump to final code to send system to sleep
        ldr     r0, =pm_cpu_sleep
@@ -76,20 +66,6 @@ resume_with_mmu:
 
        .ltorg
 
-       @@ the next bits sit in the .data segment, even though they
-       @@ happen to be code... the s3c_sleep_save_phys needs to be
-       @@ accessed by the resume code before it can restore the MMU.
-       @@ This means that the variable has to be close enough for the
-       @@ code to read it... since the .text segment needs to be RO,
-       @@ the data segment can be the only place to put this code.
-
-       .data
-
-       .global s3c_sleep_save_phys
-s3c_sleep_save_phys:
-       .word   0
-
-
        /* sleep magic, to allow the bootloader to check for an valid
         * image to resume to. Must be the first word before the
         * s3c_cpu_resume entry.
@@ -100,10 +76,6 @@ s3c_sleep_save_phys:
        /* s3c_cpu_resume
         *
         * resume code entry for bootloader to call
-        *
-        * we must put this code here in the data segment as we have no
-        * other way of restoring the stack pointer after sleep, and we
-        * must not write to the code segment (code is read-only)
        */
 
 ENTRY(s3c_cpu_resume)
@@ -134,25 +106,4 @@ ENTRY(s3c_cpu_resume)
        beq     1001b
 #endif /* CONFIG_DEBUG_RESUME */
 
-       mov     r1, #0
-       mcr     p15, 0, r1, c8, c7, 0           @@ invalidate I & D TLBs
-       mcr     p15, 0, r1, c7, c7, 0           @@ invalidate I & D caches
-
-       ldr     r0, s3c_sleep_save_phys         @ address of restore block
-       ldmia   r0, { r4 - r13 }
-
-       mcr     p15, 0, r4, c13, c0, 0          @ PID
-       mcr     p15, 0, r5, c3, c0, 0           @ Domain ID
-       mcr     p15, 0, r6, c2, c0, 0           @ translation table base
-
-#ifdef CONFIG_DEBUG_RESUME
-       mov     r3, #'R'
-       strb    r3, [ r2, #S3C2410_UTXH ]
-#endif
-
-       ldr     r2, =resume_with_mmu
-       mcr     p15, 0, r7, c1, c0, 0           @ turn on MMU, etc
-       nop                                     @ second-to-last before mmu
-       mov     pc, r2                          @ go back to virtual address
-
-       .ltorg
+       b       cpu_resume
index d9025e377675b6c323d28355b616d0c718cd1c9d..4aa697dfe13f123fa12f1ebc7443d731d2768e08 100644 (file)
@@ -50,13 +50,11 @@ extern unsigned char pm_uart_udivslot;  /* true to save UART UDIVSLOT */
 
 /* from sleep.S */
 
-extern int  s3c_cpu_save(unsigned long *saveblk);
+extern int  s3c_cpu_save(unsigned long *saveblk, long);
 extern void s3c_cpu_resume(void);
 
 extern void s3c2410_cpu_suspend(void);
 
-extern unsigned long s3c_sleep_save_phys;
-
 /* sleep save info */
 
 /**
@@ -179,13 +177,5 @@ extern void s3c_pm_restore_gpios(void);
  */
 extern void s3c_pm_save_gpios(void);
 
-/**
- * s3c_pm_cb_flushcache - callback for assembly code
- *
- * Callback to issue flush_cache_all() as this call is
- * not a directly callable object.
- */
-extern void s3c_pm_cb_flushcache(void);
-
 extern void s3c_pm_save_core(void);
 extern void s3c_pm_restore_core(void);
index 02d531fb3f8160f3abbd925d016a71551cbd14dc..d5b58d31903c740d2a0328a67e3d536adcc832d8 100644 (file)
@@ -241,8 +241,6 @@ void (*pm_cpu_sleep)(void);
 
 static int s3c_pm_enter(suspend_state_t state)
 {
-       static unsigned long regs_save[16];
-
        /* ensure the debug is initialised (if enabled) */
 
        s3c_pm_debug_init();
@@ -266,12 +264,6 @@ static int s3c_pm_enter(suspend_state_t state)
                return -EINVAL;
        }
 
-       /* store the physical address of the register recovery block */
-
-       s3c_sleep_save_phys = virt_to_phys(regs_save);
-
-       S3C_PMDBG("s3c_sleep_save_phys=0x%08lx\n", s3c_sleep_save_phys);
-
        /* save all necessary core registers not covered by the drivers */
 
        s3c_pm_save_gpios();
@@ -305,7 +297,7 @@ static int s3c_pm_enter(suspend_state_t state)
         * we resume as it saves its own register state and restores it
         * during the resume.  */
 
-       s3c_cpu_save(regs_save);
+       s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET);
 
        /* restore the cpu state using the kernel's cpu init code. */
 
@@ -336,12 +328,6 @@ static int s3c_pm_enter(suspend_state_t state)
        return 0;
 }
 
-/* callback from assembly code */
-void s3c_pm_cb_flushcache(void)
-{
-       flush_cache_all();
-}
-
 static int s3c_pm_prepare(void)
 {
        /* prepare check area if configured */