import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / thermal / mtk_cooler_shutdown.c
CommitLineData
6fa3eb70
S
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
38extern struct proc_dir_entry * mtk_thermal_get_proc_drv_therm_dir_entry(void);
39
40typedef struct _sd_state {
41 unsigned long state;
42 int sd_cnt;
43} sd_state;
44
45static 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 };
47static sd_state cl_sd_state[MAX_NUM_INSTANCE_MTK_COOLER_SHUTDOWN];
48
49#if defined(MTK_COOLER_SHUTDOWN_SIGNAL)
50
51static unsigned int tm_pid;
52static unsigned int tm_input_pid;
53static unsigned int mtk_cl_sd_rst;
54static struct task_struct g_task;
55static struct task_struct *pg_task = &g_task;
56
57static int sd_debouncet = 1;
58//static int sd_cnt = 0;
59static int sd_happened = 0;
60
61static 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
4b9e9796 67 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
6fa3eb70
S
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
93int _mtk_cl_sd_rst_read(struct seq_file *m, void *v)
94{
95 return 0;
96}
97
98static 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
107static 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
116static 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
4b9e9796 122 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
6fa3eb70
S
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
137static 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
145static 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
154static 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
163static 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
4b9e9796 168 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
6fa3eb70
S
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
189static 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
197static 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
206static 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
215static 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
248static 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
255static 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
265static 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 */
318static 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
324static 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
341static 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
357static 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
430err_unreg:
431 mtk_cooler_shutdown_unregister_ltf();
432 return err;
433}
434
435static void __exit mtk_cooler_shutdown_exit(void)
436{
437 mtk_cooler_shutdown_dprintk("exit\n");
438 mtk_cooler_shutdown_unregister_ltf();
439}
440module_init(mtk_cooler_shutdown_init);
441module_exit(mtk_cooler_shutdown_exit);