powerpc/e500mc: Add support for the wait instruction in e500_idle
authorScott Wood <scottwood@freescale.com>
Wed, 22 Jun 2011 23:10:30 +0000 (18:10 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Mon, 27 Jun 2011 13:36:15 +0000 (08:36 -0500)
e500mc cannot doze or nap due to an erratum (as well as having a
different mechanism than previous e500), but it has a "wait" instruction
that is similar to doze.

On 64-bit, due to the soft-irq-disable mechanism, the existing
book3e_idle should be used instead.

Signed-off-by: Vakul Garg <vakul@freescale.com>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
arch/powerpc/kernel/idle_e500.S
arch/powerpc/platforms/85xx/p3041_ds.c
arch/powerpc/platforms/85xx/p4080_ds.c
arch/powerpc/platforms/85xx/p5020_ds.c

index 47a1a98..3e2b95c 100644 (file)
@@ -26,6 +26,17 @@ _GLOBAL(e500_idle)
        ori     r4,r4,_TLF_NAPPING      /* so when we take an exception */
        stw     r4,TI_LOCAL_FLAGS(r3)   /* it will return to our caller */
 
+#ifdef CONFIG_E500MC
+       wrteei  1
+1:     wait
+
+       /*
+        * Guard against spurious wakeups (e.g. from a hypervisor) --
+        * any real interrupt will cause us to return to LR due to
+        * _TLF_NAPPING.
+        */
+       b       1b
+#else
        /* Check if we can nap or doze, put HID0 mask in r3 */
        lis     r3,0
 BEGIN_FTR_SECTION
@@ -72,6 +83,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_L2CSR|CPU_FTR_CAN_NAP)
        mtmsr   r7
        isync
 2:     b       2b
+#endif /* !E500MC */
 
 /*
  * Return from NAP/DOZE mode, restore some CPU specific registers,
index e2cfb6b..1fcd233 100644 (file)
@@ -69,6 +69,7 @@ define_machine(p3041_ds) {
        .restart                = fsl_rstcr_restart,
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
+       .power_save             = e500_idle,
 };
 
 machine_device_initcall(p3041_ds, corenet_ds_publish_devices);
index eed4b01..430c8f9 100644 (file)
@@ -68,6 +68,7 @@ define_machine(p4080_ds) {
        .restart                = fsl_rstcr_restart,
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
+       .power_save             = e500_idle,
 };
 
 machine_device_initcall(p4080_ds, corenet_ds_publish_devices);
index 94348c9..f7220d4 100644 (file)
@@ -74,6 +74,11 @@ define_machine(p5020_ds) {
        .restart                = fsl_rstcr_restart,
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
+#ifdef CONFIG_PPC64
+       .power_save             = book3e_idle,
+#else
+       .power_save             = e500_idle,
+#endif
 };
 
 machine_device_initcall(p5020_ds, corenet_ds_publish_devices);