diff options
Diffstat (limited to 'arch/ppc64/kernel/pSeries_setup.c')
-rw-r--r-- | arch/ppc64/kernel/pSeries_setup.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/arch/ppc64/kernel/pSeries_setup.c b/arch/ppc64/kernel/pSeries_setup.c index 5bec956e44a..f0f0630cf07 100644 --- a/arch/ppc64/kernel/pSeries_setup.c +++ b/arch/ppc64/kernel/pSeries_setup.c | |||
@@ -60,7 +60,8 @@ | |||
60 | #include <asm/nvram.h> | 60 | #include <asm/nvram.h> |
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/cputable.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 */ |
@@ -231,11 +247,9 @@ static void __init pSeries_setup_arch(void) | |||
231 | 247 | ||
232 | pSeries_nvram_init(); | 248 | pSeries_nvram_init(); |
233 | 249 | ||
234 | if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) | ||
235 | vpa_init(boot_cpuid); | ||
236 | |||
237 | /* Choose an idle loop */ | 250 | /* Choose an idle loop */ |
238 | if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { | 251 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
252 | vpa_init(boot_cpuid); | ||
239 | if (get_paca()->lppaca.shared_proc) { | 253 | if (get_paca()->lppaca.shared_proc) { |
240 | printk(KERN_INFO "Using shared processor idle loop\n"); | 254 | printk(KERN_INFO "Using shared processor idle loop\n"); |
241 | ppc_md.idle_loop = pseries_shared_idle; | 255 | ppc_md.idle_loop = pseries_shared_idle; |
@@ -247,6 +261,11 @@ static void __init pSeries_setup_arch(void) | |||
247 | printk(KERN_INFO "Using default idle loop\n"); | 261 | printk(KERN_INFO "Using default idle loop\n"); |
248 | ppc_md.idle_loop = default_idle; | 262 | ppc_md.idle_loop = default_idle; |
249 | } | 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; | ||
250 | } | 269 | } |
251 | 270 | ||
252 | static int __init pSeries_init_panel(void) | 271 | static int __init pSeries_init_panel(void) |
@@ -260,11 +279,11 @@ static int __init pSeries_init_panel(void) | |||
260 | arch_initcall(pSeries_init_panel); | 279 | arch_initcall(pSeries_init_panel); |
261 | 280 | ||
262 | 281 | ||
263 | /* Build up the firmware_features bitmask field | 282 | /* Build up the ppc64_firmware_features bitmask field |
264 | * using contents of device-tree/ibm,hypertas-functions. | 283 | * using contents of device-tree/ibm,hypertas-functions. |
265 | * Ultimately this functionality may be moved into prom.c prom_init(). | 284 | * Ultimately this functionality may be moved into prom.c prom_init(). |
266 | */ | 285 | */ |
267 | void __init fw_feature_init(void) | 286 | static void __init fw_feature_init(void) |
268 | { | 287 | { |
269 | struct device_node * dn; | 288 | struct device_node * dn; |
270 | char * hypertas; | 289 | char * hypertas; |
@@ -272,7 +291,7 @@ void __init fw_feature_init(void) | |||
272 | 291 | ||
273 | DBG(" -> fw_feature_init()\n"); | 292 | DBG(" -> fw_feature_init()\n"); |
274 | 293 | ||
275 | cur_cpu_spec->firmware_features = 0; | 294 | ppc64_firmware_features = 0; |
276 | dn = of_find_node_by_path("/rtas"); | 295 | dn = of_find_node_by_path("/rtas"); |
277 | if (dn == NULL) { | 296 | if (dn == NULL) { |
278 | printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n"); | 297 | printk(KERN_ERR "WARNING ! Cannot find RTAS in device-tree !\n"); |
@@ -288,7 +307,7 @@ void __init fw_feature_init(void) | |||
288 | if ((firmware_features_table[i].name) && | 307 | if ((firmware_features_table[i].name) && |
289 | (strcmp(firmware_features_table[i].name,hypertas))==0) { | 308 | (strcmp(firmware_features_table[i].name,hypertas))==0) { |
290 | /* we have a match */ | 309 | /* we have a match */ |
291 | cur_cpu_spec->firmware_features |= | 310 | ppc64_firmware_features |= |
292 | (firmware_features_table[i].val); | 311 | (firmware_features_table[i].val); |
293 | break; | 312 | break; |
294 | } | 313 | } |
@@ -302,7 +321,7 @@ void __init fw_feature_init(void) | |||
302 | of_node_put(dn); | 321 | of_node_put(dn); |
303 | no_rtas: | 322 | no_rtas: |
304 | printk(KERN_INFO "firmware_features = 0x%lx\n", | 323 | printk(KERN_INFO "firmware_features = 0x%lx\n", |
305 | cur_cpu_spec->firmware_features); | 324 | ppc64_firmware_features); |
306 | 325 | ||
307 | DBG(" <- fw_feature_init()\n"); | 326 | DBG(" <- fw_feature_init()\n"); |
308 | } | 327 | } |