import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / thermal / mt8127 / mtk_ts_wmt.c
CommitLineData
6fa3eb70
S
1/*
2* Copyright (C) 2011-2014 MediaTek Inc.
3*
4* This program is free software: you can redistribute it and/or modify it under the terms of the
5* GNU General Public License version 2 as published by the Free Software Foundation.
6*
7* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9* See the GNU General Public License for more details.
10*
11* You should have received a copy of the GNU General Public License along with this program.
12* If not, see <http://www.gnu.org/licenses/>.
13*/
14
15#ifdef pr_fmt
16#undef pr_fmt
17#endif
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
20#include <linux/version.h>
21#include <linux/thermal.h>
22#include <linux/printk.h>
23#include <linux/proc_fs.h>
24#include <linux/seq_file.h>
25#include <asm/uaccess.h>
26/* #include "wmt_tm.h" */
27#include <mach/mtk_thermal_monitor.h>
28#include <linux/timer.h>
29#include <linux/pid.h>
30/* For using net dev + */
31#include <linux/netdevice.h>
32/* For using net dev - */
33#include <mach/mtk_wcn_cmb_stub.h>
34
35
36static int wmt_tm_debug_log = 0;
37#define wmt_tm_dprintk(fmt, args...) \
38do { \
39 if (wmt_tm_debug_log) { \
40 pr_debug("tz/mtktswmt " fmt, ##args); \
41 } \
42} while(0)
43
44#define wmt_tm_printk(fmt, args...) \
45do { \
46 pr_debug("tz/mtktswmt " fmt, ##args); \
47} while(0)
48
49#define wmt_tm_info(fmt, args...) \
50do { \
51 pr_debug("tz/mtktswmt " fmt, ##args); \
52} while(0)
53
54struct linux_thermal_ctrl_if {
55 int kernel_mode;
56 int interval;
57 struct thermal_zone_device *thz_dev;
58 struct thermal_cooling_device *cl_dev;
59 struct thermal_cooling_device *cl_pa1_dev;
60 struct thermal_cooling_device *cl_pa2_dev;
61 struct thermal_cooling_device *cl_pa3_dev;
62};
63
64#if 0
65struct wmt_thermal_ctrl_if {
66 struct wmt_thermal_ctrl_ops ops;
67};
68#endif
69
70typedef struct wmt_tm {
71 struct linux_thermal_ctrl_if linux_if;
72 /* struct wmt_thermal_ctrl_if wmt_if; */
73}wmt_tm_t;
74
75struct wmt_stats {
76 unsigned long pre_time;
77 unsigned long pre_tx_bytes;
78};
79
80extern struct proc_dir_entry * mtk_thermal_get_proc_drv_therm_dir_entry(void);
81
82static struct timer_list wmt_stats_timer;
83static struct wmt_stats wmt_stats_info;
84static unsigned long pre_time;
85static unsigned long tx_throughput;
86
87/*New Wifi throttling Algo+*/
88//over_up_time * polling interval > up_duration --> throttling
89static unsigned int over_up_time = 0; //polling time
90static unsigned int up_duration = 30; //sec
91static unsigned int up_denominator = 2;
92static unsigned int up_numerator = 1;
93
94//below_low_time * polling interval > low_duration --> throttling
95static unsigned int below_low_time = 0; //polling time
96static unsigned int low_duration = 10; //sec
97static unsigned int low_denominator = 2;
98static unsigned int low_numerator = 3;
99
100static unsigned int low_rst_time = 0;
101static unsigned int low_rst_max = 3;
102/*New Wifi throttling Algo-*/
103
104#define MAX_LEN 256
105#define COOLER_THRO_NUM 3
106#define COOLER_NUM 10
107#define ONE_MBITS_PER_SEC 1000
108
109static unsigned int tm_pid = 0;
110static unsigned int tm_input_pid = 0;
111static unsigned int tm_wfd_stat = 0;
112static struct task_struct g_task;
113static struct task_struct *pg_task = &g_task;
114
115/* +Cooler info+ */
116static int g_num_trip = COOLER_THRO_NUM + 1;
117static char g_bind0[20]="mtktswmt-pa1";
118static char g_bind1[20]="mtktswmt-pa2";
119static char g_bind2[20]="mtktswmt-pa3";
120static char g_bind3[20]="mtktswmt-sysrst";
121static char g_bind4[20]={0};
122static char g_bind5[20]={0};
123static char g_bind6[20]={0};
124static char g_bind7[20]={0};
125static char g_bind8[20]={0};
126static char g_bind9[20]={0};
127
128/**
129 * If curr_temp >= polling_trip_temp1, use interval
130 * else if cur_temp >= polling_trip_temp2 && curr_temp < polling_trip_temp1, use interval*polling_factor1
131 * else, use interval*polling_factor2
132 */
133static int polling_trip_temp1 = 40000;
134static int polling_trip_temp2 = 20000;
135static int polling_factor1 = 5;
136static int polling_factor2 = 10;
137
138static unsigned int cl_dev_state =0;
139static unsigned int cl_pa1_dev_state =0;
140static unsigned int cl_pa2_dev_state =0;
141/*static unsigned int cl_pa3_dev_state =0;*/
142static unsigned int g_trip_temp[COOLER_NUM] = {85000,85000,85000,85000,0,0,0,0,0,0};
143
144/*static int g_thro[COOLER_THRO_NUM] = {10 * ONE_MBITS_PER_SEC, 5 * ONE_MBITS_PER_SEC, 1 * ONE_MBITS_PER_SEC};*/
145static int g_thermal_trip[COOLER_NUM] = {0,0,0,0,0,0,0,0,0,0};
146
147/* -Cooler info- */
148
149wmt_tm_t g_wmt_tm;
150wmt_tm_t *pg_wmt_tm = &g_wmt_tm;
151
152static int wmt_thz_bind(struct thermal_zone_device *,
153 struct thermal_cooling_device *);
154static int wmt_thz_unbind(struct thermal_zone_device *,
155 struct thermal_cooling_device *);
156static int wmt_thz_get_temp(struct thermal_zone_device *,
157 unsigned long *);
158static int wmt_thz_get_mode(struct thermal_zone_device *,
159 enum thermal_device_mode *);
160static int wmt_thz_set_mode(struct thermal_zone_device *,
161 enum thermal_device_mode);
162static int wmt_thz_get_trip_type(struct thermal_zone_device *, int,
163 enum thermal_trip_type *);
164static int wmt_thz_get_trip_temp(struct thermal_zone_device *, int,
165 unsigned long *);
166static int wmt_thz_get_crit_temp(struct thermal_zone_device *,
167 unsigned long *);
168static int wmt_cl_get_max_state(struct thermal_cooling_device *,
169 unsigned long *);
170static int wmt_cl_get_cur_state(struct thermal_cooling_device *,
171 unsigned long *);
172static int wmt_cl_set_cur_state(struct thermal_cooling_device *,
173 unsigned long);
174
175static int wmt_cl_pa1_get_max_state(struct thermal_cooling_device *,
176 unsigned long *);
177static int wmt_cl_pa1_get_cur_state(struct thermal_cooling_device *,
178 unsigned long *);
179static int wmt_cl_pa1_set_cur_state(struct thermal_cooling_device *,
180 unsigned long);
181
182static int wmt_cl_pa2_get_max_state(struct thermal_cooling_device *,
183 unsigned long *);
184static int wmt_cl_pa2_get_cur_state(struct thermal_cooling_device *,
185 unsigned long *);
186static int wmt_cl_pa2_set_cur_state(struct thermal_cooling_device *,
187 unsigned long);
188
189#ifdef NEVER
190static int wmt_cl_pa3_get_max_state(struct thermal_cooling_device *,
191 unsigned long *);
192static int wmt_cl_pa3_get_cur_state(struct thermal_cooling_device *,
193 unsigned long *);
194static int wmt_cl_pa3_set_cur_state(struct thermal_cooling_device *,
195 unsigned long);
196#endif /* NEVER */
197
198static struct thermal_zone_device_ops wmt_thz_dev_ops = {
199 .bind = wmt_thz_bind,
200 .unbind = wmt_thz_unbind,
201 .get_temp = wmt_thz_get_temp,
202 .get_mode = wmt_thz_get_mode,
203 .set_mode = wmt_thz_set_mode,
204 .get_trip_type = wmt_thz_get_trip_type,
205 .get_trip_temp = wmt_thz_get_trip_temp,
206 .get_crit_temp = wmt_thz_get_crit_temp,
207};
208
209static struct thermal_cooling_device_ops mtktspa_cooling_sysrst_ops = {
210 .get_max_state = wmt_cl_get_max_state,
211 .get_cur_state = wmt_cl_get_cur_state,
212 .set_cur_state = wmt_cl_set_cur_state,
213};
214
215static struct thermal_cooling_device_ops mtktspa_cooling_pa1_ops = {
216 .get_max_state = wmt_cl_pa1_get_max_state,
217 .get_cur_state = wmt_cl_pa1_get_cur_state,
218 .set_cur_state = wmt_cl_pa1_set_cur_state,
219};
220
221static struct thermal_cooling_device_ops mtktspa_cooling_pa2_ops = {
222 .get_max_state = wmt_cl_pa2_get_max_state,
223 .get_cur_state = wmt_cl_pa2_get_cur_state,
224 .set_cur_state = wmt_cl_pa2_set_cur_state,
225};
226
227#ifdef NEVER
228static struct thermal_cooling_device_ops mtktspa_cooling_pa3_ops = {
229 .get_max_state = wmt_cl_pa3_get_max_state,
230 .get_cur_state = wmt_cl_pa3_get_cur_state,
231 .set_cur_state = wmt_cl_pa3_set_cur_state,
232};
233#endif /* NEVER */
234
235static unsigned long get_tx_bytes(void)
236{
237 struct net_device *dev;
238 struct net *net;
239 unsigned long tx_bytes = 0;
240
241 read_lock(&dev_base_lock);
242 for_each_net(net) {
243 for_each_netdev(net, dev) {
244 if(!strncmp(dev->name, "wlan", 4) || !strncmp(dev->name, "ap", 2) || !strncmp(dev->name, "p2p", 3)) {
245 struct rtnl_link_stats64 temp;
246 const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
247 tx_bytes = tx_bytes + stats->tx_bytes;
248 }
249 }
250 }
251 read_unlock(&dev_base_lock);
252 return tx_bytes;
253}
254
255static int wmt_cal_stats(unsigned long data)
256{
257 struct wmt_stats *stats_info = (struct wmt_stats*) data;
258 struct timeval cur_time;
259
260 wmt_tm_dprintk("[%s] pre_time=%lu, pre_data=%lu\n", __func__, pre_time, stats_info->pre_tx_bytes);
261
262 do_gettimeofday(&cur_time);
263
264 if (pre_time != 0 && cur_time.tv_sec > pre_time) {
265 unsigned long tx_bytes = get_tx_bytes();
266 if (tx_bytes > stats_info->pre_tx_bytes) {
267
268 tx_throughput = ((tx_bytes - stats_info->pre_tx_bytes) / (cur_time.tv_sec - pre_time)) >> 7;
269
270 wmt_tm_dprintk("[%s] cur_time=%lu, cur_data=%lu, tx_throughput=%luKb/s\n", __func__, cur_time.tv_sec, tx_bytes, tx_throughput );
271
272 stats_info->pre_tx_bytes = tx_bytes;
273 } else if (tx_bytes < stats_info->pre_tx_bytes) {
274 /* Overflow */
275 tx_throughput = ((0xffffffff - stats_info->pre_tx_bytes + tx_bytes) / (cur_time.tv_sec - pre_time)) >> 7;;
276 stats_info->pre_tx_bytes = tx_bytes;
277 wmt_tm_dprintk("[%s] cur_tx(%lu) < pre_tx\n", __func__, tx_bytes);
278 } else {
279 /* No traffic */
280 tx_throughput = 0;
281 wmt_tm_dprintk("[%s] cur_tx(%lu) = pre_tx\n", __func__, tx_bytes);
282 }
283 } else {
284 /* Overflow possible ??*/
285 tx_throughput = 0;
286 wmt_tm_printk("[%s] cur_time(%lu) < pre_time\n", __func__, cur_time.tv_sec);
287 }
288
289 pre_time = cur_time.tv_sec;
290 wmt_tm_dprintk("[%s] pre_time=%lu, tv_sec=%lu\n",__func__, pre_time, cur_time.tv_sec);
291
292 wmt_stats_timer.expires = jiffies + 1 * HZ;
293 add_timer(&wmt_stats_timer);
294 return 0;
295}
296
297static int wmt_thz_bind(struct thermal_zone_device *thz_dev,
298 struct thermal_cooling_device *cool_dev)
299{
300 struct linux_thermal_ctrl_if *p_linux_if = 0;
301 int table_val = 0;
302
303 wmt_tm_dprintk("[%s]\n", __func__);
304
305 if (pg_wmt_tm) {
306 p_linux_if = &pg_wmt_tm->linux_if;
307 } else {
308 return -EINVAL;
309 }
310 #ifdef NEVER
311 /* cooling devices */
312 if (cool_dev != p_linux_if->cl_dev) {
313 return 0;
314 }
315 #endif
316
317 if(!strcmp(cool_dev->type, g_bind0)) {
318 table_val = 0;
319 wmt_tm_dprintk("[%s] %s\n", __func__, cool_dev->type);
320 } else if(!strcmp(cool_dev->type, g_bind1)) {
321 table_val = 1;
322 wmt_tm_dprintk("[%s] %s\n", __func__, cool_dev->type);
323 } else if(!strcmp(cool_dev->type, g_bind2)) {
324 table_val = 2;
325 wmt_tm_dprintk("[%s]] %s\n", __func__, cool_dev->type);
326 } else if(!strcmp(cool_dev->type, g_bind3)) {
327 table_val = 3;
328 wmt_tm_dprintk("[%s]] %s\n", __func__, cool_dev->type);
329 } else
330 return 0;
331
332 if (mtk_thermal_zone_bind_cooling_device(thz_dev, table_val, cool_dev)) {
333 wmt_tm_info("[%s] binding fail\n", __func__);
334 return -EINVAL;
335 } else {
336 wmt_tm_dprintk("[%s]] binding OK\n", __func__);
337 }
338
339 return 0;
340
341}
342
343static int wmt_thz_unbind(struct thermal_zone_device *thz_dev,
344 struct thermal_cooling_device *cool_dev)
345{
346 struct linux_thermal_ctrl_if *p_linux_if = 0;
347 int table_val = 0;
348
349 wmt_tm_dprintk("[wmt_thz_unbind] \n");
350
351 if (pg_wmt_tm) {
352 p_linux_if = &pg_wmt_tm->linux_if;
353 } else {
354 return -EINVAL;
355 }
356#if 0
357 /* cooling devices */
358 if (cool_dev == p_linux_if->cl_dev) {
359 table_val= 0;
360 } else {
361 wmt_tm_dprintk("[wmt_thz_unbind] unbind device fail..!\n");
362 return -EINVAL;
363 }
364#endif
365
366 if(!strcmp(cool_dev->type, g_bind0)) {
367 table_val = 0;
368 wmt_tm_dprintk("[wmt_thz_unbind] %s\n", cool_dev->type);
369 } else if(!strcmp(cool_dev->type, g_bind1)) {
370 table_val = 1;
371 wmt_tm_dprintk("[wmt_thz_unbind] %s\n", cool_dev->type);
372 } else if(!strcmp(cool_dev->type, g_bind2)) {
373 table_val = 2;
374 wmt_tm_dprintk("[wmt_thz_unbind] %s\n", cool_dev->type);
375 } else if(!strcmp(cool_dev->type, g_bind3)) {
376 table_val = 3;
377 wmt_tm_dprintk("[wmt_thz_unbind] %s\n", cool_dev->type);
378 } else
379 return 0;
380
381 if (thermal_zone_unbind_cooling_device(thz_dev, table_val, cool_dev)) {
382 wmt_tm_info("[wmt_thz_unbind] error unbinding cooling dev\n");
383 return -EINVAL;
384 } else {
385 wmt_tm_dprintk("[wmt_thz_unbind] unbinding OK\n");
386 }
387
388 return 0;
389}
390
391static int wmt_thz_get_temp(struct thermal_zone_device *thz_dev, unsigned long *pv)
392{
393 /* struct wmt_thermal_ctrl_ops *p_des; */
394 int temp = 0;
395
396 *pv = 0;
397
398 /* if(pg_wmt_tm) { */
399 {
400 /* p_des = &pg_wmt_tm->wmt_if.ops; */
401 /* temp = p_des->query_temp(); */
402 temp = mtk_wcn_cmb_stub_query_ctrl();
403
404 if (temp >= 255) /* dummy values */
405 temp = -127;
406
407 /* temp = ((temp & 0x80) == 0x0)?temp:(-1)*temp ; */
408 /* temp = ((temp & 0x80) == 0x0)?temp:(-1)*(temp & 0x7f); */
409 *pv = temp*1000;
410
411 wmt_tm_dprintk("[wmt_thz_get_temp] temp = %d\n", temp);
412
413 if (temp != -127) {
414 if(temp > 100 || temp < -30)
415 wmt_tm_info("[wmt_thz_get_temp] temp = %d\n", temp);
416 }
417 }
418
419 if ((int)*pv >= polling_trip_temp1)
420 thz_dev->polling_delay = g_wmt_tm.linux_if.interval;
421 else if ((int)*pv < polling_trip_temp2)
422 thz_dev->polling_delay = g_wmt_tm.linux_if.interval * polling_factor2;
423 else
424 thz_dev->polling_delay = g_wmt_tm.linux_if.interval * polling_factor1;
425
426 return 0;
427}
428
429static int wmt_thz_get_mode(struct thermal_zone_device *thz_dev, enum thermal_device_mode *mode)
430{
431 struct linux_thermal_ctrl_if *p_linux_if = 0;
432/* int kernel_mode = 0; */
433
434 wmt_tm_dprintk("[%s]\n", __func__);
435
436 if (pg_wmt_tm) {
437 p_linux_if = &pg_wmt_tm->linux_if;
438 } else {
439 wmt_tm_dprintk("[%s] fail! \n", __func__);
440 return -EINVAL;
441 }
442
443 wmt_tm_dprintk("[%s] %d\n", __func__, p_linux_if->kernel_mode);
444
445 *mode = (p_linux_if->kernel_mode) ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED;
446
447 return 0;
448}
449
450static int wmt_thz_set_mode(struct thermal_zone_device *thz_dev, enum thermal_device_mode mode)
451{
452 struct linux_thermal_ctrl_if *p_linux_if = 0;
453
454 wmt_tm_dprintk("[%s]\n", __func__);
455
456
457 if(pg_wmt_tm) {
458 p_linux_if = &pg_wmt_tm->linux_if;
459 } else {
460 wmt_tm_dprintk("[%s] fail! \n", __func__);
461 return -EINVAL;
462 }
463
464 wmt_tm_dprintk("[%s] %d\n", __func__, mode);
465
466 p_linux_if->kernel_mode = mode;
467
468 return 0;
469
470}
471
472static int wmt_thz_get_trip_type(struct thermal_zone_device *thz_dev, int trip,
473 enum thermal_trip_type *type)
474{
475 wmt_tm_dprintk("[mtktspa_get_trip_type] %d\n", trip);
476 *type = g_thermal_trip[trip];
477 return 0;
478}
479
480static int wmt_thz_get_trip_temp(struct thermal_zone_device *thz_dev, int trip, unsigned long *pv)
481{
482 wmt_tm_dprintk("[mtktspa_get_trip_temp] %d\n", trip);
483 *pv = g_trip_temp[trip];
484 return 0;
485}
486
487static int wmt_thz_get_crit_temp(struct thermal_zone_device *thz_dev, unsigned long *pv)
488{
489 wmt_tm_dprintk("[%s]\n", __func__);
490#define WMT_TM_TEMP_CRIT 85000 /* 85.000 degree Celsius */
491 *pv = WMT_TM_TEMP_CRIT;
492
493 return 0;
494}
495
496/* +mtktspa_cooling_sysrst_ops+ */
497static int wmt_cl_get_max_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
498{
499 *pv = 1;
500 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
501 return 0;
502}
503
504static int wmt_cl_get_cur_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
505{
506 *pv = cl_dev_state;
507 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
508 return 0;
509}
510
511static int wmt_cl_set_cur_state(struct thermal_cooling_device *cool_dev, unsigned long v)
512{
513 /* wmt_tm_dprintk("[%s] %d\n", __func__, v); */
514 cl_dev_state = v;
515
516 if (cl_dev_state == 1) {
517 /* the temperature is over than the critical, system reboot. */
518 BUG();
519 }
520
521 return 0;
522}
523
524/* -mtktspa_cooling_sysrst_ops- */
525
526static int wmt_send_signal(int level)
527{
528 int ret = 0;
529 int thro = level;
530
531 if (tm_input_pid == 0) {
532 wmt_tm_dprintk("[%s] pid is empty\n", __func__);
533 ret = -1;
534 }
535
536 wmt_tm_printk("[%s] pid is %d, %d, %d\n", __func__, tm_pid, tm_input_pid, thro);
537
538 if (ret == 0 && tm_input_pid != tm_pid) {
539 tm_pid = tm_input_pid;
540 pg_task = get_pid_task(find_vpid(tm_pid), PIDTYPE_PID);
541 }
542
543 if (ret == 0 && pg_task) {
544 siginfo_t info;
545 info.si_signo = SIGIO;
546 info.si_errno = 0;
547 info.si_code = thro;
548 info.si_addr = NULL;
549 ret = send_sig_info(SIGIO, &info, pg_task);
550 }
551
552 if (ret != 0)
553 wmt_tm_info("[%s] ret=%d\n", __func__, ret);
554
555 return ret;
556}
557
558#define UNK_STAT -1
559#define LOW_STAT 0
560#define MID_STAT 1
561#define HIGH_STAT 2
562#define WFD_STAT 3
563
564static inline unsigned long thro(unsigned long a, unsigned int b, unsigned int c)
565{
566
567 unsigned long tmp;
568
569 tmp = (a << 10) * b / c;
570
571 return tmp >> 10;
572}
573
574static int wmt_judge_throttling(int index, int is_on, int interval)
575{
576 /*
577 * throttling_stat
578 * 2 ( pa1=1,pa2=1 )
579 * UPPER ----
580 * 1 ( pa1=1,pa2=0 )
581 * LOWER ----
582 * 0 ( pa1=0,pa2=0 )
583 */
584 static unsigned int throttling_pre_stat = 0;
585 static int mail_box[2] = {-1,-1};
586
587 static bool is_reset = false;
588
589 unsigned long cur_thro = tx_throughput;
590 static unsigned long thro_constraint = 99 * 1000;
591
592 int cur_wifi_stat = 0;
593
594 wmt_tm_dprintk("[%s]+ [0]=%d, [1]=%d || [%d] is %s\n", __func__, mail_box[0], mail_box[1],
595 index, (is_on==1?"ON":"OFF"));
596 mail_box[index] = is_on;
597
598 if (mail_box[0] >= 0 && mail_box[1] >= 0) {
599 cur_wifi_stat = mail_box[0] + mail_box[1];
600
601 /*
602 * If Wifi-display is on, go to WFD_STAT state, and reset the throttling.
603 */
604 if (tm_wfd_stat == 2)
605 cur_wifi_stat = WFD_STAT;
606
607 switch(cur_wifi_stat) {
608 case WFD_STAT:
609 if (throttling_pre_stat != WFD_STAT) {
610 /*
611 * Enter Wifi-Display status, reset all throttling. Dont affect the performance of Wifi-Display.
612 */
613 wmt_send_signal(-1);
614 below_low_time = 0;
615 over_up_time = 0;
616 throttling_pre_stat = WFD_STAT;
617 wmt_tm_printk("WFD is on, reset everything!");
618 }
619 break;
620
621 case HIGH_STAT:
622 if (throttling_pre_stat < HIGH_STAT || throttling_pre_stat == WFD_STAT) {
623 if (cur_thro > 0) /*Wifi is working!!*/
624 thro_constraint = thro(cur_thro, up_numerator, up_denominator);
625 else /*At this moment, current throughput is none. Use the previous constraint.*/
626 thro_constraint = thro(thro_constraint, up_numerator, up_denominator);
627
628 wmt_tm_printk("LOW/MID-->HIGH:%lu <- (%d / %d) %lu", thro_constraint, up_numerator, up_denominator, cur_thro);
629
630 wmt_send_signal( thro_constraint / 1000);
631 throttling_pre_stat = HIGH_STAT;
632 over_up_time = 0;
633 } else if (throttling_pre_stat == HIGH_STAT) {
634 over_up_time++;
635 if ( (over_up_time * interval) >= up_duration) {
636 if (cur_thro < thro_constraint) /*real throughput may have huge variant*/
637 thro_constraint = thro(cur_thro, up_numerator, up_denominator);
638 else /* current throughput is large than constraint. WHAT!!!*/
639 thro_constraint = thro(thro_constraint, up_numerator, up_denominator);
640
641 wmt_tm_printk("HIGH-->HIGH:%lu <- (%d / %d) %lu", thro_constraint, up_numerator, up_denominator, cur_thro);
642
643 wmt_send_signal( thro_constraint / 1000);
644 over_up_time = 0;
645 }
646 } else {
647 wmt_tm_info("[%s] Error state1!! %u\n", __func__,
648 throttling_pre_stat);
649 }
650 wmt_tm_printk("case2 time=%d\n", over_up_time);
651 break;
652
653 case MID_STAT:
654 if (throttling_pre_stat == LOW_STAT) {
655 below_low_time = 0;
656 throttling_pre_stat = MID_STAT;
657 wmt_tm_printk("[%s] Go up!!\n", __func__);
658 } else if (throttling_pre_stat == HIGH_STAT) {
659 over_up_time = 0;
660 throttling_pre_stat = MID_STAT;
661 wmt_tm_printk("[%s] Go down!!\n", __func__);
662 } else {
663 throttling_pre_stat = MID_STAT;
664 wmt_tm_dprintk("[%s] pre_stat=%d!!\n", __func__, throttling_pre_stat);
665 }
666 break;
667
668 case LOW_STAT:
669 if (throttling_pre_stat == WFD_STAT) {
670 throttling_pre_stat = LOW_STAT;
671 wmt_tm_dprintk("[%s] pre_stat=%d!!\n", __func__, throttling_pre_stat);
672 } else if (throttling_pre_stat > LOW_STAT) {
673 if (cur_thro < 5000 && cur_thro > 0) {
674 thro_constraint = cur_thro * 3;
675 } else if (cur_thro >= 5000) {
676 thro_constraint = thro(cur_thro, low_numerator, low_denominator);
677 } else {
678 thro_constraint = thro(thro_constraint, low_numerator, low_denominator);
679 }
680
681 wmt_tm_printk("MID/HIGH-->LOW:%lu <- (%d / %d) %lu", thro_constraint, low_numerator, low_denominator, cur_thro);
682 wmt_send_signal( thro_constraint / 1000);
683 throttling_pre_stat = LOW_STAT;
684 below_low_time = 0;
685 low_rst_time = 0;
686 is_reset = false;
687 } else if (throttling_pre_stat == LOW_STAT) {
688 below_low_time++;
689 if ( (below_low_time*interval) >= low_duration) {
690 if (low_rst_time >= low_rst_max && !is_reset) {
691 wmt_tm_printk("over rst time=%d", low_rst_time);
692
693 wmt_send_signal(-1); //reset
694 low_rst_time = low_rst_max;
695 is_reset = true;
696 } else if(!is_reset) {
697 if (cur_thro < 5000 && cur_thro > 0) {
698 thro_constraint = cur_thro * 3;
699 } else if (cur_thro >= 5000) {
700 thro_constraint = thro(cur_thro, low_numerator, low_denominator);
701 low_rst_time++;
702 } else {
703 thro_constraint = thro(thro_constraint, low_numerator, low_denominator);
704 low_rst_time++;
705 }
706
707 wmt_tm_printk("LOW-->LOW:%lu <-(%d / %d) %lu", thro_constraint, low_numerator, low_denominator, cur_thro);
708
709 wmt_send_signal( thro_constraint / 1000);
710 below_low_time = 0;
711 } else {
712 wmt_tm_dprintk("Have reset, no control!!");
713 }
714 }
715 } else {
716 wmt_tm_info("[%s] Error state3 %d!!\n", __func__, throttling_pre_stat);
717 }
718 wmt_tm_dprintk("case0 time=%d, rst=%d %d\n", below_low_time, low_rst_time, is_reset);
719 break;
720
721 default:
722 wmt_tm_info("[%s] Error cur_wifi_stat=%d!!\n", __func__, cur_wifi_stat);
723 break;
724 }
725
726 mail_box[0] = UNK_STAT;
727 mail_box[1] = UNK_STAT;
728 } else {
729 wmt_tm_dprintk("[%s] dont get all info!!\n", __func__);
730 }
731 return 0;
732}
733
734/* +mtktspa_cooling_pa1_ops+ */
735static int wmt_cl_pa1_get_max_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
736{
737 *pv = 1;
738 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
739 return 0;
740}
741
742static int wmt_cl_pa1_get_cur_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
743{
744 *pv = cl_pa1_dev_state;
745 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
746 return 0;
747}
748
749static int wmt_cl_pa1_set_cur_state(struct thermal_cooling_device *cool_dev, unsigned long v)
750{
751 struct linux_thermal_ctrl_if *p_linux_if = 0;
752 int ret = 0;
753
754 /* wmt_tm_dprintk("[%s] %d\n", __func__, v); */
755
756 if (pg_wmt_tm) {
757 p_linux_if = &pg_wmt_tm->linux_if;
758 } else {
759 ret = -1;
760 }
761
762 cl_pa1_dev_state = (unsigned int)v;
763
764 if (cl_pa1_dev_state == 1) {
765 ret = wmt_judge_throttling(0, 1, p_linux_if->interval/1000);
766 } else {
767 ret = wmt_judge_throttling(0, 0, p_linux_if->interval/1000);
768 }
769 if (ret != 0)
770 wmt_tm_info("[%s] ret=%d\n", __func__, ret);
771 return ret;
772}
773
774/* -mtktspa_cooling_pa1_ops- */
775
776/* +mtktspa_cooling_pa2_ops+ */
777static int wmt_cl_pa2_get_max_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
778{
779 *pv = 1;
780 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
781 return 0;
782}
783
784static int wmt_cl_pa2_get_cur_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
785{
786 *pv = cl_pa2_dev_state;
787 /* wmt_tm_dprintk("[%s] %d\n", __func__, *pv); */
788 return 0;
789}
790
791static int wmt_cl_pa2_set_cur_state(struct thermal_cooling_device *cool_dev, unsigned long v)
792{
793 struct linux_thermal_ctrl_if *p_linux_if = 0;
794 int ret = 0;
795
796 /* wmt_tm_dprintk("[%s] %d\n", __func__, v); */
797
798 if (pg_wmt_tm) {
799 p_linux_if = &pg_wmt_tm->linux_if;
800 } else {
801 ret = -1;
802 }
803
804 cl_pa2_dev_state = (unsigned int)v;
805
806 if (cl_pa2_dev_state == 1) {
807 ret = wmt_judge_throttling(1, 1, p_linux_if->interval/1000);
808 } else {
809 ret = wmt_judge_throttling(1, 0, p_linux_if->interval/1000);
810 }
811 if (ret != 0)
812 wmt_tm_info("[%s] ret=%d\n", __func__, ret);
813 return ret;
814}
815
816/* -mtktspa_cooling_pa2_ops- */
817
818#ifdef NEVER
819/* +mtktspa_cooling_pa3_ops+ */
820static int wmt_cl_pa3_get_max_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
821{
822 *pv = 1;
823 wmt_tm_dprintk("[%s] %d\n", __func__, *pv);
824 return 0;
825}
826
827static int wmt_cl_pa3_get_cur_state(struct thermal_cooling_device *cool_dev, unsigned long *pv)
828{
829 *pv = cl_pa3_dev_state;
830 wmt_tm_dprintk("[%s] %d\n", __func__, *pv);
831 return 0;
832}
833
834static int wmt_cl_pa3_set_cur_state(struct thermal_cooling_device *cool_dev, unsigned long v)
835{
836 struct linux_thermal_ctrl_if *p_linux_if = 0;
837 int ret = 0;
838
839 wmt_tm_dprintk("[%s] %d\n", __func__, v);
840
841 if (pg_wmt_tm) {
842 p_linux_if = &pg_wmt_tm->linux_if;
843 } else {
844 ret = -1;
845 }
846
847 cl_pa3_dev_state = (unsigned int)v;
848
849 if (cl_pa3_dev_state == 1) {
850 /* ret = wmt_arbitrate_thro(2,3); */
851 } else {
852 /* ret = wmt_arbitrate_thro(2,0); */
853 }
854 if (ret != 0)
855 wmt_tm_printk("[%s] ret=%d\n", __func__, ret);
856 return ret;
857}
858
859/* -mtktspa_cooling_pa3_ops- */
860#endif /* NEVER */
861
862int wmt_wifi_tx_thro_read(struct seq_file *m, void *v)
863{
864 seq_printf(m, "%lu\n", tx_throughput);
865
866 wmt_tm_dprintk("[%s] tx=%lu\n", __func__, tx_throughput);
867
868 return 0;
869}
870
871static int wmt_wifi_tx_thro_open(struct inode *inode, struct file *file)
872{
873#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
874 return single_open(file, wmt_wifi_tx_thro_read, PDE_DATA(inode));
875#else
876 return single_open(file, wmt_wifi_tx_thro_read, PDE(inode)->data);
877#endif
878}
879
880/*New Wifi throttling Algo+*/
881ssize_t wmt_wifi_algo_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
882{
883 char desc[MAX_LEN] = {0};
884
885 unsigned int tmp_up_dur = 30;
886 unsigned int tmp_up_den = 2;
887 unsigned int tmp_up_num = 1;
888
889 unsigned int tmp_low_dur = 3;
890 unsigned int tmp_low_den = 2;
891 unsigned int tmp_low_num = 3;
892
893 unsigned int tmp_low_rst_max = 3;
894
895 unsigned int tmp_log = 0;
896
897 len = (len < (sizeof(desc) - 1)) ? len : (sizeof(desc) - 1);
898
899 /* write data to the buffer */
900 if (copy_from_user(desc, buf, len)) {
901 return -EFAULT;
902 }
903
904 if (sscanf(desc, "%d %d/%d %d %d/%d %d", &tmp_up_dur, &tmp_up_num, &tmp_up_den, &tmp_low_dur, \
905 &tmp_low_num, &tmp_low_den, &tmp_low_rst_max) == 7) {
906
907 up_duration = tmp_up_dur;
908 up_denominator = tmp_up_den;
909 up_numerator = tmp_up_num;
910
911 low_duration = tmp_low_dur;
912 low_denominator = tmp_low_den;
913 low_numerator = tmp_low_num;
914
915 low_rst_max = tmp_low_rst_max;
916
917 over_up_time = 0;
918 below_low_time = 0;
919 low_rst_time = 0;
920
921 wmt_tm_printk("[%s] %s [up]%d %d/%d, [low]%d %d/%d, rst=%d\n", __func__, desc, up_duration, \
922 up_numerator, up_denominator, low_duration, low_numerator, low_denominator, low_rst_max);
923
924 return len;
925 } else if (sscanf(desc, "log=%d", &tmp_log) == 1) {
926 if (tmp_log == 1)
927 wmt_tm_debug_log = 1;
928 else
929 wmt_tm_debug_log = 0;
930
931 return len;
932 } else {
933 wmt_tm_printk("[%s] bad argument = %s\n", __func__, desc);
934 }
935 return -EINVAL;
936}
937
938int wmt_wifi_algo_read(struct seq_file *m, void *v)
939{
940 /* int ret; */
941 /* char tmp[MAX_LEN] = {0}; */
942
943 seq_printf(m, "[up]\t%3d(sec)\t%2d/%2d\n[low]\t%3d(sec)\t%2d/%2d\nrst=%2d\n", up_duration,
944 up_numerator, up_denominator, low_duration, low_numerator, low_denominator,
945 low_rst_max);
946 /* ret = strlen(tmp); */
947
948 /* memcpy(buf, tmp, ret*sizeof(char)); */
949
950 wmt_tm_printk("[%s] [up]%d %d/%d, [low]%d %d/%d, rst=%d\n", __func__, up_duration, \
951 up_numerator, up_denominator, low_duration, low_numerator, low_denominator, low_rst_max);
952
953 return 0;
954}
955
956static int wmt_wifi_algo_open(struct inode *inode, struct file *file)
957{
958#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
959 return single_open(file, wmt_wifi_algo_read, PDE_DATA(inode));
960#else
961 return single_open(file, wmt_wifi_algo_read, PDE(inode)->data);
962#endif
963}
964
965/*New Wifi throttling Algo-*/
966
967ssize_t wmt_tm_wfd_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
968{
969 int ret = 0;
970 char tmp[MAX_LEN] = {0};
971
4b9e9796 972 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
6fa3eb70
S
973 /* write data to the buffer */
974 if (copy_from_user(tmp, buf, len)) {
975 return -EFAULT;
976 }
977
978 ret = sscanf(tmp, "%d", &tm_wfd_stat);
979
980 wmt_tm_printk("[%s] %s = %d, len=%d, ret=%d\n", __func__, tmp, tm_wfd_stat, len, ret);
981
982 return len;
983}
984
985int wmt_tm_wfd_read(struct seq_file *m, void *v)
986{
987 /* int len; */
988 /* int ret = 0; */
989 /* char tmp[MAX_LEN] = {0}; */
990
991 seq_printf(m, "%d\n", tm_wfd_stat);
992 /* len = strlen(tmp); */
993
994 /* memcpy(buf, tmp, ret*sizeof(char)); */
995
996 wmt_tm_printk("[%s] %d\n", __func__, tm_wfd_stat);
997
998 return 0;
999}
1000
1001static int wmt_tm_wfd_open(struct inode *inode, struct file *file)
1002{
1003#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1004 return single_open(file, wmt_tm_wfd_read, PDE_DATA(inode));
1005#else
1006 return single_open(file, wmt_tm_wfd_read, PDE(inode)->data);
1007#endif
1008}
1009
1010ssize_t wmt_tm_pid_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
1011{
1012 int ret = 0;
1013 char tmp[MAX_LEN] = {0};
1014
4b9e9796 1015 len = (len < (MAX_LEN-1)) ? len : (MAX_LEN-1);
6fa3eb70
S
1016 /* write data to the buffer */
1017 if ( copy_from_user(tmp, buf, len) ) {
1018 return -EFAULT;
1019 }
1020
1021 ret = kstrtouint(tmp, 10, &tm_input_pid);
1022 if (ret)
1023 WARN_ON(1);
1024
1025 wmt_tm_printk("[%s] %s = %d\n", __func__, tmp, tm_input_pid);
1026
1027 return len;
1028}
1029
1030int wmt_tm_pid_read(struct seq_file *m, void *v)
1031{
1032 /* int ret; */
1033 /* char tmp[MAX_LEN] = {0}; */
1034
1035 seq_printf(m, "%d\n", tm_input_pid);
1036 /* ret = strlen(tmp); */
1037
1038 /* memcpy(buf, tmp, ret*sizeof(char)); */
1039
1040 wmt_tm_printk("[%s] %d\n", __func__, tm_input_pid);
1041
1042 return 0;
1043}
1044
1045static int wmt_tm_pid_open(struct inode *inode, struct file *file)
1046{
1047#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1048 return single_open(file, wmt_tm_pid_read, PDE_DATA(inode));
1049#else
1050 return single_open(file, wmt_tm_pid_read, PDE(inode)->data);
1051#endif
1052}
1053
1054#define check_str(x) (x[0]=='\0'?"none\t":x)
1055
1056static int wmt_tm_read(struct seq_file *m, void *v)
1057{
1058 /* int len = 0; */
1059 /* char *p = buf; */
1060 struct linux_thermal_ctrl_if *p_linux_if = 0;
1061
1062 wmt_tm_printk("[%s]\n", __func__);
1063
1064 /* sanity */
1065 if(pg_wmt_tm) {
1066 p_linux_if = &pg_wmt_tm->linux_if;
1067 } else {
1068 wmt_tm_info("[wmt_tm_read] fail! \n");
1069 return -EINVAL;
1070 }
1071
1072 seq_printf(m, "[wmt_tm_read]"
1073 "\n \tcooler\t\ttrip_temp\ttrip_type"
1074 "\n [0] %s\t%d\t\t%d"
1075 "\n [1] %s\t%d\t\t%d"
1076 "\n [2] %s\t%d\t\t%d"
1077 "\n [3] %s\t%d\t\t%d"
1078 "\n [4] %s\t%d\t\t%d"
1079 "\n [5] %s\t%d\t\t%d"
1080 "\n [6] %s\t%d\t\t%d"
1081 "\n [7] %s\t%d\t\t%d"
1082 "\n [8] %s\t%d\t\t%d"
1083 "\n [9] %s\t%d\t\t%d"
1084 "\ntime_ms=%d\n",
1085 check_str(g_bind0), g_trip_temp[0], g_thermal_trip[0], check_str(g_bind1),
1086 g_trip_temp[1], g_thermal_trip[1], check_str(g_bind2), g_trip_temp[2],
1087 g_thermal_trip[2], check_str(g_bind3), g_trip_temp[3], g_thermal_trip[3],
1088 check_str(g_bind4), g_trip_temp[4], g_thermal_trip[4], check_str(g_bind5),
1089 g_trip_temp[5], g_thermal_trip[5], check_str(g_bind6), g_trip_temp[6],
1090 g_thermal_trip[6], check_str(g_bind7), g_trip_temp[7], g_thermal_trip[7],
1091 check_str(g_bind8), g_trip_temp[8], g_thermal_trip[8], check_str(g_bind9),
1092 g_trip_temp[9], g_thermal_trip[9], p_linux_if->interval);
1093
1094 return 0;
1095}
1096
1097static int wmt_tm_open(struct inode *inode, struct file *file)
1098{
1099#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1100 return single_open(file, wmt_tm_read, PDE_DATA(inode));
1101#else
1102 return single_open(file, wmt_tm_read, PDE(inode)->data);
1103#endif
1104}
1105
1106static ssize_t wmt_tm_write(struct file *filp, const char __user *buf, size_t count, loff_t *data)
1107{
1108 int i = 0;
1109 int len=0,time_msec=0;
1110 int trip_temp[COOLER_NUM] = {0};
1111 int thermal_trip[COOLER_NUM] = {0};
1112
1113 char desc[512];
1114 char bind0[20],bind1[20],bind2[20],bind3[20],bind4[20];
1115 char bind5[20],bind6[20],bind7[20],bind8[20],bind9[20];
1116
1117 struct linux_thermal_ctrl_if *p_linux_if = 0;
1118
1119 wmt_tm_printk("[%s]\n", __func__);
1120
1121 /* sanity */
1122 if(pg_wmt_tm) {
1123 p_linux_if = &pg_wmt_tm->linux_if;
1124 } else {
1125 wmt_tm_info("[wmt_thz_write] fail! \n");
1126 return -EINVAL;
1127 }
1128
1129 len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
1130
1131 if (copy_from_user(desc, buf, len)) {
1132 return 0;
1133 }
1134
1135 desc[len] = '\0';
1136
1137 if (sscanf
1138 (desc,
1139 "%d %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d %d %s %d",
1140 &g_num_trip, &trip_temp[0], &thermal_trip[0], bind0, &trip_temp[1], &thermal_trip[1],
1141 bind1, &trip_temp[2], &thermal_trip[2], bind2, &trip_temp[3], &thermal_trip[3], bind3,
1142 &trip_temp[4], &thermal_trip[4], bind4, &trip_temp[5], &thermal_trip[5], bind5,
1143 &trip_temp[6], &thermal_trip[6], bind6, &trip_temp[7], &thermal_trip[7], bind7,
1144 &trip_temp[8], &thermal_trip[8], bind8, &trip_temp[9], &thermal_trip[9], bind9,
1145 &time_msec) == 32) {
1146 /* unregister */
1147 if (p_linux_if->thz_dev) {
1148 mtk_thermal_zone_device_unregister(p_linux_if->thz_dev);
1149 p_linux_if->thz_dev = NULL;
1150 }
1151
1152 for ( i = 0; i < g_num_trip; i++) {
1153 g_thermal_trip[i] = thermal_trip[i];
1154 }
1155
1156 g_bind0[0]=g_bind1[0]=g_bind2[0]=g_bind3[0]=g_bind4[0]='\0';
1157 g_bind5[0]=g_bind6[0]=g_bind7[0]=g_bind8[0]=g_bind9[0]='\0';
1158
1159 for ( i = 0; i < 20; i++ ) {
1160 g_bind0[i]=bind0[i];
1161 g_bind1[i]=bind1[i];
1162 g_bind2[i]=bind2[i];
1163 g_bind3[i]=bind3[i];
1164 g_bind4[i]=bind4[i];
1165 g_bind5[i]=bind5[i];
1166 g_bind6[i]=bind6[i];
1167 g_bind7[i]=bind7[i];
1168 g_bind8[i]=bind8[i];
1169 g_bind9[i]=bind9[i];
1170 }
1171
1172 for ( i = 0; i < g_num_trip; i++) {
1173 g_trip_temp[i] = trip_temp[i];
1174 }
1175
1176 p_linux_if->interval = time_msec;
1177
1178 wmt_tm_dprintk("[wmt_tm_write] g_trip_temp [0]=%d, [1]=%d, [2]=%d, [3]=%d, [4]=%d\n",
1179 g_thermal_trip[0], g_thermal_trip[1], g_thermal_trip[2],
1180 g_thermal_trip[3], g_thermal_trip[4]);
1181
1182 wmt_tm_dprintk("[wmt_tm_write] g_trip_temp [5]=%d, [6]=%d, [7]=%d, [8]=%d, [9]=%d\n",
1183 g_thermal_trip[5], g_thermal_trip[6], g_thermal_trip[7],
1184 g_thermal_trip[8], g_thermal_trip[9]);
1185
1186 wmt_tm_dprintk("[wmt_tm_write] cooldev [0]=%s, [1]=%s, [2]=%s, [3]=%s, [4]=%s,\n",
1187 g_bind0, g_bind1, g_bind2, g_bind3, g_bind4);
1188
1189 wmt_tm_dprintk("[wmt_tm_write] cooldev [5]=%s, [6]=%s, [7]=%s, [8]=%s, [9]=%s,\n",
1190 g_bind5, g_bind6, g_bind7, g_bind8, g_bind9);
1191
1192 wmt_tm_dprintk("[wmt_tm_write] trip_temp [0]=%d, [1]=%d, [2]=%d, [3]=%d, [4]=%d\n",
1193 trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3], trip_temp[4]);
1194
1195 wmt_tm_dprintk("[wmt_tm_write] trip_temp [5]=%d, [6]=%d, [7]=%d, [8]=%d, [9]=%d\n",
1196 trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8], trip_temp[9]);
1197
1198 wmt_tm_dprintk("[wmt_tm_write] polling time=%d\n", p_linux_if->interval);
1199
1200 /* p_linux_if->thz_dev->polling_delay = p_linux_if->interval*1000; */
1201
1202 /* thermal_zone_device_update(p_linux_if->thz_dev); */
1203
1204 /* register */
1205 p_linux_if->thz_dev = mtk_thermal_zone_device_register("mtktswmt", g_num_trip, NULL,
1206 &wmt_thz_dev_ops, 0, 0, 0, p_linux_if->interval);
1207
1208 wmt_tm_dprintk("[wmt_tm_write] time_ms=%d\n", p_linux_if->interval);
1209
1210 return count;
1211 } else {
1212 wmt_tm_info("[%s] bad argument = %s\n", __func__, desc);
1213 }
1214
1215 return -EINVAL;
1216}
1217
1218static const struct file_operations _wmt_tm_fops = {
1219 .owner = THIS_MODULE,
1220 .open = wmt_tm_open,
1221 .read = seq_read,
1222 .llseek = seq_lseek,
1223 .write = wmt_tm_write,
1224 .release = single_release,
1225};
1226
1227static const struct file_operations _tm_pid_fops = {
1228 .owner = THIS_MODULE,
1229 .open = wmt_tm_pid_open,
1230 .read = seq_read,
1231 .llseek = seq_lseek,
1232 .write = wmt_tm_pid_write,
1233 .release = single_release,
1234};
1235
1236static const struct file_operations _wmt_val_fops = {
1237 .owner = THIS_MODULE,
1238 .open = wmt_wifi_algo_open,
1239 .read = seq_read,
1240 .llseek = seq_lseek,
1241 .write = wmt_wifi_algo_write,
1242 .release = single_release,
1243};
1244
1245static const struct file_operations _tx_thro_fops = {
1246 .owner = THIS_MODULE,
1247 .open = wmt_wifi_tx_thro_open,
1248 .read = seq_read,
1249 .llseek = seq_lseek,
1250 .release = single_release,
1251};
1252
1253static const struct file_operations _wfd_stat_fops = {
1254 .owner = THIS_MODULE,
1255 .open = wmt_tm_wfd_open,
1256 .read = seq_read,
1257 .llseek = seq_lseek,
1258 .write = wmt_tm_wfd_write,
1259 .release = single_release,
1260};
1261
1262static int wmt_tm_proc_register(void)
1263{
1264 struct proc_dir_entry *entry = NULL;
1265 struct proc_dir_entry *wmt_tm_proc_dir = NULL;
1266
1267 wmt_tm_dprintk("[%s]\n", __func__);
1268
1269 wmt_tm_proc_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
1270 if (!wmt_tm_proc_dir) {
1271 wmt_tm_printk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
1272 } else {
1273 entry =
1274 proc_create("tzwmt", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, wmt_tm_proc_dir,
1275 &_wmt_tm_fops);
1276 if (entry) {
1277#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1278 proc_set_user(entry, 0, 1000);
1279#else
1280 entry->gid = 1000;
1281#endif
1282 }
1283
1284 entry =
1285 proc_create("clwmt_pid", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, wmt_tm_proc_dir,
1286 &_tm_pid_fops);
1287 if (entry) {
1288#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1289 proc_set_user(entry, 0, 1000);
1290#else
1291 entry->gid = 1000;
1292#endif
1293 }
1294
1295 entry =
1296 proc_create("clwmt_val", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, wmt_tm_proc_dir,
1297 &_wmt_val_fops);
1298 if (entry) {
1299#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1300 proc_set_user(entry, 0, 1000);
1301#else
1302 entry->gid = 1000;
1303#endif
1304 }
1305
1306 entry = proc_create("wifi_tx_thro", S_IRUGO | S_IWUSR, wmt_tm_proc_dir, &_tx_thro_fops);
1307
1308 entry =
1309 proc_create("clwmt_wfdstat", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, wmt_tm_proc_dir,
1310 &_wfd_stat_fops);
1311 if (entry) {
1312#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
1313 proc_set_user(entry, 0, 1000);
1314#else
1315 entry->gid = 1000;
1316#endif
1317 }
1318 }
1319 return 0;
1320}
1321
1322static int wmt_tm_proc_unregister(void)
1323{
1324 wmt_tm_dprintk("[%s]\n", __func__);
1325 /* remove_proc_entry("wmt_tm", proc_entry); */
1326 return 0;
1327}
1328
1329static int wmt_tm_thz_cl_register(void)
1330{
1331 #define DEFAULT_POLL_TIME 0 /*Default disable, turn on by thermal policy*/
1332
1333 struct linux_thermal_ctrl_if *p_linux_if = 0;
1334
1335 wmt_tm_dprintk("[%s]\n", __func__);
1336
1337 if(pg_wmt_tm) {
1338 p_linux_if = &pg_wmt_tm->linux_if;
1339 } else {
1340 return -1;
1341 }
1342
1343 /* cooling devices */
1344 p_linux_if->cl_dev = mtk_thermal_cooling_device_register("mtktswmt-sysrst", NULL,
1345 &mtktspa_cooling_sysrst_ops);
1346
1347 p_linux_if->cl_pa1_dev = mtk_thermal_cooling_device_register("mtktswmt-pa1", NULL,
1348 &mtktspa_cooling_pa1_ops);
1349
1350 p_linux_if->cl_pa2_dev = mtk_thermal_cooling_device_register("mtktswmt-pa2", NULL,
1351 &mtktspa_cooling_pa2_ops);
1352
1353#ifdef NEVER
1354 p_linux_if->cl_pa3_dev = mtk_thermal_cooling_device_register("mtktswmt-pa3", NULL,
1355 &mtktspa_cooling_pa3_ops);
1356#endif /* NEVER */
1357
1358 p_linux_if->interval = DEFAULT_POLL_TIME;
1359
1360 /* trips */
1361 p_linux_if->thz_dev = mtk_thermal_zone_device_register("mtktswmt", g_num_trip, NULL,
1362 &wmt_thz_dev_ops, 0, 0, 0, p_linux_if->interval);
1363
1364 return 0;
1365}
1366
1367static int wmt_tm_thz_cl_unregister(void)
1368{
1369 struct linux_thermal_ctrl_if *p_linux_if = 0;
1370
1371 wmt_tm_dprintk("[%s]\n", __func__);
1372
1373 if(pg_wmt_tm) {
1374 p_linux_if = &pg_wmt_tm->linux_if;
1375 } else {
1376 return -1;
1377 }
1378
1379 if (p_linux_if->cl_dev) {
1380 mtk_thermal_cooling_device_unregister(p_linux_if->cl_dev);
1381 p_linux_if->cl_dev = NULL;
1382 }
1383
1384 if (p_linux_if->cl_pa1_dev) {
1385 mtk_thermal_cooling_device_unregister(p_linux_if->cl_pa1_dev);
1386 p_linux_if->cl_pa1_dev = NULL;
1387 }
1388
1389 if (p_linux_if->cl_pa2_dev) {
1390 mtk_thermal_cooling_device_unregister(p_linux_if->cl_pa2_dev);
1391 p_linux_if->cl_pa2_dev = NULL;
1392 }
1393
1394#ifdef NEVER
1395 if (p_linux_if->cl_pa3_dev) {
1396 mtk_thermal_cooling_device_unregister(p_linux_if->cl_pa3_dev);
1397 p_linux_if->cl_pa3_dev = NULL;
1398 }
1399#endif /* NEVER */
1400
1401 if (p_linux_if->thz_dev) {
1402 mtk_thermal_zone_device_unregister(p_linux_if->thz_dev);
1403 p_linux_if->thz_dev = NULL;
1404 }
1405
1406 return 0;
1407}
1408
1409#if 0
1410static int wmt_tm_ops_register(struct wmt_thermal_ctrl_ops *ops)
1411{
1412 struct wmt_thermal_ctrl_ops *p_des;
1413
1414 wmt_tm_printk("[%s]\n", __func__);
1415
1416 if (pg_wmt_tm) {
1417#if 1
1418 p_des = &pg_wmt_tm->wmt_if.ops;
1419 if (ops!=NULL) {
1420 wmt_tm_printk("[wmt_tm_ops_register] reg start ...\n");
1421 p_des->query_temp = ops->query_temp;
1422 p_des->set_temp = ops->set_temp;
1423 wmt_tm_printk("[wmt_tm_ops_register] reg end ...\n");
1424 } else {
1425 p_des->query_temp = 0;
1426 p_des->set_temp = 0;
1427 }
1428#endif
1429 return 0;
1430 } else {
1431 return -1;
1432 }
1433}
1434
1435static int wmt_tm_ops_unregister(void)
1436{
1437 struct wmt_thermal_ctrl_ops *p_des;
1438
1439 wmt_tm_printk("[%s]\n", __func__);
1440
1441 if (pg_wmt_tm) {
1442 p_des = &pg_wmt_tm->wmt_if.ops;
1443 p_des->query_temp = 0;
1444 p_des->set_temp = 0;
1445
1446 return 0;
1447 } else {
1448 return -1;
1449 }
1450}
1451#endif
1452
1453static int __init wmt_tm_init(void)
1454{
1455 int err = 0;
1456
1457 wmt_tm_printk("[wmt_tm_init] start -->\n");
1458
1459#if 0
1460 err = wmt_tm_ops_register(ops);
1461 if(err)
1462 return err;
1463#endif
1464
1465 err = wmt_tm_proc_register();
1466 if(err)
1467 return err;
1468
1469 /* init a timer for stats tx bytes */
1470 wmt_stats_info.pre_time = 0;
1471 wmt_stats_info.pre_tx_bytes = 0;
1472
1473 init_timer(&wmt_stats_timer);
1474 wmt_stats_timer.function = (void *)&wmt_cal_stats;
1475 wmt_stats_timer.data = (unsigned long) &wmt_stats_info;
1476 wmt_stats_timer.expires = jiffies + 1 * HZ;
1477 add_timer(&wmt_stats_timer);
1478
1479#if 1
1480 err = wmt_tm_thz_cl_register();
1481 if(err)
1482 return err;
1483#endif
1484 wmt_tm_printk("[wmt_tm_init] end <--\n");
1485
1486 return 0;
1487}
1488
1489#if 0
1490int wmt_tm_init_rt(void)
1491{
1492 int err = 0;
1493
1494 wmt_tm_printk("[wmt_tm_init_rt] start -->\n");
1495
1496 err = wmt_tm_thz_cl_register();
1497 if(err)
1498 return err;
1499
1500 wmt_tm_printk("[wmt_tm_init_rt] end <--\n");
1501
1502 return 0;
1503}
1504
1505int wmt_tm_deinit_rt(void)
1506{
1507 int err = 0;
1508
1509 wmt_tm_printk("[wmt_tm_deinit_rt] start -->\n");
1510
1511 err = wmt_tm_thz_cl_unregister();
1512 if(err)
1513 return err;
1514
1515 wmt_tm_printk("[wmt_tm_deinit_rt] end <--\n");
1516
1517 return 0;
1518}
1519#endif
1520
1521static void __exit wmt_tm_deinit(void)
1522{
1523 int err = 0;
1524
1525 wmt_tm_printk("[%s]\n", __func__);
1526#if 1
1527 err = wmt_tm_thz_cl_unregister();
1528 if(err)
1529 return;
1530#endif
1531 err = wmt_tm_proc_unregister();
1532 if(err)
1533 return;
1534
1535#if 0
1536 err = wmt_tm_ops_unregister();
1537 if(err)
1538 return;
1539#endif
1540
1541 del_timer(&wmt_stats_timer);
1542
1543 return;
1544}
1545module_init(wmt_tm_init);
1546module_exit(wmt_tm_deinit);
1547