Skip to contentSkip to conversation

PM support for Ebony

PATCH In review Geoff Levand 3 participants 7 messages Jun 3, 2005 – Jun 6, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 PM support for Ebony

I rebased this to apply to Benjamin's ppc32-rework-pm.diff, but didn't recode it to take advantage of the extra hooks. More work is certainly needed for wake-on-lan. Any comments on improvement would be most welcome.

I could also make one available against a 2.6.12-rc if requested.

-Geoff

* pm-on-ebony.patch

This patch provides power management support for the IBM PPC440GP Ebony Reference Platform. The main portion of the patch implements the platform specific pm_ops structure required by the kernel power management sub-system. The current implementation only supports suspend-to-memory (PM_SUSPEND_MEM), though unpublished suspend-to-disk work has been started.

This implementation arranges for the U44 switch on the Ebony platform, connected to the SMI interrupt handler, to be used as a system resume trigger.

--

arch/ppc/platforms/4xx/Kconfig +0 -4
Index: linux-2.6.12-bhpm/arch/ppc/platforms/4xx/Kconfig
===================================================================
@@ -214,10 +214,6 @@
 	depends on 4xx
 	default y
 
-config PM
-	bool "Power Management support (EXPERIMENTAL)"
-	depends on 4xx && EXPERIMENTAL
-
 choice
 	prompt "TTYS0 device and default console"
 	depends on 40x
arch/ppc/platforms/4xx/Makefile +3 -0
Index: linux-2.6.12-bhpm/arch/ppc/platforms/4xx/Makefile
===================================================================
@@ -25,3 +25,6 @@
 obj-$(CONFIG_405EP)		+= ibm405ep.o
 obj-$(CONFIG_405GPR)		+= ibm405gpr.o
 obj-$(CONFIG_VIRTEX_II_PRO)	+= virtex-ii_pro.o
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_EBONY)		+= ebony_pm.o ibm440gp_sleep.o
+endif
arch/ppc/platforms/4xx/ebony_pm.c +202 -0

202 lines not on this page · raw message

arch/ppc/platforms/4xx/ibm440gp_sleep.S +44 -0

44 lines not on this page · raw message

include/asm-ppc/ocp.h +8 -0
Index: linux-2.6.12-bhpm/include/asm-ppc/ocp.h
===================================================================
@@ -151,13 +151,21 @@
 static inline void
 ocp_force_power_off(struct ocp_device *odev)
 {
+#ifdef CONFIG_44x
+	mtdcr(DCRN_CPC0_FR, mfdcr(DCRN_CPC0_FR) | odev->def->pm);
+#else
 	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | odev->def->pm);
+#endif
 }
 
 static inline void
 ocp_force_power_on(struct ocp_device *odev)
 {
+#ifdef CONFIG_44x
+	mtdcr(DCRN_CPC0_FR, mfdcr(DCRN_CPC0_FR) & ~odev->def->pm);
+#else
 	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~odev->def->pm);
+#endif
 }
 #else
 #define ocp_force_power_off(x)	(void)(x)

-EOF

#1 lore raw
Quoted 6 lines · Geoff Levand

I rebased this to apply to Benjamin's ppc32-rework-pm.diff, but didn't recode it to take advantage of the extra hooks. More work is certainly needed for wake-on-lan. Any comments on improvement would be most welcome.

I could also make one available against a 2.6.12-rc if requested.

Ok, well, part of the issue here is that I'm about to rework the rework ... I discussed with Pat Mochel, and we are about to kill pm_ops completely and have the code structured differently. Instead of hooks, have the arch code be called on state change and be "in charge".

I'll try to setup an Ebony here asap so I can keep your patches in sync as well.

Ben.

#2 lore raw
In reply to Geoff Levand

On Fri, Jun 03, 2005 at 04:22:40PM -0700, Geoff Levand wrote:

[snip]

arch/ppc/platforms/4xx/ebony_pm.c line 100

