mtk_ts_pa.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. #include <linux/version.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/dmi.h>
  5. #include <linux/acpi.h>
  6. #include <linux/thermal.h>
  7. #include <linux/platform_device.h>
  8. #include <mt-plat/aee.h>
  9. #include <linux/types.h>
  10. #include <linux/delay.h>
  11. #include <linux/proc_fs.h>
  12. #include <linux/syscalls.h>
  13. #include <linux/sched.h>
  14. #include <linux/writeback.h>
  15. #include <asm/uaccess.h>
  16. #include <asm/string.h>
  17. #include <linux/spinlock.h>
  18. #include "mt-plat/mtk_thermal_monitor.h"
  19. #include "mtk_thermal_typedefs.h"
  20. #include "mach/mt_thermal.h"
  21. #include "mt-plat/mtk_mdm_monitor.h"
  22. #include <linux/uidgid.h>
  23. #include <linux/slab.h>
  24. #include <mt_ts_setting.h>
  25. #if Feature_Thro_update
  26. /* For using net dev + */
  27. #include <linux/netdevice.h>
  28. /* For using net dev - */
  29. #include <linux/timer.h>
  30. #endif
  31. static kuid_t uid = KUIDT_INIT(0);
  32. static kgid_t gid = KGIDT_INIT(1000);
  33. static unsigned int interval; /* seconds, 0 : no auto polling */
  34. static unsigned int trip_temp[10] = { 85000, 80000, 70000, 60000, 50000, 40000, 30000, 20000, 10000, 5000 };
  35. static int g_THERMAL_TRIP[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  36. static unsigned int cl_dev_sysrst_state;
  37. static struct thermal_zone_device *thz_dev;
  38. static struct thermal_cooling_device *cl_dev_sysrst;
  39. static int mtktspa_debug_log;
  40. static int kernelmode;
  41. static int num_trip;
  42. static char g_bind0[20] = "mtktspa-sysrst";
  43. static char g_bind1[20] = { 0 };
  44. static char g_bind2[20] = { 0 };
  45. static char g_bind3[20] = { 0 };
  46. static char g_bind4[20] = { 0 };
  47. static char g_bind5[20] = { 0 };
  48. static char g_bind6[20] = { 0 };
  49. static char g_bind7[20] = { 0 };
  50. static char g_bind8[20] = { 0 };
  51. static char g_bind9[20] = { 0 };
  52. /**
  53. * If curr_temp >= polling_trip_temp1, use interval
  54. * else if cur_temp >= polling_trip_temp2 && curr_temp < polling_trip_temp1, use interval*polling_factor1
  55. * else, use interval*polling_factor2
  56. */
  57. static int polling_trip_temp1 = 40000;
  58. static int polling_trip_temp2 = 20000;
  59. static int polling_factor1 = 5000;
  60. static int polling_factor2 = 10000;
  61. #define mtktspa_TEMP_CRIT 85000 /* 85.000 degree Celsius */
  62. #define mtktspa_dprintk(fmt, args...) \
  63. do { \
  64. if (mtktspa_debug_log) { \
  65. pr_debug("[Power/PA_Thermal]" fmt, ##args); \
  66. } \
  67. } while (0)
  68. #if Feature_Thro_update
  69. struct pa_stats {
  70. unsigned long pre_time;
  71. unsigned long pre_tx_bytes;
  72. };
  73. static struct pa_stats pa_stats_info;
  74. static struct timer_list pa_stats_timer;
  75. static unsigned long pre_time;
  76. static unsigned long tx_throughput;
  77. static unsigned long get_tx_bytes(void)
  78. {
  79. struct net_device *dev;
  80. struct net *net;
  81. unsigned long tx_bytes = 0;
  82. read_lock(&dev_base_lock);
  83. for_each_net(net) {
  84. for_each_netdev(net, dev) {
  85. if (!strncmp(dev->name, "ccmni", 5)) {
  86. struct rtnl_link_stats64 temp;
  87. const struct rtnl_link_stats64 *stats = dev_get_stats(dev, &temp);
  88. /* mtktspa_dprintk("%s tx_bytes: %lu\n", dev->name, (unsigned long)stats->tx_bytes); */
  89. tx_bytes = tx_bytes + stats->tx_bytes;
  90. }
  91. }
  92. }
  93. read_unlock(&dev_base_lock);
  94. return tx_bytes;
  95. }
  96. static int pa_cal_stats(unsigned long data)
  97. {
  98. struct pa_stats *stats_info = (struct pa_stats *) data;
  99. struct timeval cur_time;
  100. mtktspa_dprintk("[%s] pre_time=%lu, pre_data=%lu\n", __func__, pre_time, stats_info->pre_tx_bytes);
  101. do_gettimeofday(&cur_time);
  102. if (pre_time != 0 && cur_time.tv_sec > pre_time) {
  103. unsigned long tx_bytes = get_tx_bytes();
  104. if (tx_bytes > stats_info->pre_tx_bytes) {
  105. tx_throughput = ((tx_bytes - stats_info->pre_tx_bytes) / (cur_time.tv_sec - pre_time)) >> 7;
  106. mtktspa_dprintk("[%s] cur_time=%lu, cur_data=%lu, tx_throughput=%luKb/s\n", __func__,
  107. cur_time.tv_sec, tx_bytes, tx_throughput);
  108. stats_info->pre_tx_bytes = tx_bytes;
  109. } else if (tx_bytes < stats_info->pre_tx_bytes) {
  110. /* Overflow */
  111. tx_throughput = ((0xffffffff - stats_info->pre_tx_bytes + tx_bytes)
  112. / (cur_time.tv_sec - pre_time)) >> 7;
  113. stats_info->pre_tx_bytes = tx_bytes;
  114. mtktspa_dprintk("[%s] cur_tx(%lu) < pre_tx\n", __func__, tx_bytes);
  115. } else {
  116. /* No traffic */
  117. tx_throughput = 0;
  118. mtktspa_dprintk("[%s] cur_tx(%lu) = pre_tx\n", __func__, tx_bytes);
  119. }
  120. } else {
  121. /* Overflow possible ??*/
  122. tx_throughput = 0;
  123. mtktspa_dprintk("[%s] cur_time(%lu) < pre_time\n", __func__, cur_time.tv_sec);
  124. }
  125. pre_time = cur_time.tv_sec;
  126. mtktspa_dprintk("[%s] pre_time=%lu, tv_sec=%lu\n", __func__, pre_time, cur_time.tv_sec);
  127. pa_stats_timer.expires = jiffies + 1 * HZ;
  128. add_timer(&pa_stats_timer);
  129. return 0;
  130. }
  131. #endif
  132. /*
  133. struct md_info{
  134. char *attribute;
  135. int value;
  136. char *unit;
  137. int invalid_value;
  138. int index;
  139. };
  140. struct md_info g_pinfo_list[] =
  141. {{"TXPWR_MD1", -127, "db", -127, 0},
  142. {"TXPWR_MD2", -127, "db", -127, 1},
  143. {"RFTEMP_2G_MD1", -32767, "¢XC", -32767, 2},
  144. {"RFTEMP_2G_MD2", -32767, "¢XC", -32767, 3},
  145. {"RFTEMP_3G_MD1", -32767, "¢XC", -32767, 4},
  146. {"RFTEMP_3G_MD2", -32767, "¢XC", -32767, 5}};
  147. */
  148. static DEFINE_MUTEX(TSPA_lock);
  149. static int mtktspa_get_hw_temp(void)
  150. {
  151. struct md_info *p_info;
  152. int size, i;
  153. mutex_lock(&TSPA_lock);
  154. mtk_mdm_get_md_info(&p_info, &size);
  155. for (i = 0; i < size; i++) {
  156. mtktspa_dprintk("PA temperature: name:%s, value:%d, invalid_value=%d\n",
  157. p_info[i].attribute, p_info[i].value, p_info[i].invalid_value);
  158. if (!strcmp(p_info[i].attribute, "RFTEMP_2G_MD1")) {
  159. mtktspa_dprintk("PA temperature: RFTEMP_2G_MD1\n");
  160. if (p_info[i].value != p_info[i].invalid_value)
  161. break;
  162. } else if (!strcmp(p_info[i].attribute, "RFTEMP_3G_MD1")) {
  163. mtktspa_dprintk("PA temperature: RFTEMP_3G_MD1\n");
  164. if (p_info[i].value != p_info[i].invalid_value)
  165. break;
  166. }
  167. }
  168. if (i == size) {
  169. mtktspa_dprintk("PA temperature: not ready\n");
  170. mutex_unlock(&TSPA_lock);
  171. return -127000;
  172. }
  173. mtktspa_dprintk("PA temperature: %d\n", p_info[i].value);
  174. if ((p_info[i].value > 100000) || (p_info[i].value < -30000))
  175. pr_debug("[Power/PA_Thermal] PA T=%d\n", p_info[i].value);
  176. mutex_unlock(&TSPA_lock);
  177. return p_info[i].value;
  178. }
  179. static int mtktspa_get_temp(struct thermal_zone_device *thermal, unsigned long *t)
  180. {
  181. *t = mtktspa_get_hw_temp();
  182. if ((int)*t >= polling_trip_temp1)
  183. thermal->polling_delay = interval * 1000;
  184. else if ((int)*t < polling_trip_temp2)
  185. thermal->polling_delay = interval * polling_factor2;
  186. else
  187. thermal->polling_delay = interval * polling_factor1;
  188. return 0;
  189. }
  190. static int mtktspa_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
  191. {
  192. int table_val = 0;
  193. if (!strcmp(cdev->type, g_bind0)) {
  194. table_val = 0;
  195. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  196. } else if (!strcmp(cdev->type, g_bind1)) {
  197. table_val = 1;
  198. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  199. } else if (!strcmp(cdev->type, g_bind2)) {
  200. table_val = 2;
  201. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  202. } else if (!strcmp(cdev->type, g_bind3)) {
  203. table_val = 3;
  204. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  205. } else if (!strcmp(cdev->type, g_bind4)) {
  206. table_val = 4;
  207. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  208. } else if (!strcmp(cdev->type, g_bind5)) {
  209. table_val = 5;
  210. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  211. } else if (!strcmp(cdev->type, g_bind6)) {
  212. table_val = 6;
  213. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  214. } else if (!strcmp(cdev->type, g_bind7)) {
  215. table_val = 7;
  216. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  217. } else if (!strcmp(cdev->type, g_bind8)) {
  218. table_val = 8;
  219. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  220. } else if (!strcmp(cdev->type, g_bind9)) {
  221. table_val = 9;
  222. mtktspa_dprintk("[mtktspa_bind] %s\n", cdev->type);
  223. } else
  224. return 0;
  225. if (mtk_thermal_zone_bind_cooling_device(thermal, table_val, cdev)) {
  226. mtktspa_dprintk("[mtktspa_bind] error binding cooling dev\n");
  227. return -EINVAL;
  228. }
  229. mtktspa_dprintk("[mtktspa_bind] binding OK\n");
  230. return 0;
  231. }
  232. static int mtktspa_unbind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
  233. {
  234. int table_val = 0;
  235. if (!strcmp(cdev->type, g_bind0)) {
  236. table_val = 0;
  237. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  238. } else if (!strcmp(cdev->type, g_bind1)) {
  239. table_val = 1;
  240. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  241. } else if (!strcmp(cdev->type, g_bind2)) {
  242. table_val = 2;
  243. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  244. } else if (!strcmp(cdev->type, g_bind3)) {
  245. table_val = 3;
  246. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  247. } else if (!strcmp(cdev->type, g_bind4)) {
  248. table_val = 4;
  249. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  250. } else if (!strcmp(cdev->type, g_bind5)) {
  251. table_val = 5;
  252. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  253. } else if (!strcmp(cdev->type, g_bind6)) {
  254. table_val = 6;
  255. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  256. } else if (!strcmp(cdev->type, g_bind7)) {
  257. table_val = 7;
  258. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  259. } else if (!strcmp(cdev->type, g_bind8)) {
  260. table_val = 8;
  261. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  262. } else if (!strcmp(cdev->type, g_bind9)) {
  263. table_val = 9;
  264. mtktspa_dprintk("[mtktspa_unbind] %s\n", cdev->type);
  265. } else
  266. return 0;
  267. if (thermal_zone_unbind_cooling_device(thermal, table_val, cdev)) {
  268. mtktspa_dprintk("[mtktspa_unbind] error unbinding cooling dev\n");
  269. return -EINVAL;
  270. }
  271. mtktspa_dprintk("[mtktspa_unbind] unbinding OK\n");
  272. return 0;
  273. }
  274. static int mtktspa_get_mode(struct thermal_zone_device *thermal, enum thermal_device_mode *mode)
  275. {
  276. *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED;
  277. return 0;
  278. }
  279. static int mtktspa_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode)
  280. {
  281. kernelmode = mode;
  282. return 0;
  283. }
  284. static int mtktspa_get_trip_type(struct thermal_zone_device *thermal, int trip,
  285. enum thermal_trip_type *type)
  286. {
  287. *type = g_THERMAL_TRIP[trip];
  288. return 0;
  289. }
  290. static int mtktspa_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp)
  291. {
  292. *temp = trip_temp[trip];
  293. return 0;
  294. }
  295. static int mtktspa_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temperature)
  296. {
  297. *temperature = mtktspa_TEMP_CRIT;
  298. return 0;
  299. }
  300. /* bind callback functions to thermalzone */
  301. static struct thermal_zone_device_ops mtktspa_dev_ops = {
  302. .bind = mtktspa_bind,
  303. .unbind = mtktspa_unbind,
  304. .get_temp = mtktspa_get_temp,
  305. .get_mode = mtktspa_get_mode,
  306. .set_mode = mtktspa_set_mode,
  307. .get_trip_type = mtktspa_get_trip_type,
  308. .get_trip_temp = mtktspa_get_trip_temp,
  309. .get_crit_temp = mtktspa_get_crit_temp,
  310. };
  311. /*
  312. * cooling device callback functions (mtktspa_cooling_sysrst_ops)
  313. * 1 : ON and 0 : OFF
  314. */
  315. static int tspa_sysrst_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state)
  316. {
  317. *state = 1;
  318. return 0;
  319. }
  320. static int tspa_sysrst_get_cur_state(struct thermal_cooling_device *cdev, unsigned long *state)
  321. {
  322. *state = cl_dev_sysrst_state;
  323. return 0;
  324. }
  325. static int tspa_sysrst_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
  326. {
  327. cl_dev_sysrst_state = state;
  328. if (cl_dev_sysrst_state == 1) {
  329. pr_debug("Power/PA_Thermal: reset, reset, reset!!!");
  330. pr_debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
  331. pr_debug("*****************************************");
  332. pr_debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
  333. /* BUG(); */
  334. *(unsigned int *)0x0 = 0xdead; /* To trigger data abort to reset the system for thermal protection. */
  335. /* arch_reset(0,NULL); */
  336. }
  337. return 0;
  338. }
  339. /* bind fan callbacks to fan device */
  340. static struct thermal_cooling_device_ops mtktspa_cooling_sysrst_ops = {
  341. .get_max_state = tspa_sysrst_get_max_state,
  342. .get_cur_state = tspa_sysrst_get_cur_state,
  343. .set_cur_state = tspa_sysrst_set_cur_state,
  344. };
  345. static int mtktspa_register_thermal(void);
  346. static void mtktspa_unregister_thermal(void);
  347. static int mtktspa_read(struct seq_file *m, void *v)
  348. {
  349. seq_printf(m, "[ mtktspa_read] trip_0_temp=%d,trip_1_temp=%d,trip_2_temp=%d,trip_3_temp=%d,trip_4_temp=%d,\n",
  350. trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3], trip_temp[4]);
  351. seq_printf(m, "trip_5_temp=%d,trip_6_temp=%d,trip_7_temp=%d,trip_8_temp=%d,trip_9_temp=%d,\n",
  352. trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8], trip_temp[9]);
  353. seq_printf(m, "g_THERMAL_TRIP_0=%d,g_THERMAL_TRIP_1=%d,g_THERMAL_TRIP_2=%d,g_THERMAL_TRIP_3=%d,\n",
  354. g_THERMAL_TRIP[0], g_THERMAL_TRIP[1], g_THERMAL_TRIP[2], g_THERMAL_TRIP[3]);
  355. seq_printf(m, "g_THERMAL_TRIP_4=%d,g_THERMAL_TRIP_5=%d,g_THERMAL_TRIP_6=%d,g_THERMAL_TRIP_7=%d,\n",
  356. g_THERMAL_TRIP[4], g_THERMAL_TRIP[5], g_THERMAL_TRIP[6], g_THERMAL_TRIP[7]);
  357. seq_printf(m, "g_THERMAL_TRIP_8=%d,g_THERMAL_TRIP_9=%d,\n", g_THERMAL_TRIP[8], g_THERMAL_TRIP[9]);
  358. seq_printf(m, "cooldev0=%s,cooldev1=%s,cooldev2=%s,cooldev3=%s,cooldev4=%s,\n",
  359. g_bind0, g_bind1, g_bind2, g_bind3, g_bind4);
  360. seq_printf(m, "cooldev5=%s,cooldev6=%s,cooldev7=%s,cooldev8=%s,cooldev9=%s,time_ms=%d\n",
  361. g_bind5, g_bind6, g_bind7, g_bind8, g_bind9, interval * 1000);
  362. return 0;
  363. }
  364. static ssize_t mtktspa_write(struct file *file, const char __user *buffer, size_t count,
  365. loff_t *data)
  366. {
  367. int len = 0;
  368. int i;
  369. struct mtktspa_data {
  370. int trip[10];
  371. int t_type[10];
  372. char bind0[20], bind1[20], bind2[20], bind3[20], bind4[20];
  373. char bind5[20], bind6[20], bind7[20], bind8[20], bind9[20];
  374. int time_msec;
  375. char desc[512];
  376. };
  377. struct mtktspa_data *ptr_mtktspa_data = kmalloc(sizeof(*ptr_mtktspa_data), GFP_KERNEL);
  378. if (ptr_mtktspa_data == NULL) {
  379. /* pr_debug("[%s] kmalloc fail\n\n", __func__); */
  380. return -ENOMEM;
  381. }
  382. len = (count < (sizeof(ptr_mtktspa_data->desc) - 1)) ? count : (sizeof(ptr_mtktspa_data->desc) - 1);
  383. if (copy_from_user(ptr_mtktspa_data->desc, buffer, len)) {
  384. kfree(ptr_mtktspa_data);
  385. return 0;
  386. }
  387. ptr_mtktspa_data->desc[len] = '\0';
  388. if (sscanf
  389. (ptr_mtktspa_data->desc,
  390. "%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",
  391. &num_trip, &ptr_mtktspa_data->trip[0], &ptr_mtktspa_data->t_type[0], ptr_mtktspa_data->bind0,
  392. &ptr_mtktspa_data->trip[1], &ptr_mtktspa_data->t_type[1], ptr_mtktspa_data->bind1,
  393. &ptr_mtktspa_data->trip[2], &ptr_mtktspa_data->t_type[2], ptr_mtktspa_data->bind2,
  394. &ptr_mtktspa_data->trip[3], &ptr_mtktspa_data->t_type[3], ptr_mtktspa_data->bind3,
  395. &ptr_mtktspa_data->trip[4], &ptr_mtktspa_data->t_type[4], ptr_mtktspa_data->bind4,
  396. &ptr_mtktspa_data->trip[5], &ptr_mtktspa_data->t_type[5], ptr_mtktspa_data->bind5,
  397. &ptr_mtktspa_data->trip[6], &ptr_mtktspa_data->t_type[6], ptr_mtktspa_data->bind6,
  398. &ptr_mtktspa_data->trip[7], &ptr_mtktspa_data->t_type[7], ptr_mtktspa_data->bind7,
  399. &ptr_mtktspa_data->trip[8], &ptr_mtktspa_data->t_type[8], ptr_mtktspa_data->bind8,
  400. &ptr_mtktspa_data->trip[9], &ptr_mtktspa_data->t_type[9], ptr_mtktspa_data->bind9,
  401. &ptr_mtktspa_data->time_msec) == 32) {
  402. mtktspa_dprintk("[mtktspa_write] mtktspa_unregister_thermal\n");
  403. mtktspa_unregister_thermal();
  404. if (num_trip < 0 || num_trip > 10) {
  405. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "mtktspa_write",
  406. "Bad argument");
  407. mtktspa_dprintk("[mtktspa_write] bad argument\n");
  408. kfree(ptr_mtktspa_data);
  409. return -EINVAL;
  410. }
  411. for (i = 0; i < num_trip; i++)
  412. g_THERMAL_TRIP[i] = ptr_mtktspa_data->t_type[i];
  413. g_bind0[0] = g_bind1[0] = g_bind2[0] = g_bind3[0] = g_bind4[0] = g_bind5[0] =
  414. g_bind6[0] = g_bind7[0] = g_bind8[0] = g_bind9[0] = '\0';
  415. for (i = 0; i < 20; i++) {
  416. g_bind0[i] = ptr_mtktspa_data->bind0[i];
  417. g_bind1[i] = ptr_mtktspa_data->bind1[i];
  418. g_bind2[i] = ptr_mtktspa_data->bind2[i];
  419. g_bind3[i] = ptr_mtktspa_data->bind3[i];
  420. g_bind4[i] = ptr_mtktspa_data->bind4[i];
  421. g_bind5[i] = ptr_mtktspa_data->bind5[i];
  422. g_bind6[i] = ptr_mtktspa_data->bind6[i];
  423. g_bind7[i] = ptr_mtktspa_data->bind7[i];
  424. g_bind8[i] = ptr_mtktspa_data->bind8[i];
  425. g_bind9[i] = ptr_mtktspa_data->bind9[i];
  426. }
  427. mtktspa_dprintk("[mtktspa_write] g_THERMAL_TRIP_0=%d,g_THERMAL_TRIP_1=%d,g_THERMAL_TRIP_2=%d,",
  428. g_THERMAL_TRIP[0], g_THERMAL_TRIP[1], g_THERMAL_TRIP[2]);
  429. mtktspa_dprintk("g_THERMAL_TRIP_3=%d,g_THERMAL_TRIP_4=%d,g_THERMAL_TRIP_5=%d,g_THERMAL_TRIP_6=%d,",
  430. g_THERMAL_TRIP[3], g_THERMAL_TRIP[4], g_THERMAL_TRIP[5], g_THERMAL_TRIP[6]);
  431. mtktspa_dprintk("g_THERMAL_TRIP_7=%d,g_THERMAL_TRIP_8=%d,g_THERMAL_TRIP_9=%d,\n",
  432. g_THERMAL_TRIP[7], g_THERMAL_TRIP[8], g_THERMAL_TRIP[9]);
  433. mtktspa_dprintk("[mtktspa_write] cooldev0=%s,cooldev1=%s,cooldev2=%s,cooldev3=%s,cooldev4=%s,",
  434. g_bind0, g_bind1, g_bind2, g_bind3, g_bind4);
  435. mtktspa_dprintk("cooldev5=%s,cooldev6=%s,cooldev7=%s,cooldev8=%s,cooldev9=%s\n",
  436. g_bind5, g_bind6, g_bind7, g_bind8, g_bind9);
  437. for (i = 0; i < num_trip; i++)
  438. trip_temp[i] = ptr_mtktspa_data->trip[i];
  439. interval = ptr_mtktspa_data->time_msec / 1000;
  440. mtktspa_dprintk("[mtktspa_write] trip_0_temp=%d,trip_1_temp=%d,trip_2_temp=%d,trip_3_temp=%d,",
  441. trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3]);
  442. mtktspa_dprintk("trip_4_temp=%d,trip_5_temp=%d,trip_6_temp=%d,trip_7_temp=%d,trip_8_temp=%d,",
  443. trip_temp[4], trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8]);
  444. mtktspa_dprintk("trip_9_temp=%d,time_ms=%d\n", trip_temp[9], interval * 1000);
  445. mtktspa_dprintk("[mtktspa_write] mtktspa_register_thermal\n");
  446. mtktspa_register_thermal();
  447. kfree(ptr_mtktspa_data);
  448. return count;
  449. }
  450. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "mtktspa_write",
  451. "Bad argument");
  452. mtktspa_dprintk("[mtktspa_write] bad argument\n");
  453. kfree(ptr_mtktspa_data);
  454. return -EINVAL;
  455. }
  456. static int mtktspa_open(struct inode *inode, struct file *file)
  457. {
  458. return single_open(file, mtktspa_read, NULL);
  459. }
  460. static const struct file_operations mtktspa_fops = {
  461. .owner = THIS_MODULE,
  462. .open = mtktspa_open,
  463. .read = seq_read,
  464. .llseek = seq_lseek,
  465. .write = mtktspa_write,
  466. .release = single_release,
  467. };
  468. #if Feature_Thro_update
  469. int pa_mobile_tx_thro_read(struct seq_file *m, void *v)
  470. {
  471. seq_printf(m, "%lu\n", tx_throughput);
  472. mtktspa_dprintk("[%s] tx=%lu\n", __func__, tx_throughput);
  473. return 0;
  474. }
  475. static int pa_mobile_tx_thro_open(struct inode *inode, struct file *file)
  476. {
  477. return single_open(file, pa_mobile_tx_thro_read, PDE_DATA(inode));
  478. }
  479. static const struct file_operations _tx_thro_fops = {
  480. .owner = THIS_MODULE,
  481. .open = pa_mobile_tx_thro_open,
  482. .read = seq_read,
  483. .llseek = seq_lseek,
  484. .release = single_release,
  485. };
  486. #endif
  487. void mtkts_pa_cancel_thermal_timer(void)
  488. {
  489. /* cancel timer */
  490. /* pr_debug("mtkts_pa_cancel_thermal_timer\n"); */
  491. /* stop thermal framework polling when entering deep idle */
  492. if (thz_dev)
  493. cancel_delayed_work(&(thz_dev->poll_queue));
  494. }
  495. void mtkts_pa_start_thermal_timer(void)
  496. {
  497. /* pr_debug("mtkts_pa_start_thermal_timer\n"); */
  498. /* resume thermal framework polling when leaving deep idle */
  499. if (thz_dev != NULL && interval != 0)
  500. mod_delayed_work(system_freezable_wq, &(thz_dev->poll_queue), round_jiffies(msecs_to_jiffies(3000)));
  501. }
  502. int mtktspa_register_cooler(void)
  503. {
  504. /* cooling devices */
  505. cl_dev_sysrst = mtk_thermal_cooling_device_register("mtktspa-sysrst", NULL,
  506. &mtktspa_cooling_sysrst_ops);
  507. return 0;
  508. }
  509. static int mtktspa_register_thermal(void)
  510. {
  511. mtktspa_dprintk("[mtktspa_register_thermal]\n");
  512. /* trips */
  513. thz_dev = mtk_thermal_zone_device_register("mtktspa", num_trip, NULL,
  514. &mtktspa_dev_ops, 0, 0, 0, interval * 1000);
  515. mtk_mdm_set_md1_signal_period(interval);
  516. return 0;
  517. }
  518. void mtktspa_unregister_cooler(void)
  519. {
  520. if (cl_dev_sysrst) {
  521. mtk_thermal_cooling_device_unregister(cl_dev_sysrst);
  522. cl_dev_sysrst = NULL;
  523. }
  524. }
  525. static void mtktspa_unregister_thermal(void)
  526. {
  527. mtktspa_dprintk("[mtktspa_unregister_thermal]\n");
  528. if (thz_dev) {
  529. mtk_thermal_zone_device_unregister(thz_dev);
  530. thz_dev = NULL;
  531. }
  532. }
  533. static int __init mtktspa_init(void)
  534. {
  535. int err = 0;
  536. struct proc_dir_entry *entry = NULL;
  537. struct proc_dir_entry *mtktspa_dir = NULL;
  538. #if Feature_Thro_update
  539. struct proc_dir_entry *mobile_thro_proc_dir = NULL;
  540. #endif
  541. mtktspa_dprintk("[%s]\n", __func__);
  542. err = mtktspa_register_cooler();
  543. if (err)
  544. return err;
  545. err = mtktspa_register_thermal();
  546. if (err)
  547. goto err_unreg;
  548. #if Feature_Thro_update
  549. mobile_thro_proc_dir = proc_mkdir("mobile_tm", NULL);
  550. if (!mobile_thro_proc_dir)
  551. mtktspa_dprintk("[mobile_tm_proc_register]: mkdir /proc/mobile_tm failed\n");
  552. else
  553. entry = proc_create("tx_thro", S_IRUGO | S_IWUSR, mobile_thro_proc_dir, &_tx_thro_fops);
  554. #endif
  555. mtktspa_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
  556. if (!mtktspa_dir) {
  557. mtktspa_dprintk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
  558. } else {
  559. entry =
  560. proc_create("tzpa", S_IRUGO | S_IWUSR | S_IWGRP, mtktspa_dir, &mtktspa_fops);
  561. if (entry)
  562. proc_set_user(entry, uid, gid);
  563. }
  564. #if Feature_Thro_update
  565. /* init a timer for stats tx bytes */
  566. pa_stats_info.pre_time = 0;
  567. pa_stats_info.pre_tx_bytes = 0;
  568. init_timer_deferrable(&pa_stats_timer);
  569. pa_stats_timer.function = (void *)&pa_cal_stats;
  570. pa_stats_timer.data = (unsigned long) &pa_stats_info;
  571. pa_stats_timer.expires = jiffies + 1 * HZ;
  572. add_timer(&pa_stats_timer);
  573. #endif
  574. return 0;
  575. err_unreg:
  576. mtktspa_unregister_cooler();
  577. return err;
  578. }
  579. static void __exit mtktspa_exit(void)
  580. {
  581. mtktspa_dprintk("[mtktspa_exit]\n");
  582. mtktspa_unregister_thermal();
  583. mtktspa_unregister_cooler();
  584. #if Feature_Thro_update
  585. del_timer(&pa_stats_timer);
  586. #endif
  587. }
  588. module_init(mtktspa_init);
  589. module_exit(mtktspa_exit);