3 #include <linux/thermal.h>
4 #include <linux/proc_fs.h>
5 #include <asm/uaccess.h>
7 #include <mach/mtk_thermal_monitor.h>
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 - */
15 #if defined(CONFIG_THERMAL) && defined(CONFIG_THERMAL_OPEN)
17 static int wmt_tm_debug_log
= 0;
18 #define wmt_tm_dprint(fmt, args...) \
20 if (wmt_tm_debug_log) { \
21 pr_warn(ANDROID_LOG_DEBUG, "Power/WMT_Thermal", fmt, ##args); \
25 #define wmt_tm_print(fmt, args...) \
27 pr_warn(ANDROID_LOG_DEBUG, "Power/WMT_Thermal", fmt, ##args); \
30 #define wmt_tm_info(fmt, args...) \
32 pr_warn(ANDROID_LOG_INFO, "Power/WMT_Thermal", fmt, ##args); \
35 struct linux_thermal_ctrl_if
{
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
;
45 struct wmt_thermal_ctrl_if
{
46 struct wmt_thermal_ctrl_ops ops
;
49 typedef struct wmt_tm
{
50 struct linux_thermal_ctrl_if linux_if
;
51 struct wmt_thermal_ctrl_if wmt_if
;
55 unsigned long pre_time
;
56 unsigned long pre_tx_bytes
;
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
;
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;
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;
77 static unsigned int low_rst_time
= 0;
78 static unsigned int low_rst_max
= 3;
79 /*New Wifi throttling Algo-*/
82 #define COOLER_THRO_NUM 3
84 #define ONE_MBITS_PER_SEC 1000
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
;
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 };
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 };
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 };
118 wmt_tm_t
*pg_wmt_tm
= &g_wmt_tm
;
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);
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);
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);
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);
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
,
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
,
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
,
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
,
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
,
183 static unsigned long get_tx_bytes(void)
185 struct net_device
*dev
;
187 unsigned long tx_bytes
= 0;
189 read_lock(&dev_base_lock
);
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
;
200 read_unlock(&dev_base_lock
);
204 static int wmt_cal_stats(unsigned long data
)
206 struct wmt_stats
*stats_info
= (struct wmt_stats
*)data
;
207 struct timeval cur_time
;
209 wmt_tm_dprint("[%s] pre_time=%lu, pre_data=%lu\n", __func__
, pre_time
,
210 stats_info
->pre_tx_bytes
);
212 do_gettimeofday(&cur_time
);
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
) {
219 ((tx_bytes
- stats_info
->pre_tx_bytes
) / (cur_time
.tv_sec
-
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
);
225 stats_info
->pre_tx_bytes
= tx_bytes
;
226 } else if (tx_bytes
< stats_info
->pre_tx_bytes
) {
229 ((0xffffffff - stats_info
->pre_tx_bytes
+ tx_bytes
) / (cur_time
.tv_sec
-
231 stats_info
->pre_tx_bytes
= tx_bytes
;
232 wmt_tm_dprint("[%s] cur_tx(%lu) < pre_tx\n", __func__
, tx_bytes
);
236 wmt_tm_dprint("[%s] cur_tx(%lu) = pre_tx\n", __func__
, tx_bytes
);
239 /* Overflow possible ?? */
241 wmt_tm_print("[%s] cur_time(%lu) < pre_time\n", __func__
, cur_time
.tv_sec
);
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
);
247 wmt_stats_timer
.expires
= jiffies
+ 1 * HZ
;
248 add_timer(&wmt_stats_timer
);
252 static int wmt_thz_bind(struct thermal_zone_device
*thz_dev
,
253 struct thermal_cooling_device
*cool_dev
)
255 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
258 wmt_tm_dprint("[%s]\n", __func__
);
261 p_linux_if
= &pg_wmt_tm
->linux_if
;
266 /* cooling devices */
267 if (cool_dev
!= p_linux_if
->cl_dev
) {
272 if (!strcmp(cool_dev
->type
, g_bind0
)) {
274 wmt_tm_printk("[%s] %s\n", __func__
, cool_dev
->type
);
275 } else if (!strcmp(cool_dev
->type
, g_bind1
)) {
277 wmt_tm_printk("[%s] %s\n", __func__
, cool_dev
->type
);
278 } else if (!strcmp(cool_dev
->type
, g_bind2
)) {
280 wmt_tm_printk("[%s]] %s\n", __func__
, cool_dev
->type
);
281 } else if (!strcmp(cool_dev
->type
, g_bind3
)) {
283 wmt_tm_printk("[%s]] %s\n", __func__
, cool_dev
->type
);
287 if (mtk_thermal_zone_bind_cooling_device(thz_dev
, table_val
, cool_dev
)) {
288 wmt_tm_info("[%s] binding fail\n", __func__
);
291 wmt_tm_printk("[%s]] binding OK\n", __func__
);
298 static int wmt_thz_unbind(struct thermal_zone_device
*thz_dev
,
299 struct thermal_cooling_device
*cool_dev
)
301 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
304 wmt_tm_dprintk("[wmt_thz_unbind] \n");
307 p_linux_if
= &pg_wmt_tm
->linux_if
;
312 /* cooling devices */
313 if (cool_dev
== p_linux_if
->cl_dev
) {
316 wmt_tm_dprintk("[wmt_thz_unbind] unbind device fail..!\n");
321 if (!strcmp(cool_dev
->type
, g_bind0
)) {
323 wmt_tm_printk("[wmt_thz_unbind] %s\n", cool_dev
->type
);
324 } else if (!strcmp(cool_dev
->type
, g_bind1
)) {
326 wmt_tm_printk("[wmt_thz_unbind] %s\n", cool_dev
->type
);
327 } else if (!strcmp(cool_dev
->type
, g_bind2
)) {
329 wmt_tm_printk("[wmt_thz_unbind] %s\n", cool_dev
->type
);
330 } else if (!strcmp(cool_dev
->type
, g_bind3
)) {
332 wmt_tm_printk("[wmt_thz_unbind] %s\n", cool_dev
->type
);
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");
340 wmt_tm_printk("[wmt_thz_unbind] unbinding OK\n");
346 static int wmt_thz_get_temp(struct thermal_zone_device
*thz_dev
, unsigned long *pv
)
348 struct wmt_thermal_ctrl_ops
*p_des
;
353 p_des
= &pg_wmt_tm
->wmt_if
.ops
;
354 temp
= p_des
->query_temp();
356 /* temp = ((temp & 0x80) == 0x0)?temp:(-1)*temp ; */
357 temp
= ((temp
& 0x80) == 0x0) ? temp
: (-1) * (temp
& 0x7f);
360 wmt_tm_dprintk("[wmt_thz_get_temp] temp = %d\n", temp
);
362 if (temp
> 100 || temp
< 5)
363 wmt_tm_info("[wmt_thz_get_temp] temp = %d\n", temp
);
369 static int wmt_thz_get_mode(struct thermal_zone_device
*thz_dev
, enum thermal_device_mode
*mode
)
371 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
372 /* int kernel_mode = 0; */
374 wmt_tm_dprintk("[%s]\n", __func__
);
377 p_linux_if
= &pg_wmt_tm
->linux_if
;
379 wmt_tm_dprintk("[%s] fail! \n", __func__
);
383 wmt_tm_dprintk("[%s] %d\n", __func__
, p_linux_if
->kernel_mode
);
385 *mode
= (p_linux_if
->kernel_mode
) ? THERMAL_DEVICE_ENABLED
: THERMAL_DEVICE_DISABLED
;
390 static int wmt_thz_set_mode(struct thermal_zone_device
*thz_dev
, enum thermal_device_mode mode
)
392 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
394 wmt_tm_dprintk("[%s]\n", __func__
);
398 p_linux_if
= &pg_wmt_tm
->linux_if
;
400 wmt_tm_dprintk("[%s] fail! \n", __func__
);
404 wmt_tm_dprintk("[%s] %d\n", __func__
, mode
);
406 p_linux_if
->kernel_mode
= mode
;
412 static int wmt_thz_get_trip_type(struct thermal_zone_device
*thz_dev
, int trip
,
413 enum thermal_trip_type
*type
)
415 wmt_tm_dprintk("[mtktspa_get_trip_type] %d\n", trip
);
416 *type
= g_thermal_trip
[trip
];
420 static int wmt_thz_get_trip_temp(struct thermal_zone_device
*thz_dev
, int trip
, unsigned long *pv
)
422 wmt_tm_dprintk("[mtktspa_get_trip_temp] %d\n", trip
);
423 *pv
= g_trip_temp
[trip
];
427 static int wmt_thz_get_crit_temp(struct thermal_zone_device
*thz_dev
, unsigned long *pv
)
429 wmt_tm_dprintk("[%s]\n", __func__
);
430 #define WMT_TM_TEMP_CRIT 85000 /* 85.000 degree Celsius */
431 *pv
= WMT_TM_TEMP_CRIT
;
436 /* +mtktspa_cooling_sysrst_ops+ */
437 static int wmt_cl_get_max_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
440 wmt_tm_dprintk("[%s] %d\n", __func__
, *pv
);
444 static int wmt_cl_get_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
447 wmt_tm_dprintk("[%s] %d\n", __func__
, *pv
);
451 static int wmt_cl_set_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long v
)
453 wmt_tm_dprintk("[%s] %d\n", __func__
, v
);
456 if (cl_dev_state
== 1) {
457 /* the temperature is over than the critical, system reboot. */
464 /* -mtktspa_cooling_sysrst_ops- */
466 static int wmt_send_signal(int level
)
471 if (tm_input_pid
== 0) {
472 wmt_tm_dprintk("[%s] pid is empty\n", __func__
);
476 wmt_tm_printk("[%s] pid is %d, %d, %d\n", __func__
, tm_pid
, tm_input_pid
, thro
);
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
);
483 if (ret
== 0 && pg_task
) {
485 info
.si_signo
= SIGIO
;
489 ret
= send_sig_info(SIGIO
, &info
, pg_task
);
493 wmt_tm_info("[%s] ret=%d\n", __func__
, ret
);
504 static inline unsigned long thro(unsigned long a
, unsigned int b
, unsigned int c
)
509 tmp
= (a
<< 10) * b
/ c
;
514 static int wmt_judge_throttling(int index
, int is_on
, int interval
)
524 static unsigned int throttling_pre_stat
= 0;
525 static int mail_box
[2] = { -1, -1 };
527 static bool is_reset
= false;
529 unsigned long cur_thro
= tx_throughput
;
530 static unsigned long thro_constraint
= 99 * 1000;
532 int cur_wifi_stat
= 0;
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
;
538 if (mail_box
[0] >= 0 && mail_box
[1] >= 0) {
539 cur_wifi_stat
= mail_box
[0] + mail_box
[1];
542 * If Wifi-display is on, go to WFD_STAT state, and reset the throttling.
544 if (tm_wfd_stat
== 2)
545 cur_wifi_stat
= WFD_STAT
;
547 switch (cur_wifi_stat
) {
549 if (throttling_pre_stat
!= WFD_STAT
) {
551 * Enter Wifi-Display status, reset all throttling. Dont affect the performance of Wifi-Display.
556 throttling_pre_stat
= WFD_STAT
;
557 wmt_tm_printk("WFD is on, reset everything!");
562 if (throttling_pre_stat
< HIGH_STAT
|| throttling_pre_stat
== WFD_STAT
) {
563 if (cur_thro
> 0) /*Wifi is working!! */
565 thro(cur_thro
, up_numerator
, up_denominator
);
566 else /*At this moment, current throughput is none. Use the previous constraint. */
568 thro(thro_constraint
, up_numerator
, up_denominator
);
570 wmt_tm_print("LOW/MID-->HIGH:%lu <- (%d / %d) %lu", thro_constraint
,
571 up_numerator
, up_denominator
, cur_thro
);
573 wmt_send_signal(thro_constraint
/ 1000);
574 throttling_pre_stat
= HIGH_STAT
;
576 } else if (throttling_pre_stat
== HIGH_STAT
) {
578 if ((over_up_time
* interval
) >= up_duration
) {
579 if (cur_thro
< thro_constraint
) /*real throughput may have huge variant */
581 thro(cur_thro
, up_numerator
, up_denominator
);
582 else /* current throughput is large than constraint. WHAT!!! */
584 thro(thro_constraint
, up_numerator
,
587 wmt_tm_printk("HIGH-->HIGH:%lu <- (%d / %d) %lu",
588 thro_constraint
, up_numerator
, up_denominator
,
591 wmt_send_signal(thro_constraint
/ 1000);
595 wmt_tm_info("[%s] Error state1!!\n", __func__
, throttling_pre_stat
);
597 wmt_tm_printk("case2 time=%d\n", over_up_time
);
601 if (throttling_pre_stat
== LOW_STAT
) {
603 throttling_pre_stat
= MID_STAT
;
604 wmt_tm_printk("[%s] Go up!!\n", __func__
);
605 } else if (throttling_pre_stat
== HIGH_STAT
) {
607 throttling_pre_stat
= MID_STAT
;
608 wmt_tm_printk("[%s] Go down!!\n", __func__
);
610 throttling_pre_stat
= MID_STAT
;
611 wmt_tm_dprintk("[%s] pre_stat=%d!!\n", __func__
,
612 throttling_pre_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) {
626 thro(cur_thro
, low_numerator
, low_denominator
);
629 thro(thro_constraint
, low_numerator
, low_denominator
);
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
;
639 } else if (throttling_pre_stat
== LOW_STAT
) {
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
);
645 wmt_send_signal(-1); /* reset */
646 low_rst_time
= low_rst_max
;
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) {
653 thro(cur_thro
, low_numerator
,
658 thro(thro_constraint
, low_numerator
,
663 wmt_tm_printk("LOW-->LOW:%lu <-(%d / %d) %lu",
664 thro_constraint
, low_numerator
,
665 low_denominator
, cur_thro
);
667 wmt_send_signal(thro_constraint
/ 1000);
670 wmt_tm_dprintk("Have reset, no control!!");
674 wmt_tm_info("[%s] Error state3 %d!!\n", __func__
,
675 throttling_pre_stat
);
677 wmt_tm_dprintk("case0 time=%d, rst=%d %d\n", below_low_time
, low_rst_time
,
682 wmt_tm_info("[%s] Error cur_wifi_stat=%d!!\n", __func__
, cur_wifi_stat
);
686 mail_box
[0] = UNK_STAT
;
687 mail_box
[1] = UNK_STAT
;
689 wmt_tm_dprintk("[%s] dont get all info!!\n", __func__
);
694 /* +mtktspa_cooling_pa1_ops+ */
695 static int wmt_cl_pa1_get_max_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
698 wmt_tm_dprintk("[%s] %d\n", __func__
, *pv
);
702 static int wmt_cl_pa1_get_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
704 *pv
= cl_pa1_dev_state
;
705 wmt_tm_dprint("[%s] %d\n", __func__
, *pv
);
709 static int wmt_cl_pa1_set_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long v
)
711 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
714 wmt_tm_dprint("[%s] %d\n", __func__
, v
);
717 p_linux_if
= &pg_wmt_tm
->linux_if
;
722 cl_pa1_dev_state
= (unsigned int)v
;
724 if (cl_pa1_dev_state
== 1) {
725 ret
= wmt_judge_throttling(0, 1, p_linux_if
->interval
/ 1000);
727 ret
= wmt_judge_throttling(0, 0, p_linux_if
->interval
/ 1000);
730 wmt_tm_info("[%s] ret=%d\n", __func__
, ret
);
734 /* -mtktspa_cooling_pa1_ops- */
736 /* +mtktspa_cooling_pa2_ops+ */
737 static int wmt_cl_pa2_get_max_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
740 wmt_tm_dprint("[%s] %d\n", __func__
, *pv
);
744 static int wmt_cl_pa2_get_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
746 *pv
= cl_pa2_dev_state
;
747 wmt_tm_dprint("[%s] %d\n", __func__
, *pv
);
751 static int wmt_cl_pa2_set_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long v
)
753 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
756 wmt_tm_dprintk("[%s] %d\n", __func__
, v
);
759 p_linux_if
= &pg_wmt_tm
->linux_if
;
764 cl_pa2_dev_state
= (unsigned int)v
;
766 if (cl_pa2_dev_state
== 1) {
767 ret
= wmt_judge_throttling(1, 1, p_linux_if
->interval
/ 1000);
769 ret
= wmt_judge_throttling(1, 0, p_linux_if
->interval
/ 1000);
772 wmt_tm_info("[%s] ret=%d\n", __func__
, ret
);
776 /* -mtktspa_cooling_pa2_ops- */
779 /* +mtktspa_cooling_pa3_ops+ */
780 static int wmt_cl_pa3_get_max_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
783 wmt_tm_dprintk("[%s] %d\n", __func__
, *pv
);
787 static int wmt_cl_pa3_get_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long *pv
)
789 *pv
= cl_pa3_dev_state
;
790 wmt_tm_dprintk("[%s] %d\n", __func__
, *pv
);
794 static int wmt_cl_pa3_set_cur_state(struct thermal_cooling_device
*cool_dev
, unsigned long v
)
796 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
799 wmt_tm_dprintk("[%s] %d\n", __func__
, v
);
802 p_linux_if
= &pg_wmt_tm
->linux_if
;
807 cl_pa3_dev_state
= (unsigned int)v
;
809 if (cl_pa3_dev_state
== 1) {
810 /* ret = wmt_arbitrate_thro(2,3); */
812 /* ret = wmt_arbitrate_thro(2,0); */
815 wmt_tm_print("[%s] ret=%d\n", __func__
, ret
);
819 /* -mtktspa_cooling_pa3_ops- */
822 int wmt_wifi_tx_thro_read(char *buf
, char **start
, off_t offset
, int count
, int *eof
, void *data
)
824 count
= sprintf(buf
, "%lu\n", tx_throughput
);
826 wmt_tm_dprintk("[%s] tx=%lu\n", __func__
, tx_throughput
);
831 /*New Wifi throttling Algo+*/
832 ssize_t
wmt_wifi_algo_write(struct file
*filp
, const char __user
*buf
, unsigned long len
,
835 char desc
[MAX_LEN
] = { 0 };
837 unsigned int tmp_up_dur
= 30;
838 unsigned int tmp_up_den
= 2;
839 unsigned int tmp_up_num
= 1;
841 unsigned int tmp_low_dur
= 3;
842 unsigned int tmp_low_den
= 2;
843 unsigned int tmp_low_num
= 3;
845 unsigned int tmp_low_rst_max
= 3;
847 unsigned int tmp_log
= 0;
849 len
= (len
< (sizeof(desc
) - 1)) ? len
: (sizeof(desc
) - 1);
851 /* write data to the buffer */
852 if (copy_from_user(desc
, buf
, len
)) {
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) {
860 up_duration
= tmp_up_dur
;
861 up_denominator
= tmp_up_den
;
862 up_numerator
= tmp_up_num
;
864 low_duration
= tmp_low_dur
;
865 low_denominator
= tmp_low_den
;
866 low_numerator
= tmp_low_num
;
868 low_rst_max
= tmp_low_rst_max
;
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
);
879 } else if (sscanf(desc
, "log=%d", &tmp_log
) == 1) {
881 wmt_tm_debug_log
= 1;
883 wmt_tm_debug_log
= 0;
887 wmt_tm_printk("[%s] bad argument = %s\n", __func__
, desc
);
892 int wmt_wifi_algo_read(char *buf
, char **start
, off_t offset
, int count
, int *eof
, void *data
)
895 char tmp
[MAX_LEN
] = { 0 };
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
,
902 memcpy(buf
, tmp
, ret
* sizeof(char));
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
,
911 /*New Wifi throttling Algo-*/
913 ssize_t
wmt_tm_wfd_write(struct file
*filp
, const char __user
*buf
, unsigned long len
, void *data
)
916 char tmp
[MAX_LEN
] = { 0 };
918 /* write data to the buffer */
919 if (copy_from_user(tmp
, buf
, len
)) {
923 ret
= sscanf(tmp
, "%d", &tm_wfd_stat
);
925 wmt_tm_printk("[%s] %s = %d, len=%d, ret=%d\n", __func__
, tmp
, tm_wfd_stat
, len
, ret
);
930 int wmt_tm_wfd_read(char *buf
, char **start
, off_t offset
, int count
, int *eof
, void *data
)
934 char tmp
[MAX_LEN
] = { 0 };
936 ret
= sprintf(tmp
, "%d", tm_wfd_stat
);
939 memcpy(buf
, tmp
, ret
* sizeof(char));
941 wmt_tm_printk("[%s] %s = %d, len=%d, ret=%d\n", __func__
, tmp
, tm_wfd_stat
, len
, ret
);
946 ssize_t
wmt_tm_pid_write(struct file
*filp
, const char __user
*buf
, unsigned long len
, void *data
)
949 char tmp
[MAX_LEN
] = { 0 };
951 /* write data to the buffer */
952 if (copy_from_user(tmp
, buf
, len
)) {
956 ret
= kstrtouint(tmp
, 10, &tm_input_pid
);
960 wmt_tm_printk("[%s] %s = %d\n", __func__
, tmp
, tm_input_pid
);
965 int wmt_tm_pid_read(char *buf
, char **start
, off_t offset
, int count
, int *eof
, void *data
)
968 char tmp
[MAX_LEN
] = { 0 };
970 sprintf(tmp
, "%d", tm_input_pid
);
973 memcpy(buf
, tmp
, ret
* sizeof(char));
975 wmt_tm_printk("[%s] %s = %d\n", __func__
, buf
, tm_input_pid
);
980 #define check_str(x) (x[0] == '\0'?"none\t":x)
982 static int wmt_tm_read(char *buf
, char **start
, off_t off
, int count
, int *eof
, void *data
)
986 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
988 wmt_tm_printk("[%s]\n", __func__
);
992 p_linux_if
= &pg_wmt_tm
->linux_if
;
994 wmt_tm_info("[wmt_tm_read] fail!\n");
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"
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
);
1028 return len
< count
? len
: count
;
1031 static ssize_t
wmt_tm_write(struct file
*file
, const char *buffer
, unsigned long count
, void *data
)
1034 int len
= 0, time_msec
= 0;
1035 int trip_temp
[COOLER_NUM
] = { 0 };
1036 int thermal_trip
[COOLER_NUM
] = { 0 };
1039 char bind0
[20], bind1
[20], bind2
[20], bind3
[20], bind4
[20];
1040 char bind5
[20], bind6
[20], bind7
[20], bind8
[20], bind9
[20];
1042 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
1044 wmt_tm_printk("[%s]\n", __func__
);
1048 p_linux_if
= &pg_wmt_tm
->linux_if
;
1050 wmt_tm_info("[wmt_thz_write] fail!\n");
1054 len
= (count
< (sizeof(desc
) - 1)) ? count
: (sizeof(desc
) - 1);
1056 if (copy_from_user(desc
, buffer
, len
)) {
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) {
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
;
1077 for (i
= 0; i
< g_num_trip
; i
++) {
1078 g_thermal_trip
[i
] = thermal_trip
[i
];
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';
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
];
1097 for (i
= 0; i
< g_num_trip
; i
++) {
1098 g_trip_temp
[i
] = trip_temp
[i
];
1101 p_linux_if
->interval
= time_msec
;
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]);
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]);
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
);
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
);
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]);
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]);
1123 wmt_tm_printk("[wmt_tm_write] polling time=%d\n", p_linux_if
->interval
);
1125 /* p_linux_if->thz_dev->polling_delay = p_linux_if->interval*1000; */
1127 /* thermal_zone_device_update(p_linux_if->thz_dev); */
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
);
1134 wmt_tm_printk("[wmt_tm_write] time_ms=%d\n", p_linux_if
->interval
);
1138 wmt_tm_info("[%s] bad argument = %s\n", __func__
, desc
);
1144 static int wmt_tm_proc_register(void)
1146 struct proc_dir_entry
*entry
= NULL
;
1147 struct proc_dir_entry
*wmt_tm_proc_dir
= NULL
;
1149 wmt_tm_printk("[%s]\n", __func__
);
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");
1156 create_proc_entry("wmt_tm", S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1159 entry
->read_proc
= wmt_tm_read
;
1160 entry
->write_proc
= wmt_tm_write
;
1164 create_proc_entry("tm_pid", S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1167 entry
->read_proc
= wmt_tm_pid_read
;
1168 entry
->write_proc
= wmt_tm_pid_write
;
1172 create_proc_entry("wmt_val", S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1175 entry
->read_proc
= wmt_wifi_algo_read
;
1176 entry
->write_proc
= wmt_wifi_algo_write
;
1179 entry
= create_proc_entry("tx_thro", S_IRUGO
| S_IWUSR
, wmt_tm_proc_dir
);
1181 entry
->read_proc
= wmt_wifi_tx_thro_read
;
1185 create_proc_entry("wfd_stat", S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1188 entry
->read_proc
= wmt_tm_wfd_read
;
1189 entry
->write_proc
= wmt_tm_wfd_write
;
1195 static int wmt_tm_proc_unregister(void)
1197 wmt_tm_printk("[%s]\n", __func__
);
1198 /* remove_proc_entry("wmt_tm", proc_entry); */
1202 static int wmt_tm_thz_cl_register(void)
1204 #define DEFAULT_POLL_TIME 0 /*Default disable, turn on by thermal policy */
1206 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
1208 wmt_tm_printk("[%s]\n", __func__
);
1211 p_linux_if
= &pg_wmt_tm
->linux_if
;
1216 /* cooling devices */
1217 p_linux_if
->cl_dev
= mtk_thermal_cooling_device_register("mtktswmt-sysrst", NULL
,
1218 &mtktspa_cooling_sysrst_ops
);
1220 p_linux_if
->cl_pa1_dev
= mtk_thermal_cooling_device_register("mtktswmt-pa1", NULL
,
1221 &mtktspa_cooling_pa1_ops
);
1223 p_linux_if
->cl_pa2_dev
= mtk_thermal_cooling_device_register("mtktswmt-pa2", NULL
,
1224 &mtktspa_cooling_pa2_ops
);
1227 p_linux_if
->cl_pa3_dev
= mtk_thermal_cooling_device_register("mtktswmt-pa3", NULL
,
1228 &mtktspa_cooling_pa3_ops
);
1231 p_linux_if
->interval
= DEFAULT_POLL_TIME
;
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
);
1241 static int wmt_tm_thz_cl_unregister(void)
1243 struct linux_thermal_ctrl_if
*p_linux_if
= 0;
1245 wmt_tm_printk("[%s]\n", __func__
);
1248 p_linux_if
= &pg_wmt_tm
->linux_if
;
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
;
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
;
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
;
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
;
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
;
1282 static int wmt_tm_ops_register(struct wmt_thermal_ctrl_ops
*ops
)
1284 struct wmt_thermal_ctrl_ops
*p_des
;
1286 wmt_tm_printk("[%s]\n", __func__
);
1290 p_des
= &pg_wmt_tm
->wmt_if
.ops
;
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");
1297 p_des
->query_temp
= 0;
1298 p_des
->set_temp
= 0;
1307 static int wmt_tm_ops_unregister(void)
1309 struct wmt_thermal_ctrl_ops
*p_des
;
1311 wmt_tm_printk("[%s]\n", __func__
);
1314 p_des
= &pg_wmt_tm
->wmt_if
.ops
;
1315 p_des
->query_temp
= 0;
1316 p_des
->set_temp
= 0;
1324 int wmt_tm_init(struct wmt_thermal_ctrl_ops
*ops
)
1328 wmt_tm_printk("[wmt_tm_init] start -->\n");
1330 err
= wmt_tm_ops_register(ops
);
1334 err
= wmt_tm_proc_register();
1338 /* init a timer for stats tx bytes */
1339 wmt_stats_info
.pre_time
= 0;
1340 wmt_stats_info
.pre_tx_bytes
= 0;
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
);
1349 err
= wmt_tm_thz_cl_register();
1353 wmt_tm_printk("[wmt_tm_init] end <--\n");
1358 int wmt_tm_init_rt(void)
1362 wmt_tm_printk("[wmt_tm_init_rt] start -->\n");
1364 err
= wmt_tm_thz_cl_register();
1368 wmt_tm_printk("[wmt_tm_init_rt] end <--\n");
1373 int wmt_tm_deinit_rt(void)
1377 wmt_tm_printk("[wmt_tm_deinit_rt] start -->\n");
1379 err
= wmt_tm_thz_cl_unregister();
1383 wmt_tm_printk("[wmt_tm_deinit_rt] end <--\n");
1388 int wmt_tm_deinit(void)
1392 wmt_tm_printk("[%s]\n", __func__
);
1394 err
= wmt_tm_thz_cl_unregister();
1398 err
= wmt_tm_proc_unregister();
1402 err
= wmt_tm_ops_unregister();
1406 del_timer(&wmt_stats_timer
);