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
*pmu_model
;
20 static int pmu_enabled
;
21 static struct semaphore pmu_sem
;
23 struct op_counter_config counter_config
[OP_MAX_COUNTER
];
25 static int pmu_create_files(struct super_block
*sb
, struct dentry
*root
)
29 for (i
= 0; i
< pmu_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 pmu_setup(void)
50 spin_lock(&oprofilefs_lock
);
51 ret
= pmu_model
->setup_ctrs();
52 spin_unlock(&oprofilefs_lock
);
56 static int pmu_start(void)
62 ret
= pmu_model
->start();
69 static void pmu_stop(void)
79 static int pmu_suspend(struct sys_device
*dev
, pm_message_t state
)
88 static int pmu_resume(struct sys_device
*dev
)
91 if (pmu_enabled
&& pmu_model
->start())
97 static struct sysdev_class oprofile_sysclass
= {
98 set_kset_name("oprofile"),
100 .suspend
= pmu_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
pmu_init(struct oprofile_operations
*ops
, struct op_arm_model_spec
*spec
)
130 init_MUTEX(&pmu_sem
);
132 if (spec
->init() < 0)
137 ops
->create_files
= pmu_create_files
;
138 ops
->setup
= pmu_setup
;
139 ops
->shutdown
= pmu_stop
;
140 ops
->start
= pmu_start
;
141 ops
->stop
= pmu_stop
;
142 ops
->cpu_type
= pmu_model
->name
;
143 printk(KERN_INFO
"oprofile: using %s PMU\n", spec
->name
);