mtk_ts2.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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/spinlock.h>
  13. #include <linux/seq_file.h>
  14. #include "mt-plat/mtk_thermal_monitor.h"
  15. #include "mtk_thermal_typedefs.h"
  16. #include "mach/mt_thermal.h"
  17. #include <linux/uidgid.h>
  18. #include <linux/slab.h>
  19. #define MTK_ALLTS_SW_FILTER (1)
  20. static kuid_t uid = KUIDT_INIT(0);
  21. static kgid_t gid = KGIDT_INIT(1000);
  22. static unsigned int interval = 1000; /* mseconds, 0 : no auto polling */
  23. static int trip_temp[10] = {120000, 110000, 100000, 90000, 80000,
  24. 70000, 65000, 60000, 55000, 50000};
  25. static struct thermal_zone_device *thz_dev;
  26. static int tsallts_debug_log;
  27. static int kernelmode;
  28. static int g_THERMAL_TRIP[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  29. static int num_trip;
  30. static char g_bind0[20] = { 0 };
  31. static char g_bind1[20] = { 0 };
  32. static char g_bind2[20] = { 0 };
  33. static char g_bind3[20] = { 0 };
  34. static char g_bind4[20] = { 0 };
  35. static char g_bind5[20] = { 0 };
  36. static char g_bind6[20] = { 0 };
  37. static char g_bind7[20] = { 0 };
  38. static char g_bind8[20] = { 0 };
  39. static char g_bind9[20] = { 0 };
  40. #define TSALLTS_TEMP_CRIT 120000 /* 120.000 degree Celsius */
  41. #define tsallts_dprintk(fmt, args...) \
  42. do { \
  43. if (tsallts_debug_log) { \
  44. pr_debug("[Power/ALLTS_Thermal]" fmt, ##args);\
  45. } \
  46. } while (0)
  47. #define tsallts_printk(fmt, args...) \
  48. pr_debug("[Power/ALLTS_Thermal]" fmt, ##args)
  49. int mtkts_get_ts2_temp(void)
  50. {
  51. if (thz_dev)
  52. return thz_dev->temperature;
  53. else
  54. return -127000;
  55. }
  56. static int tsallts_get_temp(struct thermal_zone_device *thermal, unsigned long *t)
  57. {
  58. #if MTK_ALLTS_SW_FILTER == 1
  59. int curr_temp;
  60. int temp_temp;
  61. int ret = 0;
  62. static int last_abb_read_temp;
  63. curr_temp = get_immediate_ts2_wrap();
  64. tsallts_dprintk("tsallts_get_temp CPU ts2 =%d\n", curr_temp);
  65. /* abnormal high temp */
  66. if ((curr_temp > (trip_temp[0] - 15000)) || (curr_temp < -30000) || (curr_temp > 85000))
  67. tsallts_printk("ts2 =%d\n", curr_temp);
  68. temp_temp = curr_temp;
  69. if (curr_temp != 0) {/* not the first temp read after resume from suspension */
  70. if ((curr_temp > 150000) || (curr_temp < -20000)) { /* invalid range */
  71. tsallts_printk("ts2 temp invalid=%d\n", curr_temp);
  72. temp_temp = 50000;
  73. ret = -1;
  74. } else if (last_abb_read_temp != 0) {
  75. /* delta 20C, invalid change */
  76. if ((curr_temp - last_abb_read_temp > 20000) || (last_abb_read_temp - curr_temp > 20000)) {
  77. tsallts_printk("ts2 temp float hugely temp=%d, lasttemp=%d\n",
  78. curr_temp, last_abb_read_temp);
  79. temp_temp = 50000;
  80. ret = -1;
  81. }
  82. }
  83. }
  84. last_abb_read_temp = curr_temp;
  85. curr_temp = temp_temp;
  86. *t = (unsigned long)curr_temp;
  87. return ret;
  88. #else
  89. int curr_temp;
  90. curr_temp = get_immediate_ts2_wrap();
  91. tsallts_dprintk("tsallts_get_temp ts2 =%d\n", curr_temp);
  92. if ((curr_temp > (trip_temp[0] - 15000)) || (curr_temp < -30000))
  93. tsallts_printk("ts2 =%d\n", curr_temp);
  94. *t = curr_temp;
  95. return 0;
  96. #endif
  97. }
  98. static int tsallts_bind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
  99. {
  100. int table_val = 0;
  101. tsallts_dprintk("[tsallts_bind]\n");
  102. if (!strcmp(cdev->type, g_bind0)) {
  103. table_val = 0;
  104. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  105. } else if (!strcmp(cdev->type, g_bind1)) {
  106. table_val = 1;
  107. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  108. } else if (!strcmp(cdev->type, g_bind2)) {
  109. table_val = 2;
  110. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  111. } else if (!strcmp(cdev->type, g_bind3)) {
  112. table_val = 3;
  113. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  114. } else if (!strcmp(cdev->type, g_bind4)) {
  115. table_val = 4;
  116. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  117. } else if (!strcmp(cdev->type, g_bind5)) {
  118. table_val = 5;
  119. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  120. } else if (!strcmp(cdev->type, g_bind6)) {
  121. table_val = 6;
  122. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  123. } else if (!strcmp(cdev->type, g_bind7)) {
  124. table_val = 7;
  125. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  126. } else if (!strcmp(cdev->type, g_bind8)) {
  127. table_val = 8;
  128. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  129. } else if (!strcmp(cdev->type, g_bind9)) {
  130. table_val = 9;
  131. tsallts_dprintk("[tsallts_bind] %s\n", cdev->type);
  132. } else {
  133. return 0;
  134. }
  135. if (mtk_thermal_zone_bind_cooling_device(thermal, table_val, cdev)) {
  136. tsallts_dprintk("[tsallts_bind_ts2] error binding cooling dev\n");
  137. return -EINVAL;
  138. }
  139. tsallts_dprintk("[tsallts_bind_ts2] binding OK, %d\n", table_val);
  140. return 0;
  141. }
  142. static int tsallts_unbind(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev)
  143. {
  144. int table_val = 0;
  145. tsallts_dprintk("[tsallts_unbind_ts2]\n");
  146. if (!strcmp(cdev->type, g_bind0)) {
  147. table_val = 0;
  148. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  149. } else if (!strcmp(cdev->type, g_bind1)) {
  150. table_val = 1;
  151. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  152. } else if (!strcmp(cdev->type, g_bind2)) {
  153. table_val = 2;
  154. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  155. } else if (!strcmp(cdev->type, g_bind3)) {
  156. table_val = 3;
  157. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  158. } else if (!strcmp(cdev->type, g_bind4)) {
  159. table_val = 4;
  160. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  161. } else if (!strcmp(cdev->type, g_bind5)) {
  162. table_val = 5;
  163. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  164. } else if (!strcmp(cdev->type, g_bind6)) {
  165. table_val = 6;
  166. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  167. } else if (!strcmp(cdev->type, g_bind7)) {
  168. table_val = 7;
  169. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  170. } else if (!strcmp(cdev->type, g_bind8)) {
  171. table_val = 8;
  172. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  173. } else if (!strcmp(cdev->type, g_bind9)) {
  174. table_val = 9;
  175. tsallts_dprintk("[tsallts_unbind] %s\n", cdev->type);
  176. } else
  177. return 0;
  178. if (thermal_zone_unbind_cooling_device(thermal, table_val, cdev)) {
  179. tsallts_dprintk("[tsallts_unbind_ts2] error unbinding cooling dev\n");
  180. return -EINVAL;
  181. }
  182. tsallts_dprintk("[tsallts_unbind_ts2] unbinding OK\n");
  183. return 0;
  184. }
  185. static int tsallts_get_mode(struct thermal_zone_device *thermal, enum thermal_device_mode *mode)
  186. {
  187. *mode = (kernelmode) ? THERMAL_DEVICE_ENABLED : THERMAL_DEVICE_DISABLED;
  188. return 0;
  189. }
  190. static int tsallts_set_mode(struct thermal_zone_device *thermal, enum thermal_device_mode mode)
  191. {
  192. kernelmode = mode;
  193. return 0;
  194. }
  195. static int tsallts_get_trip_type(struct thermal_zone_device *thermal, int trip,
  196. enum thermal_trip_type *type)
  197. {
  198. *type = g_THERMAL_TRIP[trip];
  199. return 0;
  200. }
  201. static int tsallts_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp)
  202. {
  203. *temp = trip_temp[trip];
  204. return 0;
  205. }
  206. static int tsallts_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temperature)
  207. {
  208. *temperature = TSALLTS_TEMP_CRIT;
  209. return 0;
  210. }
  211. void mtkts_allts_cancel_ts2_timer(void)
  212. {
  213. if (thz_dev)
  214. cancel_delayed_work(&(thz_dev->poll_queue));
  215. }
  216. void mtkts_allts_start_ts2_timer(void)
  217. {
  218. if (thz_dev != NULL && interval != 0)
  219. mod_delayed_work(system_freezable_wq, &(thz_dev->poll_queue), round_jiffies(msecs_to_jiffies(1000)));
  220. /*1000 = 1sec */
  221. }
  222. /* bind callback functions to thermalzone */
  223. static struct thermal_zone_device_ops tsallts_dev_ops = {
  224. .bind = tsallts_bind,
  225. .unbind = tsallts_unbind,
  226. .get_temp = tsallts_get_temp,
  227. .get_mode = tsallts_get_mode,
  228. .set_mode = tsallts_set_mode,
  229. .get_trip_type = tsallts_get_trip_type,
  230. .get_trip_temp = tsallts_get_trip_temp,
  231. .get_crit_temp = tsallts_get_crit_temp,
  232. };
  233. static int tsallts_read(struct seq_file *m, void *v)
  234. {
  235. seq_printf(m, "[ tsallts_read_ts2] trip_0_temp=%d,trip_1_temp=%d,trip_2_temp=%d,trip_3_temp=%d,\n",
  236. trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3]);
  237. seq_printf(m, "trip_4_temp=%d,trip_5_temp=%d,trip_6_temp=%d,trip_7_temp=%d,trip_8_temp=%d,trip_9_temp=%d,\n",
  238. trip_temp[4], trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8], trip_temp[9]);
  239. seq_printf(m, "g_THERMAL_TRIP_0=%d,g_THERMAL_TRIP_1=%d,g_THERMAL_TRIP_2=%d,g_THERMAL_TRIP_3=%d,\n",
  240. g_THERMAL_TRIP[0], g_THERMAL_TRIP[1], g_THERMAL_TRIP[2], g_THERMAL_TRIP[3]);
  241. seq_printf(m, "g_THERMAL_TRIP_4=%d,g_THERMAL_TRIP_5=%d,g_THERMAL_TRIP_6=%d,g_THERMAL_TRIP_7=%d,\n",
  242. g_THERMAL_TRIP[4], g_THERMAL_TRIP[5], g_THERMAL_TRIP[6], g_THERMAL_TRIP[7]);
  243. seq_printf(m, "g_THERMAL_TRIP_8=%d,g_THERMAL_TRIP_9=%d,\n", g_THERMAL_TRIP[8], g_THERMAL_TRIP[9]);
  244. seq_printf(m, "cooldev0=%s,cooldev1=%s,cooldev2=%s,cooldev3=%s,cooldev4=%s,\n",
  245. g_bind0, g_bind1, g_bind2, g_bind3, g_bind4);
  246. seq_printf(m, "cooldev5=%s,cooldev6=%s,cooldev7=%s,cooldev8=%s,cooldev9=%s,time_ms=%d\n",
  247. g_bind5, g_bind6, g_bind7, g_bind8, g_bind9, interval);
  248. return 0;
  249. }
  250. static ssize_t tsallts_write(struct file *file, const char __user *buffer, size_t count,
  251. loff_t *data)
  252. {
  253. int len = 0, i;
  254. struct temp_data {
  255. int trip[10];
  256. int t_type[10];
  257. char bind0[20], bind1[20], bind2[20], bind3[20], bind4[20];
  258. char bind5[20], bind6[20], bind7[20], bind8[20], bind9[20];
  259. int time_msec;
  260. char desc[512];
  261. };
  262. struct temp_data *ptr_temp_data = kmalloc(sizeof(*ptr_temp_data), GFP_KERNEL);
  263. tsallts_printk("[tsallts_write_ts2]\n");
  264. if (ptr_temp_data == NULL) {
  265. pr_warn("[%s] kmalloc fail\n\n", __func__);
  266. return -ENOMEM;
  267. }
  268. len = (count < (sizeof(ptr_temp_data->desc) - 1)) ? count : (sizeof(ptr_temp_data->desc) - 1);
  269. if (copy_from_user(ptr_temp_data->desc, buffer, len)) {
  270. kfree(ptr_temp_data);
  271. return 0;
  272. }
  273. ptr_temp_data->desc[len] = '\0';
  274. if (sscanf
  275. (ptr_temp_data->desc,
  276. "%d %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d %d %19s %d",
  277. &num_trip,
  278. &ptr_temp_data->trip[0], &ptr_temp_data->t_type[0], ptr_temp_data->bind0,
  279. &ptr_temp_data->trip[1], &ptr_temp_data->t_type[1], ptr_temp_data->bind1,
  280. &ptr_temp_data->trip[2], &ptr_temp_data->t_type[2], ptr_temp_data->bind2,
  281. &ptr_temp_data->trip[3], &ptr_temp_data->t_type[3], ptr_temp_data->bind3,
  282. &ptr_temp_data->trip[4], &ptr_temp_data->t_type[4], ptr_temp_data->bind4,
  283. &ptr_temp_data->trip[5], &ptr_temp_data->t_type[5], ptr_temp_data->bind5,
  284. &ptr_temp_data->trip[6], &ptr_temp_data->t_type[6], ptr_temp_data->bind6,
  285. &ptr_temp_data->trip[7], &ptr_temp_data->t_type[7], ptr_temp_data->bind7,
  286. &ptr_temp_data->trip[8], &ptr_temp_data->t_type[8], ptr_temp_data->bind8,
  287. &ptr_temp_data->trip[9], &ptr_temp_data->t_type[9], ptr_temp_data->bind9,
  288. &ptr_temp_data->time_msec) == 32) {
  289. tsallts_dprintk("[tsallts_write_ts2] tsallts_unregister_thermal\n");
  290. if (thz_dev) {
  291. mtk_thermal_zone_device_unregister(thz_dev);
  292. thz_dev = NULL;
  293. }
  294. if (num_trip < 0 || num_trip > 10) {
  295. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "tsallts_write2",
  296. "Bad argument");
  297. tsallts_dprintk("[tsallts_write2] bad argument\n");
  298. kfree(ptr_temp_data);
  299. return -EINVAL;
  300. }
  301. for (i = 0; i < num_trip; i++)
  302. g_THERMAL_TRIP[i] = ptr_temp_data->t_type[i];
  303. g_bind0[0] = g_bind1[0] = g_bind2[0] = g_bind3[0] = g_bind4[0] = g_bind5[0] =
  304. g_bind6[0] = g_bind7[0] = g_bind8[0] = g_bind9[0] = '\0';
  305. for (i = 0; i < 20; i++) {
  306. g_bind0[i] = ptr_temp_data->bind0[i];
  307. g_bind1[i] = ptr_temp_data->bind1[i];
  308. g_bind2[i] = ptr_temp_data->bind2[i];
  309. g_bind3[i] = ptr_temp_data->bind3[i];
  310. g_bind4[i] = ptr_temp_data->bind4[i];
  311. g_bind5[i] = ptr_temp_data->bind5[i];
  312. g_bind6[i] = ptr_temp_data->bind6[i];
  313. g_bind7[i] = ptr_temp_data->bind7[i];
  314. g_bind8[i] = ptr_temp_data->bind8[i];
  315. g_bind9[i] = ptr_temp_data->bind9[i];
  316. }
  317. tsallts_dprintk("[tsallts_write1] g_THERMAL_TRIP_0=%d,g_THERMAL_TRIP_1=%d,g_THERMAL_TRIP_2=%d,",
  318. g_THERMAL_TRIP[0], g_THERMAL_TRIP[1], g_THERMAL_TRIP[2]);
  319. tsallts_dprintk("g_THERMAL_TRIP_3=%d,g_THERMAL_TRIP_4=%d,g_THERMAL_TRIP_5=%d,g_THERMAL_TRIP_6=%d,",
  320. g_THERMAL_TRIP[3], g_THERMAL_TRIP[4], g_THERMAL_TRIP[5], g_THERMAL_TRIP[6]);
  321. tsallts_dprintk("g_THERMAL_TRIP_7=%d,g_THERMAL_TRIP_8=%d,g_THERMAL_TRIP_9=%d,\n",
  322. g_THERMAL_TRIP[7], g_THERMAL_TRIP[8], g_THERMAL_TRIP[9]);
  323. tsallts_dprintk("[tsallts_write1] cooldev0=%s,cooldev1=%s,cooldev2=%s,cooldev3=%s,",
  324. g_bind0, g_bind1, g_bind2, g_bind3);
  325. tsallts_dprintk("cooldev4=%s,cooldev5=%s,cooldev6=%s,cooldev7=%s,cooldev8=%s,cooldev9=%s\n",
  326. g_bind4, g_bind5, g_bind6, g_bind7, g_bind8, g_bind9);
  327. for (i = 0; i < num_trip; i++)
  328. trip_temp[i] = ptr_temp_data->trip[i];
  329. interval = ptr_temp_data->time_msec;
  330. tsallts_dprintk("[tsallts_write] trip_0_temp=%d,trip_1_temp=%d,trip_2_temp=%d,trip_3_temp=%d,",
  331. trip_temp[0], trip_temp[1], trip_temp[2], trip_temp[3]);
  332. tsallts_dprintk("trip_4_temp=%d,trip_5_temp=%d,trip_6_temp=%d,trip_7_temp=%d,trip_8_temp=%d,",
  333. trip_temp[4], trip_temp[5], trip_temp[6], trip_temp[7], trip_temp[8]);
  334. tsallts_dprintk("trip_9_temp=%d,time_ms=%d\n", trip_temp[9], interval);
  335. tsallts_dprintk("[tsallts_write1] tsallts_register_thermal\n");
  336. if (NULL == thz_dev) {
  337. thz_dev = mtk_thermal_zone_device_register("mtkts2", num_trip, NULL,
  338. &tsallts_dev_ops, 0, 0, 0,
  339. interval);
  340. }
  341. kfree(ptr_temp_data);
  342. return count;
  343. }
  344. tsallts_dprintk("[tsallts_write1] bad argument\n");
  345. aee_kernel_warning_api(__FILE__, __LINE__, DB_OPT_DEFAULT, "tsallts_write2",
  346. "Bad argument");
  347. kfree(ptr_temp_data);
  348. return -EINVAL;
  349. }
  350. static int tsallts_open(struct inode *inode, struct file *file)
  351. {
  352. return single_open(file, tsallts_read, NULL);
  353. }
  354. static const struct file_operations tsallts_fops = {
  355. .owner = THIS_MODULE,
  356. .open = tsallts_open,
  357. .read = seq_read,
  358. .llseek = seq_lseek,
  359. .write = tsallts_write,
  360. .release = single_release,
  361. };
  362. static int __init tsallts_init(void)
  363. {
  364. struct proc_dir_entry *entry = NULL;
  365. struct proc_dir_entry *tsallts_dir = NULL;
  366. tsallts_dprintk("[tsallts_init] ts2\n");
  367. tsallts_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
  368. if (!tsallts_dir) {
  369. tsallts_dprintk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
  370. } else {
  371. entry =
  372. proc_create("tzts2", S_IRUGO | S_IWUSR | S_IWGRP, tsallts_dir, &tsallts_fops);
  373. if (entry)
  374. proc_set_user(entry, uid, gid);
  375. }
  376. return 0;
  377. }
  378. static void tsallts_unregister_thermal(void)
  379. {
  380. tsallts_dprintk("[tsallts_unregister_thermal]\n");
  381. if (thz_dev) {
  382. mtk_thermal_zone_device_unregister(thz_dev);
  383. thz_dev = NULL;
  384. }
  385. }
  386. static void __exit tsallts_exit(void)
  387. {
  388. tsallts_dprintk("[tsallts_exit] ts2\n");
  389. tsallts_unregister_thermal();
  390. }
  391. module_init(tsallts_init);
  392. module_exit(tsallts_exit);