Quoted 12 lines
arch/ppc/platforms/4xx/ebony_pm.c +12 -0
+	/* save current CPM */
+	cpm_save_er = mfdcr(DCRN_CPC0_ER);
+
+	/* save UIC0 enable registers */
+	uic_save_er = mfdcr(DCRN_UIC_ER(UIC0));
+
+#ifdef USE_ETHER_TO_RESUME
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT|UIC0_UIC1NC_BIT);
+#else
+	/* mask UIC0 interrupts, except External Intr #5 */
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT);
+#endif

Why UIC PM code is here and not in ppc4xx_pic.c? I don't think this is the right place to mess with UIC registers.

[snip]

arch/ppc/platforms/4xx/ibm440gp_sleep.S

Quoted 3 lines

===================================================================

arch/ppc/platforms/4xx/ibm440gp_sleep.S +0 -0

I think it should be in arch/ppc/syslib not in arch/ppc/platforms/4xx.

Signature · 1 line
Eugene
#3 lore raw
Quoted 5 lines · Eugene Surovegin

On Fri, Jun 03, 2005 at 04:22:40PM -0700, Geoff Levand wrote:

[snip]

Quoted 17 lines

arch/ppc/platforms/4xx/ebony_pm.c line 100

Quoted 12 lines
arch/ppc/platforms/4xx/ebony_pm.c +12 -0
+	/* save current CPM */
+	cpm_save_er = mfdcr(DCRN_CPC0_ER);
+
+	/* save UIC0 enable registers */
+	uic_save_er = mfdcr(DCRN_UIC_ER(UIC0));
+
+#ifdef USE_ETHER_TO_RESUME
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT|UIC0_UIC1NC_BIT);
+#else
+	/* mask UIC0 interrupts, except External Intr #5 */
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT);
+#endif

Why UIC PM code is here and not in ppc4xx_pic.c? I don't think this is the right place to mess with UIC registers.

Yes, that is resonable. Maybe something like ppc4xx_pic_suspend() and ppc4xx_pic_resume().

Quoted 5 lines
Quoted 4 lines

===================================================================
--- linux-2.6.12-bhpm.orig/arch/ppc/platforms/4xx/ibm440gp_sleep.S

Quoted 8 lines
2005-06-01 08:52:49.947684744 -0700
Quoted 1 line

+++ linux-2.6.12-bhpm/arch/ppc/platforms/4xx/ibm440gp_sleep.S

2005-06-03 16:15:07.000000000 -0700

I think it should be in arch/ppc/syslib not in arch/ppc/platforms/4xx.

I was thinking the same...

I want to do some cleanup of the debugging code and reformat the text, then I'll post a new version with these changes.

-Geoff

#4 lore raw
In reply to Eugene Surovegin
Quoted 28 lines · Eugene Surovegin

On Fri, Jun 03, 2005 at 04:22:40PM -0700, Geoff Levand wrote:

[snip]

Review

Quoted 12 lines
(quoted diff) +12 -0
+	/* save current CPM */
+	cpm_save_er = mfdcr(DCRN_CPC0_ER);
+
+	/* save UIC0 enable registers */
+	uic_save_er = mfdcr(DCRN_UIC_ER(UIC0));
+
+#ifdef USE_ETHER_TO_RESUME
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT|UIC0_UIC1NC_BIT);
+#else
+	/* mask UIC0 interrupts, except External Intr #5 */
+	mtdcr(DCRN_UIC_ER(UIC0), UIC0_EIR5_BIT);
+#endif

Why UIC PM code is here and not in ppc4xx_pic.c? I don't think this is the right place to mess with UIC registers.

[snip]

Quoted 2 lines

===================================================================
--- linux-2.6.12-bhpm.orig/arch/ppc/platforms/4xx/ibm440gp_sleep.S

Quoted 8 lines
2005-06-01 08:52:49.947684744 -0700
Quoted 1 line

+++ linux-2.6.12-bhpm/arch/ppc/platforms/4xx/ibm440gp_sleep.S

2005-06-03 16:15:07.000000000 -0700

