aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/oprofile
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/oprofile')
-rw-r--r--arch/blackfin/oprofile/Makefile3
-rw-r--r--arch/blackfin/oprofile/bfin_oprofile.c18
-rw-r--r--arch/blackfin/oprofile/common.c168
-rw-r--r--arch/blackfin/oprofile/op_blackfin.h98
-rw-r--r--arch/blackfin/oprofile/op_model_bf533.c161
-rw-r--r--arch/blackfin/oprofile/timer_int.c73
6 files changed, 19 insertions, 502 deletions
diff --git a/arch/blackfin/oprofile/Makefile b/arch/blackfin/oprofile/Makefile
index 634e300d67e2..c70af3a01297 100644
--- a/arch/blackfin/oprofile/Makefile
+++ b/arch/blackfin/oprofile/Makefile
@@ -10,5 +10,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
10 oprofilefs.o oprofile_stats.o \ 10 oprofilefs.o oprofile_stats.o \
11 timer_int.o ) 11 timer_int.o )
12 12
13oprofile-y := $(DRIVER_OBJS) common.o 13oprofile-y := $(DRIVER_OBJS) bfin_oprofile.o
14oprofile-$(CONFIG_HARDWARE_PM) += op_model_bf533.o
diff --git a/arch/blackfin/oprofile/bfin_oprofile.c b/arch/blackfin/oprofile/bfin_oprofile.c
new file mode 100644
index 000000000000..c3b9713b23f8
--- /dev/null
+++ b/arch/blackfin/oprofile/bfin_oprofile.c
@@ -0,0 +1,18 @@
1/*
2 * bfin_oprofile.c - Blackfin oprofile code
3 *
4 * Copyright 2004-2008 Analog Devices Inc.
5 * Licensed under the GPL-2 or later.
6 */
7
8#include <linux/oprofile.h>
9#include <linux/init.h>
10
11int __init oprofile_arch_init(struct oprofile_operations *ops)
12{
13 return -1;
14}
15
16void oprofile_arch_exit(void)
17{
18}
diff --git a/arch/blackfin/oprofile/common.c b/arch/blackfin/oprofile/common.c
deleted file mode 100644
index 0f6d303a8891..000000000000
--- a/arch/blackfin/oprofile/common.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * File: arch/blackfin/oprofile/common.c
3 * Based on: arch/alpha/oprofile/common.c
4 * Author: Anton Blanchard <anton@au.ibm.com>
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#include <linux/oprofile.h>
32#include <linux/init.h>
33#include <linux/smp.h>
34#include <linux/errno.h>
35#include <linux/mutex.h>
36#include <linux/ptrace.h>
37#include <linux/irq.h>
38#include <linux/io.h>
39
40#include <asm/system.h>
41#include <asm/blackfin.h>
42
43#include "op_blackfin.h"
44
45#define BFIN_533_ID 0xE5040003
46#define BFIN_537_ID 0xE5040002
47
48static int pfmon_enabled;
49static struct mutex pfmon_lock;
50
51struct op_bfin533_model *model;
52
53struct op_counter_config ctr[OP_MAX_COUNTER];
54
55static int op_bfin_setup(void)
56{
57 int ret;
58
59 /* Pre-compute the values to stuff in the hardware registers. */
60 spin_lock(&oprofilefs_lock);
61 ret = model->reg_setup(ctr);
62 spin_unlock(&oprofilefs_lock);
63
64 return ret;
65}
66
67static void op_bfin_shutdown(void)
68{
69#if 0
70 /* what is the difference between shutdown and stop? */
71#endif
72}
73
74static int op_bfin_start(void)
75{
76 int ret = -EBUSY;
77
78 printk(KERN_INFO "KSDBG:in %s\n", __func__);
79 mutex_lock(&pfmon_lock);
80 if (!pfmon_enabled) {
81 ret = model->start(ctr);
82 pfmon_enabled = !ret;
83 }
84 mutex_unlock(&pfmon_lock);
85
86 return ret;
87}
88
89static void op_bfin_stop(void)
90{
91 mutex_lock(&pfmon_lock);
92 if (pfmon_enabled) {
93 model->stop();
94 pfmon_enabled = 0;
95 }
96 mutex_unlock(&pfmon_lock);
97}
98
99static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
100{
101 int i;
102
103 for (i = 0; i < model->num_counters; ++i) {
104 struct dentry *dir;
105 char buf[3];
106 printk(KERN_INFO "Oprofile: creating files... \n");
107
108 snprintf(buf, sizeof buf, "%d", i);
109 dir = oprofilefs_mkdir(sb, root, buf);
110
111 oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
112 oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
113 oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
114 /*
115 * We dont support per counter user/kernel selection, but
116 * we leave the entries because userspace expects them
117 */
118 oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
119 oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
120 oprofilefs_create_ulong(sb, dir, "unit_mask",
121 &ctr[i].unit_mask);
122 }
123
124 return 0;
125}
126int __init oprofile_arch_init(struct oprofile_operations *ops)
127{
128#ifdef CONFIG_HARDWARE_PM
129 unsigned int dspid;
130
131 mutex_init(&pfmon_lock);
132
133 dspid = bfin_read_DSPID();
134
135 printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid);
136
137 switch (dspid) {
138 case BFIN_533_ID:
139 model = &op_model_bfin533;
140 model->num_counters = 2;
141 break;
142 case BFIN_537_ID:
143 model = &op_model_bfin533;
144 model->num_counters = 2;
145 break;
146 default:
147 return -ENODEV;
148 }
149
150 ops->cpu_type = model->name;
151 ops->create_files = op_bfin_create_files;
152 ops->setup = op_bfin_setup;
153 ops->shutdown = op_bfin_shutdown;
154 ops->start = op_bfin_start;
155 ops->stop = op_bfin_stop;
156
157 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
158 ops->cpu_type);
159
160 return 0;
161#else
162 return -1;
163#endif
164}
165
166void oprofile_arch_exit(void)
167{
168}
diff --git a/arch/blackfin/oprofile/op_blackfin.h b/arch/blackfin/oprofile/op_blackfin.h
deleted file mode 100644
index 05dd08c9d154..000000000000
--- a/arch/blackfin/oprofile/op_blackfin.h
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * File: arch/blackfin/oprofile/op_blackfin.h
3 * Based on:
4 * Author: Anton Blanchard <anton@au.ibm.com>
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef OP_BLACKFIN_H
32#define OP_BLACKFIN_H 1
33
34#define OP_MAX_COUNTER 2
35
36#include <asm/blackfin.h>
37
38/* Per-counter configuration as set via oprofilefs. */
39struct op_counter_config {
40 unsigned long valid;
41 unsigned long enabled;
42 unsigned long event;
43 unsigned long count;
44 unsigned long kernel;
45 unsigned long user;
46 unsigned long unit_mask;
47};
48
49/* System-wide configuration as set via oprofilefs. */
50struct op_system_config {
51 unsigned long enable_kernel;
52 unsigned long enable_user;
53};
54
55/* Per-arch configuration */
56struct op_bfin533_model {
57 int (*reg_setup) (struct op_counter_config *);
58 int (*start) (struct op_counter_config *);
59 void (*stop) (void);
60 int num_counters;
61 char *name;
62};
63
64extern struct op_bfin533_model op_model_bfin533;
65
66static inline unsigned int ctr_read(void)
67{
68 unsigned int tmp;
69
70 tmp = bfin_read_PFCTL();
71 CSYNC();
72
73 return tmp;
74}
75
76static inline void ctr_write(unsigned int val)
77{
78 bfin_write_PFCTL(val);
79 CSYNC();
80}
81
82static inline void count_read(unsigned int *count)
83{
84 count[0] = bfin_read_PFCNTR0();
85 count[1] = bfin_read_PFCNTR1();
86 CSYNC();
87}
88
89static inline void count_write(unsigned int *count)
90{
91 bfin_write_PFCNTR0(count[0]);
92 bfin_write_PFCNTR1(count[1]);
93 CSYNC();
94}
95
96extern int pm_overflow_handler(int irq, struct pt_regs *regs);
97
98#endif
diff --git a/arch/blackfin/oprofile/op_model_bf533.c b/arch/blackfin/oprofile/op_model_bf533.c
deleted file mode 100644
index d1c698bb9ee5..000000000000
--- a/arch/blackfin/oprofile/op_model_bf533.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * File: arch/blackfin/oprofile/op_model_bf533.c
3 * Based on:
4 * Author: Anton Blanchard <anton@au.ibm.com>
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#include <linux/oprofile.h>
32#include <linux/init.h>
33#include <linux/smp.h>
34#include <linux/interrupt.h>
35#include <linux/ptrace.h>
36#include <linux/irq.h>
37#include <linux/io.h>
38#include <asm/system.h>
39#include <asm/processor.h>
40#include <asm/blackfin.h>
41
42#include "op_blackfin.h"
43
44#define PM_ENABLE 0x01;
45#define PM_CTL1_ENABLE 0x18
46#define PM_CTL0_ENABLE 0xC000
47#define COUNT_EDGE_ONLY 0x3000000
48
49static int oprofile_running;
50
51static unsigned curr_pfctl, curr_count[2];
52
53static int bfin533_reg_setup(struct op_counter_config *ctr)
54{
55 unsigned int pfctl = ctr_read();
56 unsigned int count[2];
57
58 /* set Blackfin perf monitor regs with ctr */
59 if (ctr[0].enabled) {
60 pfctl |= (PM_CTL0_ENABLE | ((char)ctr[0].event << 5));
61 count[0] = 0xFFFFFFFF - ctr[0].count;
62 curr_count[0] = count[0];
63 }
64 if (ctr[1].enabled) {
65 pfctl |= (PM_CTL1_ENABLE | ((char)ctr[1].event << 16));
66 count[1] = 0xFFFFFFFF - ctr[1].count;
67 curr_count[1] = count[1];
68 }
69
70 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);
71 pfctl |= COUNT_EDGE_ONLY;
72 curr_pfctl = pfctl;
73
74 pr_debug("write 0x%x to pfctl\n", pfctl);
75 ctr_write(pfctl);
76 count_write(count);
77
78 return 0;
79}
80
81static int bfin533_start(struct op_counter_config *ctr)
82{
83 unsigned int pfctl = ctr_read();
84
85 pfctl |= PM_ENABLE;
86 curr_pfctl = pfctl;
87
88 ctr_write(pfctl);
89
90 oprofile_running = 1;
91 pr_debug("start oprofile counter \n");
92
93 return 0;
94}
95
96static void bfin533_stop(void)
97{
98 int pfctl;
99
100 pfctl = ctr_read();
101 pfctl &= ~PM_ENABLE;
102 /* freeze counters */
103 ctr_write(pfctl);
104
105 oprofile_running = 0;
106 pr_debug("stop oprofile counter \n");
107}
108
109static int get_kernel(void)
110{
111 int ipend, is_kernel;
112
113 ipend = bfin_read_IPEND();
114
115 /* test bit 15 */
116 is_kernel = ((ipend & 0x8000) != 0);
117
118 return is_kernel;
119}
120
121int pm_overflow_handler(int irq, struct pt_regs *regs)
122{
123 int is_kernel;
124 int i, cpu;
125 unsigned int pc, pfctl;
126 unsigned int count[2];
127
128 pr_debug("get interrupt in %s\n", __func__);
129 if (oprofile_running == 0) {
130 pr_debug("error: entering interrupt when oprofile is stopped.\n\r");
131 return -1;
132 }
133
134 is_kernel = get_kernel();
135 cpu = smp_processor_id();
136 pc = regs->pc;
137 pfctl = ctr_read();
138
139 /* read the two event counter regs */
140 count_read(count);
141
142 /* if the counter overflows, add sample to oprofile buffer */
143 for (i = 0; i < 2; ++i) {
144 if (oprofile_running) {
145 oprofile_add_sample(regs, i);
146 }
147 }
148
149 /* reset the perfmon counter */
150 ctr_write(curr_pfctl);
151 count_write(curr_count);
152 return 0;
153}
154
155struct op_bfin533_model op_model_bfin533 = {
156 .reg_setup = bfin533_reg_setup,
157 .start = bfin533_start,
158 .stop = bfin533_stop,
159 .num_counters = 2,
160 .name = "blackfin/bf533"
161};
diff --git a/arch/blackfin/oprofile/timer_int.c b/arch/blackfin/oprofile/timer_int.c
deleted file mode 100644
index 6c6f8606af4c..000000000000
--- a/arch/blackfin/oprofile/timer_int.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * File: arch/blackfin/oprofile/timer_int.c
3 * Based on:
4 * Author: Michael Kang
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/init.h>
31#include <linux/smp.h>
32#include <linux/irq.h>
33#include <linux/oprofile.h>
34#include <linux/ptrace.h>
35
36static void enable_sys_timer0()
37{
38}
39static void disable_sys_timer0()
40{
41}
42
43static irqreturn_t sys_timer0_int_handler(int irq, void *dev_id,
44 struct pt_regs *regs)
45{
46 oprofile_add_sample(regs, 0);
47 return IRQ_HANDLED;
48}
49
50static int sys_timer0_start(void)
51{
52 enable_sys_timer0();
53 return request_irq(IVG11, sys_timer0_int_handler, 0, "sys_timer0", NULL);
54}
55
56static void sys_timer0_stop(void)
57{
58 disable_sys_timer();
59}
60
61int __init sys_timer0_init(struct oprofile_operations *ops)
62{
63 extern int nmi_active;
64
65 if (nmi_active <= 0)
66 return -ENODEV;
67
68 ops->start = timer_start;
69 ops->stop = timer_stop;
70 ops->cpu_type = "timer";
71 printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
72 return 0;
73}