[RFC/PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function

Michael Ellerman michael at ellerman.id.au
Tue Jul 12 17:07:30 EST 2005


This patch adds an enable_pmc entry to the ppc_md structure, and moves code
from arch/ppc64/kerne/sysfs.c into the various platform files. There should be
no functional changes.

The logic for pSeries seems a little confused. Are the platform check and the
firmware_features check equivalent?

We also call power4_enable_pmcs() unconditionally on pSeries. It seems to
work on power3, but not power5.  Maybe it should be called something else?
And therefore probably not be in op_model_power4.c?

Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
 arch/ppc64/kernel/iSeries_setup.c     |    2 +
 arch/ppc64/kernel/pSeries_setup.c     |   18 ++++++++++
 arch/ppc64/kernel/pmac_setup.c        |    6 +++
 arch/ppc64/kernel/sysfs.c             |   56 ++--------------------------------
 arch/ppc64/oprofile/op_model_power4.c |   21 ++++++++++++
 include/asm-ppc64/machdep.h           |    5 +++
 6 files changed, 56 insertions(+), 52 deletions(-)

Index: work/arch/ppc64/kernel/iSeries_setup.c
===================================================================
--- work.orig/arch/ppc64/kernel/iSeries_setup.c
+++ work/arch/ppc64/kernel/iSeries_setup.c
@@ -946,6 +946,8 @@ void __init iSeries_early_setup(void)
 	ppc_md.calibrate_decr = iSeries_calibrate_decr;
 	ppc_md.progress = iSeries_progress;
 
+	/* XXX Implement enable_pmcs for iSeries */
+
 	if (get_paca()->lppaca.shared_proc) {
 		ppc_md.idle_loop = iseries_shared_idle;
 		printk(KERN_INFO "Using shared processor idle loop\n");
Index: work/arch/ppc64/kernel/pSeries_setup.c
===================================================================
--- work.orig/arch/ppc64/kernel/pSeries_setup.c
+++ work/arch/ppc64/kernel/pSeries_setup.c
@@ -574,6 +574,23 @@ static int pseries_shared_idle(void)
 	return 0;
 }
 
+static void pSeries_enable_pmcs(void)
+{
+	power4_enable_pmcs();
+
+	if (systemcfg->platform & PLATFORM_LPAR) {
+		unsigned long set, reset;
+
+		set = 1UL << 63;
+		reset = 0;
+		plpar_hcall_norets(H_PERFMON, set, reset);
+	}
+
+        /* instruct hypervisor to maintain PMCs */
+        if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
+		get_paca()->lppaca.pmcregs_in_use = 1;
+}
+
 struct machdep_calls __initdata pSeries_md = {
 	.probe			= pSeries_probe,
 	.setup_arch		= pSeries_setup_arch,
@@ -595,4 +612,5 @@ struct machdep_calls __initdata pSeries_
 	.check_legacy_ioport	= pSeries_check_legacy_ioport,
 	.system_reset_exception = pSeries_system_reset_exception,
 	.machine_check_exception = pSeries_machine_check_exception,
+	.enable_pmcs		= pSeries_enable_pmcs,
 };
Index: work/arch/ppc64/kernel/pmac_setup.c
===================================================================
--- work.orig/arch/ppc64/kernel/pmac_setup.c
+++ work/arch/ppc64/kernel/pmac_setup.c
@@ -489,6 +489,11 @@ static int __init pmac_probe(int platfor
 	return 1;
 }
 
+static void pmac_enable_pmcs(void)
+{
+	power4_enable_pmcs();
+}
+
 struct machdep_calls __initdata pmac_md = {
 #ifdef CONFIG_HOTPLUG_CPU
 	.cpu_die		= generic_mach_cpu_die,
@@ -511,4 +516,5 @@ struct machdep_calls __initdata pmac_md 
 	.progress		= pmac_progress,
 	.check_legacy_ioport	= pmac_check_legacy_ioport,
 	.idle_loop		= native_idle,
+	.enable_pmcs		= pmac_enable_pmcs,
 };
Index: work/arch/ppc64/kernel/sysfs.c
===================================================================
--- work.orig/arch/ppc64/kernel/sysfs.c
+++ work/arch/ppc64/kernel/sysfs.c
@@ -100,6 +100,8 @@ static int __init setup_smt_snooze_delay
 }
 __setup("smt-snooze-delay=", setup_smt_snooze_delay);
 
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
 /*
  * Enabling PMCs will slow partition context switch times so we only do
  * it the first time we write to the PMCs.
@@ -109,65 +111,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled
 
 void ppc64_enable_pmcs(void)
 {
-	unsigned long hid0;
-#ifdef CONFIG_PPC_PSERIES
-	unsigned long set, reset;
-#endif /* CONFIG_PPC_PSERIES */
-
 	/* Only need to enable them once */
 	if (__get_cpu_var(pmcs_enabled))
 		return;
 
 	__get_cpu_var(pmcs_enabled) = 1;
 
