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