[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>
This commit is contained in:
Родитель
b13cfd173f
Коммит
180a33627d
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче