diff options
| author | Michael Ellerman <michael@ellerman.id.au> | 2005-08-08 21:13:36 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2005-08-28 20:53:38 -0400 |
| commit | 180a33627d958d5d9d3602dde6ac74b315e136f0 (patch) | |
| tree | 2c480741288f1f27ff3b65a95bb67fdf2f206a8f | |
| parent | b13cfd173f73c3f6f9a307b7b6e64d45fbd756b2 (diff) | |
[PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function
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>
| -rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 2 | ||||
| -rw-r--r-- | arch/ppc64/kernel/pSeries_setup.c | 21 | ||||
| -rw-r--r-- | arch/ppc64/kernel/pmac_setup.c | 2 | ||||
| -rw-r--r-- | arch/ppc64/kernel/pmc.c | 21 | ||||
| -rw-r--r-- | arch/ppc64/kernel/sysfs.c | 54 | ||||
| -rw-r--r-- | include/asm-ppc64/machdep.h | 3 | ||||
| -rw-r--r-- | include/asm-ppc64/pmc.h | 2 |
7 files changed, 55 insertions, 50 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index b384a6ad0a57..3ffefbbc6623 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c | |||
| @@ -964,6 +964,8 @@ void __init iSeries_early_setup(void) | |||
| 964 | ppc_md.calibrate_decr = iSeries_calibrate_decr; | 964 | ppc_md.calibrate_decr = iSeries_calibrate_decr; |
| 965 | ppc_md.progress = iSeries_progress; | 965 | ppc_md.progress = iSeries_progress; |
| 966 | 966 | ||
| 967 | /* XXX Implement enable_pmcs for iSeries */ | ||
| 968 | |||
| 967 | if (get_paca()->lppaca.shared_proc) { | 969 | if (get_paca()->lppaca.shared_proc) { |
| 968 | ppc_md.idle_loop = iseries_shared_idle; | 970 | ppc_md.idle_loop = iseries_shared_idle; |
| 969 | printk(KERN_INFO "Using shared processor idle loop\n"); | 971 | printk(KERN_INFO "Using shared processor idle loop\n"); |
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index 54e0651ba3fd..f0f0630cf07c 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c | |||
| @@ -61,6 +61,7 @@ | |||
| 61 | #include <asm/plpar_wrappers.h> | 61 | #include <asm/plpar_wrappers.h> |
| 62 | #include <asm/xics.h> | 62 | #include <asm/xics.h> |
| 63 | #include <asm/firmware.h> | 63 | #include <asm/firmware.h> |
| 64 | #include <asm/pmc.h> | ||
| 64 | 65 | ||
| 65 | #include "i8259.h" | 66 | #include "i8259.h" |
| 66 | #include "mpic.h" | 67 | #include "mpic.h" |
| @@ -187,6 +188,21 @@ static void __init pSeries_setup_mpic(void) | |||
| 187 | " MPIC "); | 188 | " MPIC "); |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 191 | static void pseries_lpar_enable_pmcs(void) | ||
| 192 | { | ||
| 193 | unsigned long set, reset; | ||
| 194 | |||
| 195 | power4_enable_pmcs(); | ||
| 196 | |||
| 197 | set = 1UL << 63; | ||
| 198 | reset = 0; | ||
| 199 | plpar_hcall_norets(H_PERFMON, set, reset); | ||
| 200 | |||
| 201 | /* instruct hypervisor to maintain PMCs */ | ||
| 202 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
| 203 | get_paca()->lppaca.pmcregs_in_use = 1; | ||
| 204 | } | ||
| 205 | |||
| 190 | static void __init pSeries_setup_arch(void) | 206 | static void __init pSeries_setup_arch(void) |
| 191 | { | 207 | { |
| 192 | /* Fixup ppc_md depending on the type of interrupt controller */ | 208 | /* Fixup ppc_md depending on the type of interrupt controller */ |
| @@ -245,6 +261,11 @@ static void __init pSeries_setup_arch(void) | |||
| 245 | printk(KERN_INFO "Using default idle loop\n"); | 261 | printk(KERN_INFO "Using default idle loop\n"); |
| 246 | ppc_md.idle_loop = default_idle; | 262 | ppc_md.idle_loop = default_idle; |
| 247 | } | 263 | } |
| 264 | |||
| 265 | if (systemcfg->platform & PLATFORM_LPAR) | ||
| 266 | ppc_md.enable_pmcs = pseries_lpar_enable_pmcs; | ||
| 267 | else | ||
| 268 | ppc_md.enable_pmcs = power4_enable_pmcs; | ||
| 248 | } | 269 | } |
| 249 | 270 | ||
| 250 | static int __init pSeries_init_panel(void) | 271 | static int __init pSeries_init_panel(void) |
diff --git a/arch/ppc64/kernel/pmac_setup.c b/arch/ppc64/kernel/pmac_setup.c index e40877fa67cd..8ff86a766cdf 100644 --- a/arch/ppc64/kernel/pmac_setup.c +++ b/arch/ppc64/kernel/pmac_setup.c | |||
| @@ -71,6 +71,7 @@ | |||
| 71 | #include <asm/of_device.h> | 71 | #include <asm/of_device.h> |
| 72 | #include <asm/lmb.h> | 72 | #include <asm/lmb.h> |
| 73 | #include <asm/smu.h> | 73 | #include <asm/smu.h> |
| 74 | #include <asm/pmc.h> | ||
| 74 | 75 | ||
| 75 | #include "pmac.h" | 76 | #include "pmac.h" |
| 76 | #include "mpic.h" | 77 | #include "mpic.h" |
| @@ -511,4 +512,5 @@ struct machdep_calls __initdata pmac_md = { | |||
| 511 | .progress = pmac_progress, | 512 | .progress = pmac_progress, |
| 512 | .check_legacy_ioport = pmac_check_legacy_ioport, | 513 | .check_legacy_ioport = pmac_check_legacy_ioport, |
| 513 | .idle_loop = native_idle, | 514 | .idle_loop = native_idle, |
| 515 | .enable_pmcs = power4_enable_pmcs, | ||
| 514 | }; | 516 | }; |
diff --git a/arch/ppc64/kernel/pmc.c b/arch/ppc64/kernel/pmc.c index 67be773f9c00..cdfec7438d01 100644 --- a/arch/ppc64/kernel/pmc.c +++ b/arch/ppc64/kernel/pmc.c | |||
| @@ -65,3 +65,24 @@ void release_pmc_hardware(void) | |||
| 65 | spin_unlock(&pmc_owner_lock); | 65 | spin_unlock(&pmc_owner_lock); |
| 66 | } | 66 | } |
| 67 | EXPORT_SYMBOL_GPL(release_pmc_hardware); | 67 | EXPORT_SYMBOL_GPL(release_pmc_hardware); |
| 68 | |||
| 69 | void power4_enable_pmcs(void) | ||
| 70 | { | ||
| 71 | unsigned long hid0; | ||
| 72 | |||
| 73 | hid0 = mfspr(HID0); | ||
| 74 | hid0 |= 1UL << (63 - 20); | ||
| 75 | |||
| 76 | /* POWER4 requires the following sequence */ | ||
| 77 | asm volatile( | ||
| 78 | "sync\n" | ||
| 79 | "mtspr %1, %0\n" | ||
| 80 | "mfspr %0, %1\n" | ||
| 81 | "mfspr %0, %1\n" | ||
| 82 | "mfspr %0, %1\n" | ||
| 83 | "mfspr %0, %1\n" | ||
| 84 | "mfspr %0, %1\n" | ||
| 85 | "mfspr %0, %1\n" | ||
| 86 | "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): | ||
| 87 | "memory"); | ||
| 88 | } | ||
diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index eca15d25e026..f311ee7c0070 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c | |||
| @@ -101,6 +101,8 @@ static int __init setup_smt_snooze_delay(char *str) | |||
| 101 | } | 101 | } |
| 102 | __setup("smt-snooze-delay=", setup_smt_snooze_delay); | 102 | __setup("smt-snooze-delay=", setup_smt_snooze_delay); |
| 103 | 103 | ||
| 104 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
| 105 | |||
| 104 | /* | 106 | /* |
| 105 | * Enabling PMCs will slow partition context switch times so we only do | 107 | * Enabling PMCs will slow partition context switch times so we only do |
| 106 | * it the first time we write to the PMCs. | 108 | * it the first time we write to the PMCs. |
| @@ -110,63 +112,15 @@ static DEFINE_PER_CPU(char, pmcs_enabled); | |||
| 110 | 112 | ||
| 111 | void ppc64_enable_pmcs(void) | 113 | void ppc64_enable_pmcs(void) |
| 112 | { | 114 | { |
| 113 | unsigned long hid0; | ||
| 114 | #ifdef CONFIG_PPC_PSERIES | ||
| 115 | unsigned long set, reset; | ||
| 116 | #endif /* CONFIG_PPC_PSERIES */ | ||
| 117 | |||
| 118 | /* Only need to enable them once */ | 115 | /* Only need to enable them once */ |
| 119 | if (__get_cpu_var(pmcs_enabled)) | 116 | if (__get_cpu_var(pmcs_enabled)) |
| 120 | return; | 117 | return; |
| 121 | 118 | ||
| 122 | __get_cpu_var(pmcs_enabled) = 1; | 119 | __get_cpu_var(pmcs_enabled) = 1; |
| 123 | 120 | ||
| 124 | switch (systemcfg->platform) { | 121 | if (ppc_md.enable_pmcs) |
| 125 | case PLATFORM_PSERIES: | 122 | ppc_md.enable_pmcs(); |
| 126 | case PLATFORM_POWERMAC: | ||
| 127 | hid0 = mfspr(HID0); | ||
| 128 | hid0 |= 1UL << (63 - 20); | ||
| 129 | |||
| 130 | /* POWER4 requires the following sequence */ | ||
| 131 | asm volatile( | ||
| 132 | "sync\n" | ||
| 133 | "mtspr %1, %0\n" | ||
| 134 | "mfspr %0, %1\n" | ||
| 135 | "mfspr %0, %1\n" | ||
| 136 | "mfspr %0, %1\n" | ||
| 137 | "mfspr %0, %1\n" | ||
| 138 | "mfspr %0, %1\n" | ||
| 139 | "mfspr %0, %1\n" | ||
| 140 | "isync" : "=&r" (hid0) : "i" (HID0), "0" (hid0): | ||
| 141 | "memory"); | ||
| 142 | break; | ||
| 143 | |||
| 144 | #ifdef CONFIG_PPC_PSERIES | ||
| 145 | case PLATFORM_PSERIES_LPAR: | ||
| 146 | set = 1UL << 63; | ||
| 147 | reset = 0; | ||
| 148 | plpar_hcall_norets(H_PERFMON, set, reset); | ||
| 149 | break; | ||
| 150 | #endif /* CONFIG_PPC_PSERIES */ | ||
| 151 | |||
| 152 | default: | ||
| 153 | break; | ||
| 154 | } | ||
| 155 | |||
| 156 | /* instruct hypervisor to maintain PMCs */ | ||
| 157 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) | ||
| 158 | get_paca()->lppaca.pmcregs_in_use = 1; | ||
| 159 | } | 123 | } |
| 160 | |||
| 161 | #else | ||
| 162 | |||
| 163 | /* PMC stuff */ | ||
| 164 | void ppc64_enable_pmcs(void) | ||
| 165 | { | ||
| 166 | /* XXX Implement for iseries */ | ||
| 167 | } | ||
| 168 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | ||
| 169 | |||
| 170 | EXPORT_SYMBOL(ppc64_enable_pmcs); | 124 | EXPORT_SYMBOL(ppc64_enable_pmcs); |
| 171 | 125 | ||
| 172 | /* XXX convert to rusty's on_one_cpu */ | 126 | /* XXX convert to rusty's on_one_cpu */ |
diff --git a/include/asm-ppc64/machdep.h b/include/asm-ppc64/machdep.h index f0ef06375947..ff2c9287d3b6 100644 --- a/include/asm-ppc64/machdep.h +++ b/include/asm-ppc64/machdep.h | |||
| @@ -140,6 +140,9 @@ struct machdep_calls { | |||
| 140 | 140 | ||
| 141 | /* Idle loop for this platform, leave empty for default idle loop */ | 141 | /* Idle loop for this platform, leave empty for default idle loop */ |
| 142 | int (*idle_loop)(void); | 142 | int (*idle_loop)(void); |
| 143 | |||
| 144 | /* Function to enable pmcs for this platform, called once per cpu. */ | ||
| 145 | void (*enable_pmcs)(void); | ||
| 143 | }; | 146 | }; |
| 144 | 147 | ||
| 145 | extern int default_idle(void); | 148 | extern int default_idle(void); |
diff --git a/include/asm-ppc64/pmc.h b/include/asm-ppc64/pmc.h index c924748c0bea..d1d297dbccfe 100644 --- a/include/asm-ppc64/pmc.h +++ b/include/asm-ppc64/pmc.h | |||
| @@ -26,4 +26,6 @@ typedef void (*perf_irq_t)(struct pt_regs *); | |||
| 26 | int reserve_pmc_hardware(perf_irq_t new_perf_irq); | 26 | int reserve_pmc_hardware(perf_irq_t new_perf_irq); |
| 27 | void release_pmc_hardware(void); | 27 | void release_pmc_hardware(void); |
| 28 | 28 | ||
| 29 | void power4_enable_pmcs(void); | ||
| 30 | |||
| 29 | #endif /* _PPC64_PMC_H */ | 31 | #endif /* _PPC64_PMC_H */ |