I think it should be in arch/ppc/syslib not in arch/ppc/platforms/4xx.

Here's a cleaned-up version. I moved ibm440gp_sleep.S into syslib and put a declaration in ibm440gp_common.h. I also made two new pm suspend/resume routines in ppc4xx_pic.c.

I was thinking to add a static variable in ppc4xx_pic.c to hold the state, that way the arch pm code doesn't need to take care of it, which will make suspend to disk easier since the value will be saved in the system image. I'm not sure which way to go. Any comments?

-Geoff

* pm-on-ebony.patch

This patch provides power management support for the IBM PPC440GP Ebony Reference Platform. The main portion of the patch implements the platform specific pm_ops structure required by the kernel power management sub-system. The current implementation only supports suspend-to-memory (PM_SUSPEND_MEM), though unpublished suspend-to-disk work has been started.

This implementation arranges for the U44 switch on the Ebony platform, connected to the SMI interrupt handler, to be used as a system resume trigger.

--

arch/ppc/platforms/4xx/Kconfig +0 -4
Index: linux-2.6.12-bhpm/arch/ppc/platforms/4xx/Kconfig
===================================================================
@@ -214,10 +214,6 @@
 	depends on 4xx
 	default y
 
-config PM
-	bool "Power Management support (EXPERIMENTAL)"
-	depends on 4xx && EXPERIMENTAL
-
 choice
 	prompt "TTYS0 device and default console"
 	depends on 40x
arch/ppc/platforms/4xx/Makefile +3 -0
Index: linux-2.6.12-bhpm/arch/ppc/platforms/4xx/Makefile
===================================================================
@@ -25,3 +25,6 @@
 obj-$(CONFIG_405EP)		+= ibm405ep.o
 obj-$(CONFIG_405GPR)		+= ibm405gpr.o
 obj-$(CONFIG_VIRTEX_II_PRO)	+= virtex-ii_pro.o
+ifeq ($(CONFIG_PM),y)
+obj-$(CONFIG_EBONY)		+= ebony_pm.o
+endif
arch/ppc/platforms/4xx/ebony_pm.c +192 -0

192 lines not on this page · raw message

arch/ppc/syslib/Makefile +1 -1
Index: linux-2.6.12-bhpm/arch/ppc/syslib/Makefile
===================================================================
@@ -11,7 +11,7 @@
 obj-$(CONFIG_PPC_OCP)		+= ocp.o
 obj-$(CONFIG_IBM_OCP)		+= ibm_ocp.o
 obj-$(CONFIG_44x)		+= ibm44x_common.o
-obj-$(CONFIG_440GP)		+= ibm440gp_common.o
+obj-$(CONFIG_440GP)		+= ibm440gp_common.o ibm440gp_sleep.o
 obj-$(CONFIG_440GX)		+= ibm440gx_common.o
 obj-$(CONFIG_440SP)		+= ibm440gx_common.o ibm440sp_common.o
 ifeq ($(CONFIG_4xx),y)
arch/ppc/syslib/ibm440gp_common.h +1 -0
Index: linux-2.6.12-bhpm/arch/ppc/syslib/ibm440gp_common.h
===================================================================
@@ -29,6 +29,7 @@
  */
 void ibm440gp_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
 	unsigned int ser_clk) __init;
+void ibm440gp_sleep(u32 cpc0_er_val, u32 msr_or_val);
 
 #endif /* __ASSEMBLY__ */
 #endif /* __PPC_SYSLIB_IBM440GP_COMMON_H */
arch/ppc/syslib/ibm440gp_sleep.S +45 -0

45 lines not on this page · raw message

include/asm-ppc/ocp.h +8 -0
Index: linux-2.6.12-bhpm/include/asm-ppc/ocp.h
===================================================================
@@ -151,13 +151,21 @@
 static inline void
 ocp_force_power_off(struct ocp_device *odev)
 {
+#ifdef CONFIG_44x
+	mtdcr(DCRN_CPC0_FR, mfdcr(DCRN_CPC0_FR) | odev->def->pm);
+#else
 	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) | odev->def->pm);
