Skip to content

Commit

Permalink
[PATCH] ppc64: Move ppc64_enable_pmcs() logic into a ppc_md function
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Ellerman authored and Paul Mackerras committed Aug 29, 2005
1 parent b13cfd1 commit 180a336
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 50 deletions.
2 changes: 2 additions & 0 deletions arch/ppc64/kernel/iSeries_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
21 changes: 21 additions & 0 deletions arch/ppc64/kernel/pSeries_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions arch/ppc64/kernel/pmac_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
};
21 changes: 21 additions & 0 deletions arch/ppc64/kernel/pmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
54 changes: 4 additions & 50 deletions arch/ppc64/kernel/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 */
Expand Down
3 changes: 3 additions & 0 deletions include/asm-ppc64/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions include/asm-ppc64/pmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 180a336

Please sign in to comment.