4 * @remark Copyright 2004 Oprofile Authors
5 * @remark Read the file COPYING
7 * @author Zwane Mwaikambo
10 #include <linux/init.h>
11 #include <linux/oprofile.h>
12 #include <linux/errno.h>
13 #include <linux/sysdev.h>
14 #include <asm/semaphore.h>
16 #include "op_counter.h"
17 #include "op_arm_model.h"
19 static struct op_arm_model_spec
*op_arm_model
;
20 static int op_arm_enabled
;
21 static struct semaphore op_arm_sem
;
23 struct op_counter_config counter_config
[OP_MAX_COUNTER
];
25 static int op_arm_create_files(struct super_block
*sb
, struct dentry
*root
)
29 for (i
= 0; i
< op_arm_model
->num_counters
; i
++) {
33 snprintf(buf
, sizeof buf
, "%d", i
);
34 dir
= oprofilefs_mkdir(sb
, root
, buf
);
35 oprofilefs_create_ulong(sb
, dir
, "enabled", &counter_config
[i
].enabled
);
36 oprofilefs_create_ulong(sb
, dir
, "event", &counter_config
[i
].event
);
37 oprofilefs_create_ulong(sb
, dir
, "count", &counter_config
[i
].count
);
38 oprofilefs_create_ulong(sb
, dir
, "unit_mask", &counter_config
[i
].unit_mask
);
39 oprofilefs_create_ulong(sb
, dir
, "kernel", &counter_config
[i
].kernel
);
40 oprofilefs_create_ulong(sb
, dir
, "user", &counter_config
[i
].user
);
46 static int op_arm_setup(void)
50 spin_lock(&oprofilefs_lock
);
51 ret
= op_arm_model
->setup_ctrs();
52 spin_unlock(&oprofilefs_lock
);
56 static int op_arm_start(void)
61 if (!op_arm_enabled
) {
62 ret
= op_arm_model
->start();
63 op_arm_enabled
= !ret
;
69 static void op_arm_stop(void)
79 static int op_arm_suspend(struct sys_device
*dev
, pm_message_t state
)
88 static int op_arm_resume(struct sys_device
*dev
)
91 if (op_arm_enabled
&& op_arm_model
->start())
97 static struct sysdev_class oprofile_sysclass
= {
98 set_kset_name("oprofile"),
99 .resume
= op_arm_resume
,
100 .suspend
= op_arm_suspend
,
103 static struct sys_device device_oprofile
= {
105 .cls
= &oprofile_sysclass
,
108 static int __init
init_driverfs(void)
112 if (!(ret
= sysdev_class_register(&oprofile_sysclass
)))
113 ret
= sysdev_register(&device_oprofile
);
118 static void exit_driverfs(void)
120 sysdev_unregister(&device_oprofile
);
121 sysdev_class_unregister(&oprofile_sysclass
);
124 #define init_driverfs() do { } while (0)
125 #define exit_driverfs() do { } while (0)
126 #endif /* CONFIG_PM */
128 int __init
oprofile_arch_init(struct oprofile_operations
*ops
)
130 struct op_arm_model_spec
*spec
= NULL
;
133 #ifdef CONFIG_CPU_XSCALE
134 spec
= &op_xscale_spec
;
138 init_MUTEX(&op_arm_sem
);
146 ops
->create_files
= op_arm_create_files
;
147 ops
->setup
= op_arm_setup
;
148 ops
->shutdown
= op_arm_stop
;
149 ops
->start
= op_arm_start
;
150 ops
->stop
= op_arm_stop
;
151 ops
->cpu_type
= op_arm_model
->name
;
152 ops
->backtrace
= arm_backtrace
;
153 printk(KERN_INFO
"oprofile: using %s\n", spec
->name
);
159 void oprofile_arch_exit(void)