+#endif
 }
 
 static inline void
 ocp_force_power_on(struct ocp_device *odev)
 {
+#ifdef CONFIG_44x
+	mtdcr(DCRN_CPC0_FR, mfdcr(DCRN_CPC0_FR) & ~odev->def->pm);
+#else
 	mtdcr(DCRN_CPMFR, mfdcr(DCRN_CPMFR) & ~odev->def->pm);
+#endif
 }
 #else
 #define ocp_force_power_off(x)	(void)(x)

* ppc4xx_pic-pm.patch

This patch provides power management support for the IBM PPC4xx interrupt controllers.

--

arch/ppc/syslib/ppc4xx_pic.c +20 -0
Index: linux-2.6.12-bhpm/arch/ppc/syslib/ppc4xx_pic.c
===================================================================
@@ -245,3 +245,23 @@
 
 	ppc_md.get_irq = ppc4xx_pic_get_irq;
 }
+
+#if defined(CONFIG_PM)
+
+void ppc4xx_pic_suspend(u32 resume_bits, u32* pic_state)
+{
+	/* save UIC0 enable registers */
+	*pic_state = mfdcr(DCRN_UIC_ER(UIC0));
+
+	/* mask UIC0 interrupts, except resume_bits */
+	mtdcr(DCRN_UIC_ER(UIC0), resume_bits);
+}
+
+void ppc4xx_pic_resume(u32 pic_state)
+{
+	/* Restore UIC0 enable registers */
+	mtdcr(DCRN_UIC_ER(UIC0), pic_state);
+}
+
+#endif /* defined(CONFIG_PM) */
+
include/asm-ppc/ppc4xx_pic.h +2 -0
Index: linux-2.6.12-bhpm/include/asm-ppc/ppc4xx_pic.h
===================================================================
@@ -49,5 +49,7 @@
 };
 
 extern void ppc4xx_pic_init(void);
+void ppc4xx_pic_suspend(u32 resume_bits, u32* pic_state);
+void ppc4xx_pic_resume(u32 pic_state);
 
 #endif				/* __PPC4XX_PIC_H__ */

-EOF

#5 lore raw
Quoted 5 lines · Geoff Levand

I was thinking to add a static variable in ppc4xx_pic.c to hold the state, that way the arch pm code doesn't need to take care of it, which will make suspend to disk easier since the value will be saved in the system image. I'm not sure which way to go. Any comments?

I don't have a problem with having static variables for PM in ppc4xx_pic.c. However, why only one for UIC0? What about UIC1? What about UIC2 (for 440GX) ?

Also, function, you just added, uses resume_bits are for UIC0, it's not clear from the function prototype why just UIC0. Shouldn't it be more generic?

Another note, code in ebony_pm_enter doesn't look very Ebony specific, maybe it's would be a good idea to move most of it into ibm440gp_sleep.

Signature · 1 line
Eugene
#6 lore raw
Quoted 9 lines · Eugene Surovegin
Quoted 5 lines · Geoff Levand

I was thinking to add a static variable in ppc4xx_pic.c to hold the state, that way the arch pm code doesn't need to take care of it, which will make suspend to disk easier since the value will be saved in the system image. I'm not sure which way to go. Any comments?

Quoted 7 lines

I don't have a problem with having static variables for PM in ppc4xx_pic.c. However, why only one for UIC0? What about UIC1? What about UIC2 (for 440GX) ?

Also, function, you just added, uses resume_bits are for UIC0, it's not clear from the function prototype why just UIC0. Shouldn't it be more generic?

Well, I guess I was originally only interested in waking up from things connected to UIC0... I'll look at the other interrupts.

Quoted 4 lines

Another note, code in ebony_pm_enter doesn't look very Ebony specific, maybe it's would be a good idea to move most of it into ibm440gp_sleep.

My thoughts also, but I'll wait until I see BenH's new design before deciding what to do.

-Geoff