mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-16 09:56:46 +00:00
[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:
parent
b13cfd173f
commit
180a33627d
@ -964,6 +964,8 @@ void __init iSeries_early_setup(void)
|
|||||||
ppc_md.calibrate_decr = iSeries_calibrate_decr;
|
ppc_md.calibrate_decr = iSeries_calibrate_decr;
|
||||||
ppc_md.progress = iSeries_progress;
|
ppc_md.progress = iSeries_progress;
|
||||||
|
|
||||||
|
/* XXX Implement enable_pmcs for iSeries */
|
||||||
|
|
||||||
if (get_paca()->lppaca.shared_proc) {
|
if (get_paca()->lppaca.shared_proc) {
|
||||||
ppc_md.idle_loop = iseries_shared_idle;
|
ppc_md.idle_loop = iseries_shared_idle;
|
||||||
printk(KERN_INFO "Using shared processor idle loop\n");
|
printk(KERN_INFO "Using shared processor idle loop\n");
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include <asm/plpar_wrappers.h>
|
#include <asm/plpar_wrappers.h>
|
||||||
#include <asm/xics.h>
|
#include <asm/xics.h>
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/pmc.h>
|
||||||
|
|
||||||
#include "i8259.h"
|
#include "i8259.h"
|
||||||
#include "mpic.h"
|
#include "mpic.h"
|
||||||
@ -187,6 +188,21 @@ static void __init pSeries_setup_mpic(void)
|
|||||||
" MPIC ");
|
" 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)
|
static void __init pSeries_setup_arch(void)
|
||||||
{
|
{
|
||||||
/* Fixup ppc_md depending on the type of interrupt controller */
|
/* 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");
|
printk(KERN_INFO "Using default idle loop\n");
|
||||||
ppc_md.idle_loop = default_idle;
|
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)
|
static int __init pSeries_init_panel(void)
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
#include <asm/of_device.h>
|
#include <asm/of_device.h>
|
||||||
#include <asm/lmb.h>
|
#include <asm/lmb.h>
|
||||||
#include <asm/smu.h>
|
#include <asm/smu.h>
|
||||||
|
#include <asm/pmc.h>
|
||||||
|
|
||||||
#include "pmac.h"
|
#include "pmac.h"
|
||||||
#include "mpic.h"
|
#include "mpic.h"
|
||||||
@ -511,4 +512,5 @@ struct machdep_calls __initdata pmac_md = {
|
|||||||
.progress = pmac_progress,
|
.progress = pmac_progress,
|
||||||
.check_legacy_ioport = pmac_check_legacy_ioport,
|
.check_legacy_ioport = pmac_check_legacy_ioport,
|
||||||
.idle_loop = native_idle,
|
.idle_loop = native_idle,
|
||||||
|
.enable_pmcs = power4_enable_pmcs,
|
||||||
};
|
};
|
||||||
|
@ -65,3 +65,24 @@ void release_pmc_hardware(void)
|
|||||||
spin_unlock(&pmc_owner_lock);
|
spin_unlock(&pmc_owner_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(release_pmc_hardware);
|
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);
|
__setup("smt-snooze-delay=", setup_smt_snooze_delay);
|
||||||
|
|
||||||
|
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enabling PMCs will slow partition context switch times so we only do
|
* Enabling PMCs will slow partition context switch times so we only do
|
||||||
* it the first time we write to the PMCs.
|
* 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)
|
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 */
|
/* Only need to enable them once */
|
||||||
if (__get_cpu_var(pmcs_enabled))
|
if (__get_cpu_var(pmcs_enabled))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__get_cpu_var(pmcs_enabled) = 1;
|
__get_cpu_var(pmcs_enabled) = 1;
|
||||||
|
|
||||||
switch (systemcfg->platform) {
|
if (ppc_md.enable_pmcs)
|
||||||
case PLATFORM_PSERIES:
|
ppc_md.enable_pmcs();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* PMC stuff */
|
|
||||||
void ppc64_enable_pmcs(void)
|
|
||||||
{
|
|
||||||
/* XXX Implement for iseries */
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(ppc64_enable_pmcs);
|
EXPORT_SYMBOL(ppc64_enable_pmcs);
|
||||||
|
|
||||||
/* XXX convert to rusty's on_one_cpu */
|
/* 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 */
|
/* Idle loop for this platform, leave empty for default idle loop */
|
||||||
int (*idle_loop)(void);
|
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 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);
|
int reserve_pmc_hardware(perf_irq_t new_perf_irq);
|
||||||
void release_pmc_hardware(void);
|
void release_pmc_hardware(void);
|
||||||
|
|
||||||
|
void power4_enable_pmcs(void);
|
||||||
|
|
||||||
#endif /* _PPC64_PMC_H */
|
#endif /* _PPC64_PMC_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user