Blackfin arch: remove hardware PM code, oprofile not use it
Signed-off-by: Graf Yang <graf.yang@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org>
This commit is contained in:
Родитель
e32f55d9db
Коммит
172e65e778
|
@ -1007,12 +1007,6 @@ config EBIU_FCTLVAL
|
|||
hex "Flash Memory Bank Control Register"
|
||||
depends on BF54x
|
||||
default 6
|
||||
|
||||
config HARDWARE_PM
|
||||
bool "OProfile use hardware porformance monitor"
|
||||
depends on OPROFILE=y
|
||||
default n
|
||||
|
||||
endmenu
|
||||
|
||||
#############################################################################
|
||||
|
|
|
@ -165,16 +165,6 @@ ENTRY(_evt_ivhw)
|
|||
r0 = [p2];
|
||||
[sp + PT_IPEND] = r0;
|
||||
|
||||
#ifdef CONFIG_HARDWARE_PM
|
||||
r7 = [sp + PT_SEQSTAT];
|
||||
r7 = r7 >>> 0xe;
|
||||
r6 = 0x1F;
|
||||
r7 = r7 & r6;
|
||||
r5 = 0x12;
|
||||
cc = r7 == r5;
|
||||
if cc jump .Lcall_do_ovf; /* deal with performance counter overflow */
|
||||
#endif
|
||||
|
||||
/* set the EXCAUSE to HWERR for trap_c */
|
||||
r0 = [sp + PT_SEQSTAT];
|
||||
R1.L = LO(VEC_HWERR);
|
||||
|
@ -200,18 +190,6 @@ ENTRY(_evt_ivhw)
|
|||
.Lcommon_restore_all_sys:
|
||||
RESTORE_ALL_SYS
|
||||
rti;
|
||||
|
||||
#ifdef CONFIG_HARDWARE_PM
|
||||
.Lcall_do_ovf:
|
||||
|
||||
R0 = SP;
|
||||
SP += -12;
|
||||
call _pm_overflow;
|
||||
SP += 12;
|
||||
|
||||
jump .Lcommon_restore_all_sys;
|
||||
#endif
|
||||
|
||||
ENDPROC(_evt_ivhw)
|
||||
|
||||
/* Interrupt routine for evt2 (NMI).
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include <asm/traps.h>
|
||||
#include <asm/blackfin.h>
|
||||
|
||||
#include "../oprofile/op_blackfin.h"
|
||||
|
||||
#ifdef CONFIG_DEBUG_ICACHE_CHECK
|
||||
#define L1_ICACHE_START 0xffa10000
|
||||
#define L1_ICACHE_END 0xffa13fff
|
||||
|
@ -134,13 +132,3 @@ asmlinkage void irq_panic(int reason, struct pt_regs *regs)
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HARDWARE_PM
|
||||
/*
|
||||
* call the handler of Performance overflow
|
||||
*/
|
||||
asmlinkage void pm_overflow(struct pt_regs *regs)
|
||||
{
|
||||
pm_overflow_handler(regs);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,4 +11,3 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
|
|||
timer_int.o )
|
||||
|
||||
oprofile-y := $(DRIVER_OBJS) common.o
|
||||
oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o
|
||||
|
|
|
@ -30,129 +30,10 @@
|
|||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/blackfin.h>
|
||||
|
||||
#include "op_blackfin.h"
|
||||
|
||||
#define BFIN_533_ID 0xE5040003
|
||||
#define BFIN_537_ID 0xE5040002
|
||||
|
||||
static int pfmon_enabled;
|
||||
static struct mutex pfmon_lock;
|
||||
|
||||
struct op_bfin533_model *model;
|
||||
|
||||
struct op_counter_config ctr[OP_MAX_COUNTER];
|
||||
|
||||
static int op_bfin_setup(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Pre-compute the values to stuff in the hardware registers. */
|
||||
spin_lock(&oprofilefs_lock);
|
||||
ret = model->reg_setup(ctr);
|
||||
spin_unlock(&oprofilefs_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void op_bfin_shutdown(void)
|
||||
{
|
||||
#if 0
|
||||
/* what is the difference between shutdown and stop? */
|
||||
#endif
|
||||
}
|
||||
|
||||
static int op_bfin_start(void)
|
||||
{
|
||||
int ret = -EBUSY;
|
||||
|
||||
printk(KERN_INFO "KSDBG:in %s\n", __func__);
|
||||
mutex_lock(&pfmon_lock);
|
||||
if (!pfmon_enabled) {
|
||||
ret = model->start(ctr);
|
||||
pfmon_enabled = !ret;
|
||||
}
|
||||
mutex_unlock(&pfmon_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void op_bfin_stop(void)
|
||||
{
|
||||
mutex_lock(&pfmon_lock);
|
||||
if (pfmon_enabled) {
|
||||
model->stop();
|
||||
pfmon_enabled = 0;
|
||||
}
|
||||
mutex_unlock(&pfmon_lock);
|
||||
}
|
||||
|
||||
static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < model->num_counters; ++i) {
|
||||
struct dentry *dir;
|
||||
char buf[3];
|
||||
printk(KERN_INFO "Oprofile: creating files... \n");
|
||||
|
||||
snprintf(buf, sizeof buf, "%d", i);
|
||||
dir = oprofilefs_mkdir(sb, root, buf);
|
||||
|
||||
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
|
||||
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
|
||||
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
|
||||
/*
|
||||
* We dont support per counter user/kernel selection, but
|
||||
* we leave the entries because userspace expects them
|
||||
*/
|
||||
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
|
||||
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
|
||||
oprofilefs_create_ulong(sb, dir, "unit_mask",
|
||||
&ctr[i].unit_mask);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int __init oprofile_arch_init(struct oprofile_operations *ops)
|
||||
{
|
||||
#ifdef CONFIG_HARDWARE_PM
|
||||
mutex_init(&pfmon_lock);
|
||||
|
||||
|
||||
switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) {
|
||||
case 0xca:
|
||||
printk(KERN_INFO "Oprofile: cpu vendor is Analog Devices.\n");
|
||||
model = &op_model_bfin533;
|
||||
model->num_counters = 2;
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ops->cpu_type = model->name;
|
||||
ops->create_files = op_bfin_create_files;
|
||||
ops->setup = op_bfin_setup;
|
||||
ops->shutdown = op_bfin_shutdown;
|
||||
ops->start = op_bfin_start;
|
||||
ops->stop = op_bfin_stop;
|
||||
|
||||
printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
|
||||
ops->cpu_type);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void oprofile_arch_exit(void)
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
* File: arch/blackfin/oprofile/op_blackfin.h
|
||||
* Based on:
|
||||
* Author: Anton Blanchard <anton@au.ibm.com>
|
||||
*
|
||||
* Created:
|
||||
* Description:
|
||||
*
|
||||
* Modified:
|
||||
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
|
||||
* Copyright 2004-2006 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef OP_BLACKFIN_H
|
||||
#define OP_BLACKFIN_H 1
|
||||
|
||||
#define OP_MAX_COUNTER 2
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
|
||||
/* Per-counter configuration as set via oprofilefs. */
|
||||
struct op_counter_config {
|
||||
unsigned long valid;
|
||||
unsigned long enabled;
|
||||
unsigned long event;
|
||||
unsigned long count;
|
||||
unsigned long kernel;
|
||||
unsigned long user;
|
||||
unsigned long unit_mask;
|
||||
};
|
||||
|
||||
/* System-wide configuration as set via oprofilefs. */
|
||||
struct op_system_config {
|
||||
unsigned long enable_kernel;
|
||||
unsigned long enable_user;
|
||||
};
|
||||
|
||||
/* Per-arch configuration */
|
||||
struct op_bfin533_model {
|
||||
int (*reg_setup) (struct op_counter_config *);
|
||||
int (*start) (struct op_counter_config *);
|
||||
void (*stop) (void);
|
||||
int num_counters;
|
||||
char *name;
|
||||
};
|
||||
|
||||
extern struct op_bfin533_model op_model_bfin533;
|
||||
|
||||
static inline unsigned int ctr_read(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = bfin_read_PFCTL();
|
||||
CSYNC();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static inline void ctr_write(unsigned int val)
|
||||
{
|
||||
bfin_write_PFCTL(val);
|
||||
CSYNC();
|
||||
}
|
||||
|
||||
static inline void count_read(unsigned int *count)
|
||||
{
|
||||
count[0] = bfin_read_PFCNTR0();
|
||||
count[1] = bfin_read_PFCNTR1();
|
||||
CSYNC();
|
||||
}
|
||||
|
||||
static inline void count_write(unsigned int *count)
|
||||
{
|
||||
bfin_write_PFCNTR0(count[0]);
|
||||
bfin_write_PFCNTR1(count[1]);
|
||||
CSYNC();
|
||||
}
|
||||
|
||||
extern int pm_overflow_handler(struct pt_regs *regs);
|
||||
|
||||
#endif
|
|
@ -1,161 +0,0 @@
|
|||
/*
|
||||
* File: arch/blackfin/oprofile/op_model_bf533.c
|
||||
* Based on:
|
||||
* Author: Anton Blanchard <anton@au.ibm.com>
|
||||
*
|
||||
* Created:
|
||||
* Description:
|
||||
*
|
||||
* Modified:
|
||||
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
|
||||
* Copyright 2004-2006 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/blackfin.h>
|
||||
|
||||
#include "op_blackfin.h"
|
||||
|
||||
#define PM_ENABLE 0x01;
|
||||
#define PM_CTL1_ENABLE 0x18
|
||||
#define PM_CTL0_ENABLE 0xC000
|
||||
#define COUNT_EDGE_ONLY 0x3000000
|
||||
|
||||
static int oprofile_running;
|
||||
|
||||
static unsigned curr_pfctl, curr_count[2];
|
||||
|
||||
static int bfin533_reg_setup(struct op_counter_config *ctr)
|
||||
{
|
||||
unsigned int pfctl = 0;
|
||||
unsigned int count[2];
|
||||
|
||||
/* set Blackfin perf monitor regs with ctr */
|
||||
if (ctr[0].enabled) {
|
||||
pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5));
|
||||
count[0] = 0xFFFFFFFF - ctr[0].count;
|
||||
curr_count[0] = count[0];
|
||||
}
|
||||
if (ctr[1].enabled) {
|
||||
pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16));
|
||||
count[1] = 0xFFFFFFFF - ctr[1].count;
|
||||
curr_count[1] = count[1];
|
||||
}
|
||||
|
||||
pr_debug("ctr[0].enabled=%d,ctr[1].enabled=%d,ctr[0].event<<5=0x%x,ctr[1].event<<16=0x%x\n", ctr[0].enabled, ctr[1].enabled, ctr[0].event << 5, ctr[1].event << 16);
|
||||
pfctl |= COUNT_EDGE_ONLY;
|
||||
curr_pfctl = pfctl;
|
||||
|
||||
pr_debug("write 0x%x to pfctl\n", pfctl);
|
||||
ctr_write(pfctl);
|
||||
count_write(count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bfin533_start(struct op_counter_config *ctr)
|
||||
{
|
||||
unsigned int pfctl = ctr_read();
|
||||
|
||||
pfctl |= PM_ENABLE;
|
||||
curr_pfctl = pfctl;
|
||||
|
||||
ctr_write(pfctl);
|
||||
|
||||
oprofile_running = 1;
|
||||
pr_debug("start oprofile counter \n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bfin533_stop(void)
|
||||
{
|
||||
int pfctl;
|
||||
|
||||
pfctl = ctr_read();
|
||||
pfctl &= ~PM_ENABLE;
|
||||
/* freeze counters */
|
||||
ctr_write(pfctl);
|
||||
|
||||
oprofile_running = 0;
|
||||
pr_debug("stop oprofile counter \n");
|
||||
}
|
||||
|
||||
static int get_kernel(void)
|
||||
{
|
||||
int ipend, is_kernel;
|
||||
|
||||
ipend = bfin_read_IPEND();
|
||||
|
||||
/* test bit 15 */
|
||||
is_kernel = ((ipend & 0x8000) != 0);
|
||||
|
||||
return is_kernel;
|
||||
}
|
||||
|
||||
int pm_overflow_handler(struct pt_regs *regs)
|
||||
{
|
||||
int is_kernel;
|
||||
int i, cpu;
|
||||
unsigned int pc, pfctl;
|
||||
unsigned int count[2];
|
||||
|
||||
pr_debug("get interrupt in %s\n", __func__);
|
||||
if (oprofile_running == 0) {
|
||||
pr_debug("error: entering interrupt when oprofile is stopped.\n\r");
|
||||
return -1;
|
||||
}
|
||||
|
||||
is_kernel = get_kernel();
|
||||
cpu = smp_processor_id();
|
||||
pc = regs->pc;
|
||||
pfctl = ctr_read();
|
||||
|
||||
/* read the two event counter regs */
|
||||
count_read(count);
|
||||
|
||||
/* if the counter overflows, add sample to oprofile buffer */
|
||||
for (i = 0; i < 2; ++i) {
|
||||
if (oprofile_running) {
|
||||
oprofile_add_sample(regs, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the perfmon counter */
|
||||
ctr_write(curr_pfctl);
|
||||
count_write(curr_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct op_bfin533_model op_model_bfin533 = {
|
||||
.reg_setup = bfin533_reg_setup,
|
||||
.start = bfin533_start,
|
||||
.stop = bfin533_stop,
|
||||
.num_counters = 2,
|
||||
.name = "blackfin/bf533"
|
||||
};
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* File: arch/blackfin/oprofile/timer_int.c
|
||||
* Based on:
|
||||
* Author: Michael Kang
|
||||
*
|
||||
* Created:
|
||||
* Description:
|
||||
*
|
||||
* Modified:
|
||||
* Copyright 2004-2006 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/oprofile.h>
|
||||
#include <linux/ptrace.h>
|
||||
|
||||
static void enable_sys_timer0()
|
||||
{
|
||||
}
|
||||
static void disable_sys_timer0()
|
||||
{
|
||||
}
|
||||
|
||||
static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
oprofile_add_sample(regs, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int sys_timer0_start(void)
|
||||
{
|
||||
enable_sys_timer0();
|
||||
return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL);
|
||||
}
|
||||
|
||||
static void sys_timer0_stop(void)
|
||||
{
|
||||
disable_sys_timer();
|
||||
}
|
||||
|
||||
int __init sys_timer0_init(struct oprofile_operations *ops)
|
||||
{
|
||||
extern int nmi_active;
|
||||
|
||||
if (nmi_active <= 0)
|
||||
return -ENODEV;
|
||||
|
||||
ops->start = timer_start;
|
||||
ops->stop = timer_stop;
|
||||
ops->cpu_type = "timer";
|
||||
printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
|
||||
return 0;
|
||||
}
|
Загрузка…
Ссылка в новой задаче