-	switch (systemcfg->platform) {
-	case PLATFORM_PSERIES:
-	case PLATFORM_POWERMAC:
-		hid0 = mfspr(HID0);
-		hid0 |= 1UL << (63 - 20);
-
-		/* POWER4 requires the following sequence */
-		asm volatile(
-			     "sync\n"
-			     "mtspr	%1, %0\n"
-			     "mfspr	%0, %1\n"
-			     "mfspr	%0, %1\n"
-			     "mfspr	%0, %1\n"
-			     "mfspr	%0, %1\n"
-			     "mfspr	%0, %1\n"
-			     "mfspr	%0, %1\n"
-			     "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
-			     "memory");
-		break;
-
-#ifdef CONFIG_PPC_PSERIES
-	case PLATFORM_PSERIES_LPAR:
-		set = 1UL << 63;
-		reset = 0;
-		plpar_hcall_norets(H_PERFMON, set, reset);
-		break;
-#endif /* CONFIG_PPC_PSERIES */
-
-	default:
-		break;
-	}
-
-#ifdef CONFIG_PPC_PSERIES
-	/* instruct hypervisor to maintain PMCs */
-	if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
-		get_paca()->lppaca.pmcregs_in_use = 1;
-#endif /* CONFIG_PPC_PSERIES */
+	if (ppc_md.enable_pmcs)
+		ppc_md.enable_pmcs();
 }
-
-#else
-
-/* PMC stuff */
-void ppc64_enable_pmcs(void)
-{
-	/* XXX Implement for iseries */
-}
-#endif /* CONFIG_PPC_MULTIPLATFORM */
-
 EXPORT_SYMBOL(ppc64_enable_pmcs);
 
 /* XXX convert to rusty's on_one_cpu */
Index: work/arch/ppc64/oprofile/op_model_power4.c
===================================================================
--- work.orig/arch/ppc64/oprofile/op_model_power4.c
+++ work/arch/ppc64/oprofile/op_model_power4.c
@@ -83,6 +83,27 @@ static void power4_reg_setup(struct op_c
 		mmcr0_val |= MMCR0_PROBLEM_DISABLE;
 }
 
+void power4_enable_pmcs(void)
+{
+	unsigned long hid0;
+
+	hid0 = mfspr(HID0);
+	hid0 |= 1UL << (63 - 20);
+
+	/* POWER4 requires the following sequence */
+	asm volatile(
+		"sync\n"
+		"mtspr     %1, %0\n"
+		"mfspr     %0, %1\n"
+		"mfspr     %0, %1\n"
+		"mfspr     %0, %1\n"
+		"mfspr     %0, %1\n"
+		"mfspr     %0, %1\n"
+		"mfspr     %0, %1\n"
+		"isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0):
+		"memory");
+}
+
 extern void ppc64_enable_pmcs(void);
 
 static void power4_cpu_setup(void *unused)
Index: work/include/asm-ppc64/machdep.h
===================================================================
--- work.orig/include/asm-ppc64/machdep.h
+++ work/include/asm-ppc64/machdep.h
@@ -142,11 +142,16 @@ struct machdep_calls {
 
 	/* Idle loop for this platform, leave empty for default idle loop */
 	int		(*idle_loop)(void);
+
+	/* Function to enable pmcs for this platform, called once per cpu. */
+	void		(*enable_pmcs)(void);
 };
 
 extern int default_idle(void);
 extern int native_idle(void);
 
+extern void power4_enable_pmcs(void);
+
 extern struct machdep_calls ppc_md;
 extern char cmd_line[COMMAND_LINE_SIZE];
 



More information about the Linuxppc64-dev mailing list