import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / thermal / mtk_cooler_shutdown.c
1 #ifdef pr_fmt
2 #undef pr_fmt
3 #endif
4 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5
6 #include <linux/version.h>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/printk.h>
10 #include <linux/types.h>
11 #include <linux/kobject.h>
12 #include "mach/mtk_thermal_monitor.h"
13
14 #define MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN 3
15
16 /* #define MTK_COOLER_SHUTDOWN_UEVENT */
17 #define MTK_COOLER_SHUTDOWN_SIGNAL
18
19 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
20 #include <linux/version.h>
21 #include <linux/proc_fs.h>
22 #include <linux/seq_file.h>
23 #include <asm/uaccess.h>
24 #include <linux/pid.h>
25 #include <linux/signal.h>
26 #include <linux/sched.h>
27
28 #define MAX_LEN 256
29 #endif
30
31 #if 1
32 #define mtk_cooler_shutdown_dprintk(fmt, args...) \
33 do { pr_debug("thermal/cooler/shutdown " fmt, ##args); } while (0)
34 #else
35 #define mtk_cooler_shutdown_dprintk(fmt, args...)
36 #endif
37
38 extern struct proc_dir_entry * mtk_thermal_get_proc_drv_therm_dir_entry(void);
39
40 typedef struct _sd_state {
41 unsigned long state;
42 int sd_cnt;
43 } sd_state;
44
45 static struct thermal_cooling_device *cl_shutdown_dev[MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN] = { 0 };
46 //static unsigned long cl_shutdown_state[MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN] = { 0 };
47 static sd_state cl_sd_state[MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN];
48
49 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
50
51 static unsigned int tm_pid;
52 static unsigned int tm_input_pid;
53 static unsigned int mtk_cl_sd_rst;
54 static struct task_struct g_task;
55 static struct task_struct *pg_task = &g_task;
56
57 static int sd_debouncet = 1;
58 //static int sd_cnt = 0;
59 static int sd_happened = 0;
60
61 static ssize_t _mtk_cl_sd_rst_write(struct file *filp, const char __user *buf, size_t len,
62 loff_t *data)
63 {
64 int ret = 0;
65 char tmp[MAX_LEN] = { 0 };
66
67 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
68 /* write data to the buffer */
69 if (copy_from_user(tmp, buf, len)) {
70 return -EFAULT;
71 }
72
73 ret = kstrtouint(tmp, 10, &mtk_cl_sd_rst);
74 if (ret)
75 WARN_ON(1);
76
77
78 if (1 == mtk_cl_sd_rst) {
79 int i;
80 for (i = MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN; i-- > 0;) {
81 cl_sd_state[i].state = 0;
82 cl_sd_state[i].sd_cnt = 0;
83 }
84 mtk_cl_sd_rst = 0;
85 sd_happened = 0;
86 //sd_cnt = 0;
87 }
88 mtk_cooler_shutdown_dprintk("%s %s = %d\n", __func__, tmp, mtk_cl_sd_rst);
89
90 return len;
91 }
92
93 int _mtk_cl_sd_rst_read(struct seq_file *m, void *v)
94 {
95 return 0;
96 }
97
98 static int _mtk_cl_sd_rst_open(struct inode *inode, struct file *file)
99 {
100 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
101 return single_open(file, _mtk_cl_sd_rst_read, PDE_DATA(inode));
102 #else
103 return single_open(file, _mtk_cl_sd_rst_read, PDE(inode)->data);
104 #endif
105 }
106
107 static const struct file_operations _cl_sd_rst_fops = {
108 .owner = THIS_MODULE,
109 .open = _mtk_cl_sd_rst_open,
110 .read = seq_read,
111 .llseek = seq_lseek,
112 .write = _mtk_cl_sd_rst_write,
113 .release = single_release,
114 };
115
116 static ssize_t _mtk_cl_sd_pid_write(struct file *filp, const char __user *buf, size_t len,
117 loff_t *data)
118 {
119 int ret = 0;
120 char tmp[MAX_LEN] = { 0 };
121
122 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
123 /* write data to the buffer */
124 if (copy_from_user(tmp, buf, len)) {
125 return -EFAULT;
126 }
127
128 ret = kstrtouint(tmp, 10, &tm_input_pid);
129 if (ret)
130 WARN_ON(1);
131
132 mtk_cooler_shutdown_dprintk("%s %s = %d\n", __func__, tmp, tm_input_pid);
133
134 return len;
135 }
136
137 static int _mtk_cl_sd_pid_read(struct seq_file *m, void *v)
138 {
139 seq_printf(m, "%d\n", tm_input_pid);
140 mtk_cooler_shutdown_dprintk("%s %d\n", __func__, tm_input_pid);
141
142 return 0;
143 }
144
145 static int _mtk_cl_sd_pid_open(struct inode *inode, struct file *file)
146 {
147 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
148 return single_open(file, _mtk_cl_sd_pid_read, PDE_DATA(inode));
149 #else
150 return single_open(file, _mtk_cl_sd_pid_read, PDE(inode)->data);
151 #endif
152 }
153
154 static const struct file_operations _cl_sd_pid_fops = {
155 .owner = THIS_MODULE,
156 .open = _mtk_cl_sd_pid_open,
157 .read = seq_read,
158 .llseek = seq_lseek,
159 .write = _mtk_cl_sd_pid_write,
160 .release = single_release,
161 };
162
163 static ssize_t _mtk_cl_sd_debouncet_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
164 {
165 char desc[MAX_LEN] = {0};
166 int tmp_dbt = -1;
167
168 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
169 /* write data to the buffer */
170 if (copy_from_user(desc, buf, len)) {
171 return -EFAULT;
172 }
173
174 if(sscanf(desc, "%d", &tmp_dbt) == 1)
175 {
176 if (tmp_dbt >= 0 && tmp_dbt <= 5)
177 sd_debouncet = tmp_dbt;
178 else
179 mtk_cooler_shutdown_dprintk("[%s] oo range %s = %d\n", __func__, desc, sd_debouncet);
180 }
181 else
182 mtk_cooler_shutdown_dprintk("[%s] bad arg %s = %d\n", __func__, desc, sd_debouncet);
183
184 mtk_cooler_shutdown_dprintk("[%s] %s = %d\n", __func__, desc, sd_debouncet);
185
186 return len;
187 }
188
189 static int _mtk_cl_sd_debouncet_read(struct seq_file *m, void *v)
190 {
191 seq_printf(m, "%d\n", sd_debouncet);
192 mtk_cooler_shutdown_dprintk("[%s] %d\n", __func__, sd_debouncet);
193
194 return 0;
195 }
196
197 static int _mtk_cl_sd_debouncet_open(struct inode *inode, struct file *file)
198 {
199 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
200 return single_open(file, _mtk_cl_sd_debouncet_read, PDE_DATA(inode));
201 #else
202 return single_open(file, _mtk_cl_sd_debouncet_read, PDE(inode)->data);
203 #endif
204 }
205
206 static const struct file_operations _cl_sd_debouncet_fops = {
207 .owner = THIS_MODULE,
208 .open = _mtk_cl_sd_debouncet_open,
209 .read = seq_read,
210 .llseek = seq_lseek,
211 .write = _mtk_cl_sd_debouncet_write,
212 .release = single_release,
213 };
214
215 static int _mtk_cl_sd_send_signal(void)
216 {
217 int ret = 0;
218
219 if (tm_input_pid == 0) {
220 mtk_cooler_shutdown_dprintk("%s pid is empty\n", __func__);
221 ret = -1;
222 }
223
224 mtk_cooler_shutdown_dprintk("%s pid is %d, %d\n", __func__, tm_pid, tm_input_pid);
225
226 if (ret == 0 && tm_input_pid != tm_pid) {
227 tm_pid = tm_input_pid;
228 pg_task = get_pid_task(find_vpid(tm_pid), PIDTYPE_PID);
229 }
230
231 if (ret == 0 && pg_task) {
232 siginfo_t info;
233 info.si_signo = SIGIO;
234 info.si_errno = 0;
235 info.si_code = 1;
236 info.si_addr = NULL;
237 ret = send_sig_info(SIGIO, &info, pg_task);
238 }
239
240 if (ret != 0)
241 mtk_cooler_shutdown_dprintk("%s ret=%d\n", __func__, ret);
242
243 return ret;
244 }
245
246 #endif
247
248 static int mtk_cl_shutdown_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
249 {
250 *state = 1;
251 /* mtk_cooler_shutdown_dprintk("mtk_cl_shutdown_get_max_state() %s %d\n", cdev->type, *state); */
252 return 0;
253 }
254
255 static int mtk_cl_shutdown_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
256 {
257 //*state = *((unsigned long *)cdev->devdata);
258 sd_state *cl_state = (sd_state *) cdev->devdata;
259 if (state)
260 *state = cl_state->state;
261 /* mtk_cooler_shutdown_dprintk("mtk_cl_shutdown_get_cur_state() %s %d\n", cdev->type, *state); */
262 return 0;
263 }
264
265 static int mtk_cl_shutdown_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
266 {
267 sd_state *cl_state = (sd_state *) cdev->devdata;
268 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
269 volatile unsigned long original_state;
270 #endif
271 /* mtk_cooler_shutdown_dprintk("mtk_cl_shutdown_set_cur_state() %s %d\n", cdev->type, state); */
272 if (!cl_state)
273 return -1;
274
275 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
276 original_state = cl_state->state;
277 #endif
278
279 cl_state->state = state;
280
281 if (0 == state)
282 {
283 if (cl_state->sd_cnt > 0)
284 cl_state->sd_cnt--;
285 else
286 ;
287 }
288 else if (1 == state)
289 {
290 cl_state->sd_cnt++;
291 }
292
293 if (sd_debouncet == cl_state->sd_cnt) {
294 #if defined(MTK_COOLER_SHUTDOWN_UEVENT)
295 {
296 /* send uevent to notify current call must be dropped */
297 char event[] = "SHUTDOWN=1";
298 char *envp[] = { event, NULL };
299
300 kobject_uevent_env(&(cdev->device.kobj), KOBJ_CHANGE, envp);
301 }
302 #endif
303
304 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
305 if (0 == sd_happened) /* make this an edge trigger instead of level trigger */
306 {
307 /* send signal to target process */
308 _mtk_cl_sd_send_signal();
309 sd_happened = 1;
310 }
311 #endif
312 }
313
314 return 0;
315 }
316
317 /* bind fan callbacks to fan device */
318 static struct thermal_cooling_device_ops mtk_cl_shutdown_ops = {
319 .get_max_state = mtk_cl_shutdown_get_max_state,
320 .get_cur_state = mtk_cl_shutdown_get_cur_state,
321 .set_cur_state = mtk_cl_shutdown_set_cur_state,
322 };
323
324 static int mtk_cooler_shutdown_register_ltf(void)
325 {
326 int i;
327 mtk_cooler_shutdown_dprintk("register ltf\n");
328
329 for (i = MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN; i-- > 0;) {
330 char temp[20] = { 0 };
331 sprintf(temp, "mtk-cl-shutdown%02d", i);
332 cl_shutdown_dev[i] = mtk_thermal_cooling_device_register(temp,
333 (void *)
334 &cl_sd_state[i],
335 &mtk_cl_shutdown_ops);
336 }
337
338 return 0;
339 }
340
341 static void mtk_cooler_shutdown_unregister_ltf(void)
342 {
343 int i;
344 mtk_cooler_shutdown_dprintk("unregister ltf\n");
345
346 for (i = MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN; i-- > 0;) {
347 if (cl_shutdown_dev[i]) {
348 mtk_thermal_cooling_device_unregister(cl_shutdown_dev[i]);
349 cl_shutdown_dev[i] = NULL;
350 cl_sd_state[i].state = 0;
351 cl_sd_state[i].sd_cnt = 0;
352 }
353 }
354 }
355
356
357 static int __init mtk_cooler_shutdown_init(void)
358 {
359 int err = 0;
360 int i;
361
362 for (i = MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN; i-- > 0;) {
363 cl_shutdown_dev[i] = NULL;
364 cl_sd_state[i].state = 0;
365 cl_sd_state[i].sd_cnt = 0;
366 }
367
368 mtk_cooler_shutdown_dprintk("init\n");
369
370 #if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
371 {
372 struct proc_dir_entry *entry = NULL;
373 struct proc_dir_entry *dir_entry = mtk_thermal_get_proc_drv_therm_dir_entry();
374
375 if (!dir_entry) {
376 mtk_cooler_shutdown_dprintk("%s mkdir /proc/driver/thermal failed\n", __func__);
377 return 0;
378 }
379
380 entry =
381 proc_create("clsd_pid", S_IRUGO | S_IWUSR | S_IWGRP, dir_entry,
382 &_cl_sd_pid_fops);
383 if (!entry) {
384 mtk_cooler_shutdown_dprintk("%s clsd_pid creation failed\n",
385 __func__);
386 } else {
387 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
388 proc_set_user(entry, 0, 1000);
389 #else
390 entry->gid = 1000;
391 #endif
392 }
393
394 entry =
395 proc_create("clsd_rst", S_IRUGO | S_IWUSR | S_IWGRP, dir_entry,
396 &_cl_sd_rst_fops);
397 if (!entry) {
398 mtk_cooler_shutdown_dprintk("%s clsd_rst creation failed\n",
399 __func__);
400 } else {
401 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
402 proc_set_user(entry, 0, 1000);
403 #else
404 entry->gid = 1000;
405 #endif
406 }
407
408 entry =
409 proc_create("clsd_dbt", S_IRUGO | S_IWUSR | S_IWGRP, dir_entry,
410 &_cl_sd_debouncet_fops);
411 if (!entry) {
412 mtk_cooler_shutdown_dprintk("%s clsd_dbt creation failed\n",
413 __func__);
414 } else {
415 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
416 proc_set_user(entry, 0, 1000);
417 #else
418 entry->gid = 1000;
419 #endif
420 }
421 }
422 #endif
423
424 err = mtk_cooler_shutdown_register_ltf();
425 if (err)
426 goto err_unreg;
427
428 return 0;
429
430 err_unreg:
431 mtk_cooler_shutdown_unregister_ltf();
432 return err;
433 }
434
435 static void __exit mtk_cooler_shutdown_exit(void)
436 {
437 mtk_cooler_shutdown_dprintk("exit\n");
438 mtk_cooler_shutdown_unregister_ltf();
439 }
440 module_init(mtk_cooler_shutdown_init);
441 module_exit(mtk_cooler_shutdown_exit);