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 <asm/semaphore.h>
14 #include <linux/sysdev.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 static int pmu_start(void);
24 static int pmu_setup(void);
25 static void pmu_stop(void);
26 static int pmu_create_files(struct super_block
*, struct dentry
*);
29 static int pmu_suspend(struct sys_device
*dev
, pm_message_t state
)
36 static int pmu_resume(struct sys_device
*dev
)
43 static struct sysdev_class oprofile_sysclass
= {
44 set_kset_name("oprofile"),
46 .suspend
= pmu_suspend
,
49 static struct sys_device device_oprofile
= {
51 .cls
= &oprofile_sysclass
,
54 static int __init
init_driverfs(void)
58 if (!(ret
= sysdev_class_register(&oprofile_sysclass
)))
59 ret
= sysdev_register(&device_oprofile
);
64 static void exit_driverfs(void)
66 sysdev_unregister(&device_oprofile
);
67 sysdev_class_unregister(&oprofile_sysclass
);
70 #define init_driverfs() do { } while (0)
71 #define exit_driverfs() do { } while (0)
72 #endif /* CONFIG_PM */
74 struct op_counter_config counter_config
[OP_MAX_COUNTER
];
76 static int pmu_create_files(struct super_block
*sb
, struct dentry
*root
)
80 for (i
= 0; i
< pmu_model
->num_counters
; i
++) {
84 snprintf(buf
, sizeof buf
, "%d", i
);
85 dir
= oprofilefs_mkdir(sb
, root
, buf
);
86 oprofilefs_create_ulong(sb
, dir
, "enabled", &counter_config
[i
].enabled
);
87 oprofilefs_create_ulong(sb
, dir
, "event", &counter_config
[i
].event
);
88 oprofilefs_create_ulong(sb
, dir
, "count", &counter_config
[i
].count
);
89 oprofilefs_create_ulong(sb
, dir
, "unit_mask", &counter_config
[i
].unit_mask
);
90 oprofilefs_create_ulong(sb
, dir
, "kernel", &counter_config
[i
].kernel
);
91 oprofilefs_create_ulong(sb
, dir
, "user", &counter_config
[i
].user
);
97 static int pmu_setup(void)
101 spin_lock(&oprofilefs_lock
);
102 ret
= pmu_model
->setup_ctrs();
103 spin_unlock(&oprofilefs_lock
);
107 static int pmu_start(void)
113 ret
= pmu_model
->start();
120 static void pmu_stop(void)
129 int __init
pmu_init(struct oprofile_operations
*ops
, struct op_arm_model_spec
*spec
)
131 init_MUTEX(&pmu_sem
);
133 if (spec
->init() < 0)
138 ops
->create_files
= pmu_create_files
;
139 ops
->setup
= pmu_setup
;
140 ops
->shutdown
= pmu_stop
;
141 ops
->start
= pmu_start
;
142 ops
->stop
= pmu_stop
;
143 ops
->cpu_type
= pmu_model
->name
;
144 printk(KERN_INFO
"oprofile: using %s PMU\n", spec
->name
);