@@ -253,6 +253,7 @@ struct machdep_calls {
};
extern void e500_idle(void);
+extern void e500mc_idle(void);
extern void power4_idle(void);
extern void power7_idle(void);
extern void ppc6xx_idle(void);
@@ -61,7 +61,8 @@ obj-$(CONFIG_IBMEBUS) += ibmebus.o
obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
ifeq ($(CONFIG_PPC32),y)
-obj-$(CONFIG_E500) += idle_e500.o
+obj-$(CONFIG_FSL_E500_V1_V2) += idle_e500.o
+obj-$(CONFIG_FSL_E500MC) += idle_e500mc.o
endif
obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
obj-$(CONFIG_TAU) += tau_6xx.o
@@ -26,17 +26,6 @@ _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_PPC_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
@@ -83,7 +72,6 @@ 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,
new file mode 100644
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ * Dave Liu <daveliu@freescale.com>
+ * copy from idle_6xx.S and modify for e500 based processor,
+ * implement the power_save function in idle.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/threads.h>
+#include <asm/reg.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+ .text
+
+_GLOBAL(e500mc_idle)
+ rlwinm r3,r1,0,0,31-THREAD_SHIFT /* current thread_info */
+ lwz r4,TI_LOCAL_FLAGS(r3) /* set napping bit */
+ ori r4,r4,_TLF_NAPPING /* so when we take an exception */
+ stw r4,TI_LOCAL_FLAGS(r3) /* it will return to our caller */
+ 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
+
+/*
+ * Return from NAP/DOZE mode, restore some CPU specific registers,
+ * r2 containing physical address of current.
+ * r11 points to the exception frame (physical address).
+ * We have to preserve r10.
+ */
+_GLOBAL(power_save_ppc32_restore)
+ lwz r9,_LINK(r11) /* interrupted in e500mc_idle */
+ stw r9,_NIP(r11) /* make it do a blr */
+
+#ifdef CONFIG_SMP
+ rlwinm r12,r1,0,0,31-THREAD_SHIFT
+ lwz r11,TI_CPU(r12) /* get cpu number * 4 */
+ slwi r11,r11,2
+#else
+ li r11,0
+#endif
+
+ b transfer_to_handler_cont
@@ -139,7 +139,7 @@ notrace void __init machine_init(u64 dt_ptr)
ppc_md.power_save = ppc6xx_idle;
#endif
-#ifdef CONFIG_E500
+#ifdef CONFIG_FSL_E500_V1_V2
if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
cpu_has_feature(CPU_FTR_CAN_NAP))
ppc_md.power_save = e500_idle;
@@ -78,7 +78,7 @@ define_machine(p2041_rdb) {
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
- .power_save = e500_idle,
+ .power_save = e500mc_idle,
};
machine_device_initcall(p2041_rdb, corenet_ds_publish_devices);
@@ -80,7 +80,7 @@ define_machine(p3041_ds) {
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
- .power_save = e500_idle,
+ .power_save = e500mc_idle,
};
machine_device_initcall(p3041_ds, corenet_ds_publish_devices);
@@ -67,7 +67,7 @@ define_machine(p3060_qds) {
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
- .power_save = e500_idle,
+ .power_save = e500mc_idle,
};
machine_device_initcall(p3060_qds, declare_of_platform_devices);
@@ -79,7 +79,7 @@ define_machine(p4080_ds) {
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
- .power_save = e500_idle,
+ .power_save = e500mc_idle,
};
machine_device_initcall(p4080_ds, corenet_ds_publish_devices);
@@ -88,7 +88,7 @@ define_machine(p5020_ds) {
#ifdef CONFIG_PPC64
.power_save = book3e_idle,
#else
- .power_save = e500_idle,
+ .power_save = e500mc_idle,
#endif
};
These are totally different (more so in fact than 6xx vs. e500v1/v2), so there isn't really a good reason to keep them in the same file. Signed-off-by: Kyle Moffett <Kyle.D.Moffett@boeing.com> --- arch/powerpc/include/asm/machdep.h | 1 + arch/powerpc/kernel/Makefile | 3 +- arch/powerpc/kernel/idle_e500.S | 12 ------- arch/powerpc/kernel/idle_e500mc.S | 56 +++++++++++++++++++++++++++++++ arch/powerpc/kernel/setup_32.c | 2 +- arch/powerpc/platforms/85xx/p2041_rdb.c | 2 +- arch/powerpc/platforms/85xx/p3041_ds.c | 2 +- arch/powerpc/platforms/85xx/p3060_qds.c | 2 +- arch/powerpc/platforms/85xx/p4080_ds.c | 2 +- arch/powerpc/platforms/85xx/p5020_ds.c | 2 +- 10 files changed, 65 insertions(+), 19 deletions(-) create mode 100644 arch/powerpc/kernel/idle_e500mc.S