Commit | Line | Data |
---|---|---|
6fa3eb70 S |
1 | #include <linux/proc_fs.h> |
2 | #include <linux/device.h> | |
3 | #include <linux/platform_device.h> | |
4 | #include <linux/miscdevice.h> | |
5 | #include <linux/module.h> | |
6 | #include <linux/ioctl.h> | |
7 | #include <linux/uaccess.h> | |
8 | #include <linux/ftrace_event.h> | |
9 | #include "mach/mt_mon.h" | |
10 | ||
11 | #define MODULE_NAME "monitor" | |
12 | ||
13 | static struct mtk_monitor *mtk_mon; | |
14 | ||
15 | #include <linux/proc_fs.h> | |
16 | ||
17 | #define DEV_IOCTLID 0xD0 | |
18 | ||
19 | #define IOCTL_WRITE_PMU _IOW(DEV_IOCTLID, 1, struct pmu_cfg) | |
20 | #define IOCTL_READ_PMU _IOR(DEV_IOCTLID, 2, struct pmu_cfg) | |
21 | ||
22 | #ifdef CONFIG_CACHE_L2X0 | |
23 | #define IOCTL_WRITE_L2C _IOW(DEV_IOCTLID, 3, struct l2c_cfg) | |
24 | #define IOCTL_READ_L2C _IOR(DEV_IOCTLID, 4, struct l2c_cfg) | |
25 | #endif | |
26 | ||
27 | #define IOCTL_WRITE_BM _IOR(DEV_IOCTLID, 5, int) | |
28 | #define IOCTL_CTRL _IOW(DEV_IOCTLID, 6, int) | |
29 | #define IOCTL_PRINTLOG _IOR(DEV_IOCTLID, 7, struct mt_mon_log) | |
30 | ||
31 | ||
32 | #define MONITOR_START 1 | |
33 | #define MONITOR_STOP 2 | |
34 | ||
35 | static int | |
36 | mpu_dev_open(struct inode *inode, struct file *filp) | |
37 | { | |
38 | int ret; | |
39 | ||
40 | ret = register_monitor(&mtk_mon, MODE_MANUAL_USER); | |
41 | ||
42 | if(ret != 0) { | |
43 | printk("MTK Monitor Register Fail\n"); | |
44 | return -1; | |
45 | } | |
46 | ||
47 | mtk_mon->init(); | |
48 | ||
49 | return 0; | |
50 | } | |
51 | ||
52 | static int | |
53 | mpu_dev_release(struct inode *inode, struct file *filp) | |
54 | { | |
55 | mtk_mon->deinit(); | |
56 | unregister_monitor(&mtk_mon); | |
57 | return 0; | |
58 | } | |
59 | ||
60 | static long mpu_dev_ioctl(struct file *filp, | |
61 | unsigned int cmd, unsigned long arg) | |
62 | { | |
63 | u32 index, ret; | |
64 | struct pmu_cfg p_cfg; | |
65 | #ifdef CONFIG_CACHE_L2X0 | |
66 | struct l2c_cfg l_cfg; | |
67 | #endif | |
68 | ||
69 | if(mtk_mon == NULL) { | |
70 | printk("Don't Have PMU Resource\n"); | |
71 | return -1; | |
72 | } | |
73 | ||
74 | switch (cmd) { | |
75 | case IOCTL_WRITE_PMU: | |
76 | ret = copy_from_user((void * )&p_cfg, (const void *)arg, sizeof(struct pmu_cfg)); | |
77 | if(ret != 0) { | |
78 | printk("ERROR: wrong return value [IOCTL_WRITE_PMU]\n"); | |
79 | return -1; | |
80 | } | |
81 | mtk_mon->set_pmu(&p_cfg); | |
82 | break; | |
83 | ||
84 | case IOCTL_READ_PMU: | |
85 | mtk_mon->get_pmu(&p_cfg); | |
86 | ret = copy_to_user((void *)arg, (const void * )&p_cfg, sizeof(struct pmu_cfg)); | |
87 | if(ret != 0) { | |
88 | printk("ERROR: wrong return value [IOCTL_READ_PMU]\n"); | |
89 | return -1; | |
90 | } | |
91 | break; | |
92 | #ifdef CONFIG_CACHE_L2X0 | |
93 | case IOCTL_WRITE_L2C: | |
94 | ret = copy_from_user((void * )&l_cfg, (const void *)arg, sizeof(struct l2c_cfg)); | |
95 | if(ret != 0) { | |
96 | printk("ERROR: wrong return value [IOCTL_WRITE_L2C]\n"); | |
97 | return -1; | |
98 | } | |
99 | mtk_mon->set_l2c(&l_cfg); | |
100 | break; | |
101 | ||
102 | case IOCTL_READ_L2C: | |
103 | mtk_mon->get_l2c(&l_cfg); | |
104 | ret = copy_to_user((void *)arg, (const void * )&l_cfg, sizeof(struct l2c_cfg)); | |
105 | if(ret != 0) { | |
106 | printk("ERROR: wrong return value [IOCTL_READ_L2C]\n"); | |
107 | return -1; | |
108 | } | |
109 | break; | |
110 | #endif | |
111 | case IOCTL_WRITE_BM: | |
112 | mtk_mon->set_bm_rw(arg); | |
113 | break; | |
114 | ||
115 | case IOCTL_CTRL: | |
116 | switch (arg) { | |
117 | case MONITOR_START: | |
118 | mtk_mon->enable(); | |
119 | break; | |
120 | case MONITOR_STOP: | |
121 | mtk_mon->disable(); | |
122 | break; | |
123 | default: | |
124 | printk("Error Number: Start(1), Stop(2)!!!\n"); | |
125 | break; | |
126 | } | |
127 | break; | |
128 | ||
129 | case IOCTL_PRINTLOG: | |
130 | index = mtk_mon->mon_log(NULL); | |
131 | ret = copy_to_user((void *)arg, (const void * )&mtk_mon->log_buff[index], sizeof(struct mt_mon_log)); | |
132 | if(ret != 0) { | |
133 | printk("ERROR: wrong return value [IOCTL_PRINTLOG]\n"); | |
134 | return -1; | |
135 | } | |
136 | break; | |
137 | ||
138 | default: | |
139 | return -1; | |
140 | } | |
141 | return 0; | |
142 | } | |
143 | ||
144 | ||
145 | ||
146 | static struct file_operations dev_fops = { | |
147 | .owner = THIS_MODULE, | |
148 | .open = mpu_dev_open, | |
149 | .release = mpu_dev_release, | |
150 | .unlocked_ioctl = mpu_dev_ioctl, | |
151 | }; | |
152 | ||
153 | static struct miscdevice mpu_miscdev = { | |
154 | .minor = MISC_DYNAMIC_MINOR, | |
155 | .name = "mtk_monitor", | |
156 | .fops = &dev_fops, | |
157 | }; | |
158 | ||
159 | ||
160 | static int __init mon_user_init(void) | |
161 | { | |
162 | int ret; | |
163 | ||
164 | ret = misc_register(&mpu_miscdev); | |
165 | ||
166 | if(ret < 0) { | |
167 | printk("PMU MISC Register fail\n"); | |
168 | return ret; | |
169 | } | |
170 | ||
171 | /* everything OK */ | |
172 | printk(KERN_INFO "%s initialised\n", MODULE_NAME); | |
173 | return 0; | |
174 | ||
175 | } | |
176 | static void __exit mon_user_exit(void) | |
177 | { | |
178 | misc_deregister(&mpu_miscdev); | |
179 | printk(KERN_INFO "%s removed\n", MODULE_NAME); | |
180 | } | |
181 | ||
182 | module_init(mon_user_init); | |
183 | module_exit(mon_user_exit); | |
184 |