Blackfin arch: rewrite get_sclk()/get_vco()
[linux-2.6/mini2440.git] / arch / blackfin / oprofile / common.c
blobcf8f48848d1b11f273839e421f50cd92787d1d00
1 /*
2 * File: arch/blackfin/oprofile/common.c
3 * Based on: arch/alpha/oprofile/common.c
4 * Author: Anton Blanchard <anton@au.ibm.com>
6 * Created:
7 * Description:
9 * Modified:
10 * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
11 * Copyright 2004-2006 Analog Devices Inc.
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
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.
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.
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
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>
40 #include <asm/system.h>
41 #include <asm/blackfin.h>
43 #include "op_blackfin.h"
45 #define BFIN_533_ID 0xE5040003
46 #define BFIN_537_ID 0xE5040002
48 static int pfmon_enabled;
49 static struct mutex pfmon_lock;
51 struct op_bfin533_model *model;
53 struct op_counter_config ctr[OP_MAX_COUNTER];
55 static int op_bfin_setup(void)
57 int ret;
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);
64 return ret;
67 static void op_bfin_shutdown(void)
69 #if 0
70 /* what is the difference between shutdown and stop? */
71 #endif
74 static int op_bfin_start(void)
76 int ret = -EBUSY;
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;
84 mutex_unlock(&pfmon_lock);
86 return ret;
89 static void op_bfin_stop(void)
91 mutex_lock(&pfmon_lock);
92 if (pfmon_enabled) {
93 model->stop();
94 pfmon_enabled = 0;
96 mutex_unlock(&pfmon_lock);
99 static int op_bfin_create_files(struct super_block *sb, struct dentry *root)
101 int i;
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");
108 snprintf(buf, sizeof buf, "%d", i);
109 dir = oprofilefs_mkdir(sb, root, buf);
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);
115 * We dont support per counter user/kernel selection, but
116 * we leave the entries because userspace expects them
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);
124 return 0;
126 int __init oprofile_arch_init(struct oprofile_operations *ops)
128 #ifdef CONFIG_HARDWARE_PM
129 mutex_init(&pfmon_lock);
132 switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) {
133 case 0xca:
134 printk(KERN_INFO "Oprofile: cpu vendor is Analog Devices.\n");
135 model = &op_model_bfin533;
136 model->num_counters = 2;
137 break;
138 default:
139 return -ENODEV;
142 ops->cpu_type = model->name;
143 ops->create_files = op_bfin_create_files;
144 ops->setup = op_bfin_setup;
145 ops->shutdown = op_bfin_shutdown;
146 ops->start = op_bfin_start;
147 ops->stop = op_bfin_stop;
149 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
150 ops->cpu_type);
152 return 0;
153 #else
154 return -1;
155 #endif
158 void oprofile_arch_exit(void)