ACPI: thinkpad-acpi: fix the module init failure path
[wrt350n-kernel.git] / arch / blackfin / oprofile / common.c
blobcb8b8d5af34fa450f1c58273d10acf71428eff2b
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", __FUNCTION__);
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 unsigned int dspid;
131 mutex_init(&pfmon_lock);
133 dspid = bfin_read_DSPID();
135 printk(KERN_INFO "Oprofile got the cpu id is 0x%x. \n", dspid);
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;
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;
157 printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
158 ops->cpu_type);
160 return 0;
161 #else
162 return -1;
163 #endif
166 void oprofile_arch_exit(void)