[PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function
authorMichael Ellerman <michael@ellerman.id.au>
Tue, 9 Aug 2005 01:13:36 +0000 (11:13 +1000)
committerPaul Mackerras <paulus@samba.org>
Mon, 29 Aug 2005 00:53:38 +0000 (10:53 +1000)
This patch moves power4_enable_pmcs() to arch/ppc64/kernel/pmc.c.

I've tested it on P5 LPAR and P4. It does what it used to.

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Paul Mackerras <paulus@samba.org>
arch/ppc64/kernel/iSeries_setup.c
arch/ppc64/kernel/pSeries_setup.c
arch/ppc64/kernel/pmac_setup.c
arch/ppc64/kernel/pmc.c
arch/ppc64/kernel/sysfs.c
include/asm-ppc64/machdep.h
include/asm-ppc64/pmc.h

index b384a6ad0a5753b8300936b63901a84b0774880b..3ffefbbc6623a9e27e262691f5cb877bad32feb2 100644 (file)
@@ -964,6 +964,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 54e0651ba3fde3f557754dd1f73ecb62005ab846..f0f0630cf07cb0098030d92297f4e4d12b0ed74d 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/plpar_wrappers.h>
 #include <asm/xics.h>
 #include <asm/firmware.h>
+#include <asm/pmc.h>
 
 #include "i8259.h"
 #include "mpic.h"
@@ -187,6 +188,21 @@ static void __init pSeries_setup_mpic(void)
                                  " MPIC     ");
 }
 
+static void pseries_lpar_enable_pmcs(void)
+{
+       unsigned long set, reset;
+
+       power4_enable_pmcs();
+
+       set = 1UL << 63;
+       reset = 0;
+       plpar_hcall_norets(H_PERFMON, set, reset);
+
+       /* instruct hypervisor to maintain PMCs */
+       if (firmware_has_feature(FW_FEATURE_SPLPAR))
+               get_paca()->lppaca.pmcregs_in_use = 1;
+}
+
 static void __init pSeries_setup_arch(void)
 {
        /* Fixup ppc_md depending on the type of interrupt controller */
@@ -245,6 +261,11 @@ static void __init pSeries_setup_arch(void)
                printk(KERN_INFO "Using default idle loop\n");
                ppc_md.idle_loop = default_idle;
        }
+
+       if (systemcfg->platform & PLATFORM_LPAR)
+               ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
+       else
+               ppc_md.enable_pmcs = power4_enable_pmcs;
 }
 
 static int __init pSeries_init_panel(void)
index e40877fa67cd0efd266a78d1446f10bded9efa7e..8ff86a766cdf7d3595b5aab03224150cacc992c4 100644 (file)
@@ -71,6 +71,7 @@
 #include <asm/of_device.h>
 #include <asm/lmb.h>
 #include <asm/smu.h>
+#include <asm/pmc.h>
 
 #include "pmac.h"
 #include "mpic.h"
@@ -511,4 +512,5 @@ struct machdep_calls __initdata pmac_md = {
        .progress               = pmac_progress,
        .check_legacy_ioport    = pmac_check_legacy_ioport,
        .idle_loop              = native_idle,
+       .enable_pmcs            = power4_enable_pmcs,
 };
index 67be773f9c00d25d8df4ee6ed6c42870a57706f8..cdfec7438d0132334f17b65ec539fa919c997b91 100644 (file)
@@ -65,3 +65,24 @@ void release_pmc_hardware(void)
        spin_unlock(&pmc_owner_lock);
 }
 EXPORT_SYMBOL_GPL(release_pmc_hardware);
+
+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");
+}
index eca15d25e02615f8d8acd0ca372451bff0a9b71f..f311ee7c0070d2d024d25b78b88622e154793ce5 100644 (file)
@@ -101,6 +101,8 @@ static int __init setup_smt_snooze_delay(char *str)
 }
 __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.
@@ -110,63 +112,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;
-       }
-
-       /* instruct hypervisor to maintain PMCs */
-       if (firmware_has_feature(FW_FEATURE_SPLPAR))
-               get_paca()->lppaca.pmcregs_in_use = 1;
+       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 f0ef06375947bbb86b634338a215575a3fb143c9..ff2c9287d3b6bda6ea9cc5a01d35a5ee02f63e5c 100644 (file)
@@ -140,6 +140,9 @@ 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);
index c924748c0beaa36e9ed4502f31a6f8772766e529..d1d297dbccfec062fde2ae8011ebc32fc4617d33 100644 (file)
@@ -26,4 +26,6 @@ typedef void (*perf_irq_t)(struct pt_regs *);
 int reserve_pmc_hardware(perf_irq_t new_perf_irq);
 void release_pmc_hardware(void);
 
+void power4_enable_pmcs(void);
+
 #endif /* _PPC64_PMC_H */