ARM: vexpress/MCPM: fix cache disable sequence when CONFIG_FRAME_POINTER=y
authorNicolas Pitre <nicolas.pitre@linaro.org>
Wed, 14 Aug 2013 14:25:14 +0000 (10:25 -0400)
committerJon Medhurst <tixy@linaro.org>
Mon, 2 Dec 2013 12:54:16 +0000 (12:54 +0000)
Commit fac2e57742d9aa3dbe41860280352efda9d5566e upstream

If CONFIG_FRAME_POINTER=y we get the following error:

arch/arm/mach-vexpress/tc2_pm.c: In function 'tc2_pm_down':
arch/arm/mach-vexpress/tc2_pm.c:200:1: error: fp cannot be used in asm here

Let's fix that by explicitly preserving r11 on the stack and removing it
from the clobber list.

Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Jon Medhurst <tixy@linaro.org>
arch/arm/mach-vexpress/dcscb.c
arch/arm/mach-vexpress/tc2_pm.c

index df593951cbf42de60c3564b493bba2ea660e3e96..19a7d08102be7141f271f48c8e8719aa181271f4 100644 (file)
@@ -145,8 +145,13 @@ static void dcscb_power_down(void)
                 * Let's do it in the safest possible way i.e. with
                 * no memory access within the following sequence
                 * including to the stack.
+                *
+                * Note: fp is preserved to the stack explicitly prior doing
+                * this since adding it to the clobber list is incompatible
+                * with having CONFIG_FRAME_POINTER=y.
                 */
                asm volatile(
+               "str    fp, [sp, #-4]! \n\t"
                "mrc    p15, 0, r0, c1, c0, 0   @ get CR \n\t"
                "bic    r0, r0, #"__stringify(CR_C)" \n\t"
                "mcr    p15, 0, r0, c1, c0, 0   @ set CR \n\t"
@@ -157,9 +162,10 @@ static void dcscb_power_down(void)
                "bic    r0, r0, #(1 << 6)       @ disable local coherency \n\t"
                "mcr    p15, 0, r0, c1, c0, 1   @ set AUXCR \n\t"
                "isb    \n\t"
-               "dsb    "
+               "dsb    \n\t"
+               "ldr    fp, [sp], #4"
                : : : "r0","r1","r2","r3","r4","r5","r6","r7",
-                     "r9","r10","r11","lr","memory");
+                     "r9","r10","lr","memory");
 
                /*
                 * This is a harmless no-op.  On platforms with a real
@@ -183,6 +189,7 @@ static void dcscb_power_down(void)
                 * Let's do it in the safest possible way as above.
                 */
                asm volatile(
+               "str    fp, [sp, #-4]! \n\t"
                "mrc    p15, 0, r0, c1, c0, 0   @ get CR \n\t"
                "bic    r0, r0, #"__stringify(CR_C)" \n\t"
                "mcr    p15, 0, r0, c1, c0, 0   @ set CR \n\t"
@@ -193,9 +200,10 @@ static void dcscb_power_down(void)
                "bic    r0, r0, #(1 << 6)       @ disable local coherency \n\t"
                "mcr    p15, 0, r0, c1, c0, 1   @ set AUXCR \n\t"
                "isb    \n\t"
-               "dsb    "
+               "dsb    \n\t"
+               "ldr    fp, [sp], #4"
                : : : "r0","r1","r2","r3","r4","r5","r6","r7",
-                     "r9","r10","r11","lr","memory");
+                     "r9","r10","lr","memory");
        }
 
        __mcpm_cpu_down(cpu, cluster);
index b4b090ccc61fd3ca09bac1b36fbd358dac6a2bfb..9221903af53c782a66e7104d23f8fcea9d0d0cbc 100644 (file)
@@ -152,8 +152,13 @@ static void tc2_pm_down(u64 residency)
                 * Let's do it in the safest possible way i.e. with
                 * no memory access within the following sequence
                 * including the stack.
+                *
+                * Note: fp is preserved to the stack explicitly prior doing
+                * this since adding it to the clobber list is incompatible
+                * with having CONFIG_FRAME_POINTER=y.
                 */
                asm volatile(
+               "str    fp, [sp, #-4]! \n\t"
                "mrc    p15, 0, r0, c1, c0, 0   @ get CR \n\t"
                "bic    r0, r0, #"__stringify(CR_C)" \n\t"
                "mcr    p15, 0, r0, c1, c0, 0   @ set CR \n\t"
@@ -164,9 +169,10 @@ static void tc2_pm_down(u64 residency)
                "bic    r0, r0, #(1 << 6)       @ disable local coherency \n\t"
                "mcr    p15, 0, r0, c1, c0, 1   @ set AUXCR \n\t"
                "isb    \n\t"
-               "dsb    "
+               "dsb    \n\t"
+               "ldr    fp, [sp], #4"
                : : : "r0","r1","r2","r3","r4","r5","r6","r7",
-                     "r9","r10","r11","lr","memory");
+                     "r9","r10","lr","memory");
 
                cci_disable_port_by_cpu(mpidr);
 
@@ -187,6 +193,7 @@ static void tc2_pm_down(u64 residency)
                 * Let's do it in the safest possible way as above.
                 */
                asm volatile(
+               "str    fp, [sp, #-4]! \n\t"
                "mrc    p15, 0, r0, c1, c0, 0   @ get CR \n\t"
                "bic    r0, r0, #"__stringify(CR_C)" \n\t"
                "mcr    p15, 0, r0, c1, c0, 0   @ set CR \n\t"
@@ -197,9 +204,10 @@ static void tc2_pm_down(u64 residency)
                "bic    r0, r0, #(1 << 6)       @ disable local coherency \n\t"
                "mcr    p15, 0, r0, c1, c0, 1   @ set AUXCR \n\t"
                "isb    \n\t"
-               "dsb    "
+               "dsb    \n\t"
+               "ldr    fp, [sp], #4"
                : : : "r0","r1","r2","r3","r4","r5","r6","r7",
-                     "r9","r10","r11","lr","memory");
+                     "r9","r10","lr","memory");
        }
 
        __mcpm_cpu_down(cpu, cluster);