mtk_cooler_amutt.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. #include <linux/version.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/types.h>
  5. #include <linux/kobject.h>
  6. #include <linux/proc_fs.h>
  7. #include <asm/uaccess.h>
  8. #include <linux/err.h>
  9. #include <linux/syscalls.h>
  10. #include <linux/timer.h>
  11. #include <mt_ccci_common.h>
  12. #include "mt-plat/mtk_thermal_monitor.h"
  13. #include <linux/uidgid.h>
  14. int __attribute__ ((weak))
  15. exec_ccci_kern_func_by_md_id(int md_id, unsigned int id, char *buf, unsigned int len)
  16. {
  17. pr_err("E_WF: %s doesn't exist\n", __func__);
  18. return -316;
  19. }
  20. #define cl_type_upper "cl-amutt-u"
  21. #define cl_type_lower "cl-amutt-l"
  22. #define mtk_cooler_amutt_dprintk_always(fmt, args...) \
  23. pr_debug("thermal/cooler/amutt" fmt, ##args)
  24. #define mtk_cooler_amutt_dprintk(fmt, args...) \
  25. do { \
  26. if (1 == cl_amutt_klog_on) { \
  27. pr_debug("[thermal/cooler/amutt]" fmt, ##args); \
  28. } \
  29. } while (0)
  30. static kuid_t uid = KUIDT_INIT(0);
  31. static kgid_t gid = KGIDT_INIT(1000);
  32. static int cl_amutt_klog_on;
  33. /* over_up_time * polling interval > up_duration --> throttling */
  34. static unsigned int over_up_time; /* polling time */
  35. static unsigned int up_duration = 30; /* sec */
  36. static unsigned int up_step = 1; /* step */
  37. /* below_low_time * polling interval > low_duration --> throttling */
  38. static unsigned int below_low_time; /* polling time */
  39. static unsigned int low_duration = 10; /* sec */
  40. static unsigned int low_step = 1; /* step */
  41. static unsigned int low_rst_time;
  42. static unsigned int low_rst_max = 3;
  43. /* static unsigned int deepest_step = 0; */
  44. static int polling_interval = 1; /* second */
  45. #define UNK_STAT -1
  46. #define LOW_STAT 0
  47. #define MID_STAT 1
  48. #define HIGH_STAT 2
  49. #define MAX_LEN 256
  50. #define COOLER_STEPS 5
  51. static unsigned int cl_upper_dev_state;
  52. static unsigned int cl_lower_dev_state;
  53. static struct thermal_cooling_device *cl_upper_dev;
  54. static struct thermal_cooling_device *cl_lower_dev;
  55. typedef int (*activate_cooler_opp_func) (int level);
  56. static activate_cooler_opp_func opp_func[COOLER_STEPS] = { 0 };
  57. static unsigned int amutt_param[COOLER_STEPS] = { 0 };
  58. typedef struct adaptive_cooler {
  59. int cur_level;
  60. int max_level;
  61. activate_cooler_opp_func *opp_func_array;
  62. } adaptive_coolers;
  63. static adaptive_coolers amutt;
  64. static int amutt_backoff(int level)
  65. {
  66. int ret;
  67. if (level == 0) {
  68. /* no throttle */
  69. ret =
  70. exec_ccci_kern_func_by_md_id(MD_SYS1, ID_THROTTLING_CFG,
  71. (char *)&amutt_param[level], 4);
  72. mtk_cooler_amutt_dprintk_always("[%s] unlimit\n", __func__);
  73. } else if (level >= 1 && level <= COOLER_STEPS - 1) {
  74. ret =
  75. exec_ccci_kern_func_by_md_id(MD_SYS1, ID_THROTTLING_CFG,
  76. (char *)&amutt_param[level], 4);
  77. mtk_cooler_amutt_dprintk_always("[%s] limit %x\n", __func__, amutt_param[level]);
  78. } else {
  79. /* error... */
  80. ret = -1;
  81. mtk_cooler_amutt_dprintk_always("[%s] ouf of range\n", __func__);
  82. }
  83. return ret;
  84. }
  85. static int down_throttle(adaptive_coolers *p, int step)
  86. {
  87. if (NULL == p)
  88. return -1;
  89. if (step <= 0)
  90. return p->cur_level;
  91. if (p->cur_level + step > p->max_level) {
  92. p->cur_level = p->max_level;
  93. p->opp_func_array[p->cur_level] (p->cur_level);
  94. return p->cur_level;
  95. }
  96. p->cur_level += step;
  97. p->opp_func_array[p->cur_level] (p->cur_level);
  98. return p->cur_level;
  99. }
  100. static int up_throttle(adaptive_coolers *p, int step)
  101. {
  102. if (NULL == p)
  103. return -1;
  104. if (step <= 0)
  105. return p->cur_level;
  106. if (p->cur_level - step < 0) {
  107. p->cur_level = 0;
  108. p->opp_func_array[p->cur_level] (p->cur_level);
  109. return p->cur_level;
  110. }
  111. p->cur_level -= step;
  112. p->opp_func_array[p->cur_level] (p->cur_level);
  113. return p->cur_level;
  114. }
  115. static int rst_throttle(adaptive_coolers *p)
  116. {
  117. if (NULL == p)
  118. return -1;
  119. p->cur_level = 0;
  120. p->opp_func_array[p->cur_level] (p->cur_level);
  121. return p->cur_level;
  122. }
  123. /* index --> 0, lower; 1, upper */
  124. /* is_on --> 0, off; 1, on */
  125. static int judge_throttling(int index, int is_on, int interval)
  126. {
  127. /*
  128. * throttling_stat
  129. * 2 ( upper=1,lower=1 )
  130. * UPPER ----
  131. * 1 ( upper=0,lower=1 )
  132. * LOWER ----
  133. * 0 ( upper=0,lower=0 )
  134. */
  135. static unsigned int throttling_pre_stat;
  136. static int mail_box[2] = { -1, -1 };
  137. static bool is_reset;
  138. /* unsigned long cur_thro = tx_throughput; */
  139. /* static unsigned long thro_constraint = 99 * 1000; */
  140. int cur_wifi_stat = 0;
  141. mtk_cooler_amutt_dprintk("[%s]+ [0]=%d, [1]=%d || [%d] is %s\n", __func__, mail_box[0],
  142. mail_box[1], index, (is_on == 1 ? "ON" : "OFF"));
  143. mail_box[index] = is_on;
  144. if (mail_box[0] >= 0 && mail_box[1] >= 0) {
  145. cur_wifi_stat = mail_box[0] + mail_box[1];
  146. switch (cur_wifi_stat) {
  147. case HIGH_STAT:
  148. if (throttling_pre_stat < HIGH_STAT) {
  149. /* 1st down throttle */
  150. int new_step = down_throttle(&amutt, up_step);
  151. mtk_cooler_amutt_dprintk_always("LOW/MID-->HIGH: step %d\n",
  152. new_step);
  153. throttling_pre_stat = HIGH_STAT;
  154. over_up_time = 0;
  155. } else if (throttling_pre_stat == HIGH_STAT) {
  156. /* keep down throttle */
  157. over_up_time++;
  158. if ((over_up_time * interval) >= up_duration) {
  159. int new_step = down_throttle(&amutt, up_step);
  160. mtk_cooler_amutt_dprintk_always("HIGH-->HIGH: step %d\n",
  161. new_step);
  162. over_up_time = 0;
  163. }
  164. } else {
  165. mtk_cooler_amutt_dprintk("[%s] Error state1=%d!!\n", __func__,
  166. throttling_pre_stat);
  167. }
  168. mtk_cooler_amutt_dprintk_always("case2 time=%d\n", over_up_time);
  169. break;
  170. case MID_STAT:
  171. if (throttling_pre_stat == LOW_STAT) {
  172. below_low_time = 0;
  173. throttling_pre_stat = MID_STAT;
  174. mtk_cooler_amutt_dprintk_always("[%s] Go up!!\n", __func__);
  175. } else if (throttling_pre_stat == HIGH_STAT) {
  176. over_up_time = 0;
  177. throttling_pre_stat = MID_STAT;
  178. mtk_cooler_amutt_dprintk_always("[%s] Go down!!\n", __func__);
  179. } else {
  180. throttling_pre_stat = MID_STAT;
  181. mtk_cooler_amutt_dprintk("[%s] pre_stat=%d!!\n", __func__,
  182. throttling_pre_stat);
  183. }
  184. break;
  185. case LOW_STAT:
  186. if (throttling_pre_stat > LOW_STAT) {
  187. /* 1st up throttle */
  188. int new_step = up_throttle(&amutt, low_step);
  189. mtk_cooler_amutt_dprintk_always("MID/HIGH-->LOW: step %d\n",
  190. new_step);
  191. throttling_pre_stat = LOW_STAT;
  192. below_low_time = 0;
  193. low_rst_time = 0;
  194. is_reset = false;
  195. } else if (throttling_pre_stat == LOW_STAT) {
  196. below_low_time++;
  197. if ((below_low_time * interval) >= low_duration) {
  198. if (low_rst_time >= low_rst_max && !is_reset) {
  199. /* rst */
  200. rst_throttle(&amutt);
  201. mtk_cooler_amutt_dprintk_always
  202. ("over rst time=%d\n", low_rst_time);
  203. low_rst_time = low_rst_max;
  204. is_reset = true;
  205. } else if (!is_reset) {
  206. /* keep up throttle */
  207. int new_step = up_throttle(&amutt, low_step);
  208. low_rst_time++;
  209. mtk_cooler_amutt_dprintk_always
  210. ("LOW-->LOW: step %d\n", new_step);
  211. below_low_time = 0;
  212. } else {
  213. mtk_cooler_amutt_dprintk
  214. ("Have reset, no control!!");
  215. }
  216. }
  217. } else {
  218. mtk_cooler_amutt_dprintk_always("[%s] Error state3 %d!!\n",
  219. __func__, throttling_pre_stat);
  220. }
  221. mtk_cooler_amutt_dprintk("case0 time=%d, rst=%d %d\n", below_low_time,
  222. low_rst_time, is_reset);
  223. break;
  224. default:
  225. mtk_cooler_amutt_dprintk_always("[%s] Error cur_wifi_stat=%d!!\n", __func__,
  226. cur_wifi_stat);
  227. break;
  228. }
  229. mail_box[0] = UNK_STAT;
  230. mail_box[1] = UNK_STAT;
  231. } else {
  232. mtk_cooler_amutt_dprintk("[%s] dont get all info!!\n", __func__);
  233. }
  234. return 0;
  235. }
  236. /* +amutt_cooler_upper_ops+ */
  237. static int amutt_cooler_upper_get_max_state(struct thermal_cooling_device *cool_dev,
  238. unsigned long *pv)
  239. {
  240. *pv = 1;
  241. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, *pv);
  242. return 0;
  243. }
  244. static int amutt_cooler_upper_get_cur_state(struct thermal_cooling_device *cool_dev,
  245. unsigned long *pv)
  246. {
  247. *pv = cl_upper_dev_state;
  248. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, *pv);
  249. return 0;
  250. }
  251. static int amutt_cooler_upper_set_cur_state(struct thermal_cooling_device *cool_dev,
  252. unsigned long v)
  253. {
  254. int ret = 0;
  255. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, v);
  256. cl_upper_dev_state = (unsigned int)v;
  257. if (cl_upper_dev_state == 1)
  258. ret = judge_throttling(1, 1, polling_interval);
  259. else
  260. ret = judge_throttling(1, 0, polling_interval);
  261. if (ret != 0)
  262. mtk_cooler_amutt_dprintk_always("[%s] ret=%d\n", __func__, ret);
  263. return ret;
  264. }
  265. static struct thermal_cooling_device_ops amutt_cooler_upper_ops = {
  266. .get_max_state = amutt_cooler_upper_get_max_state,
  267. .get_cur_state = amutt_cooler_upper_get_cur_state,
  268. .set_cur_state = amutt_cooler_upper_set_cur_state,
  269. };
  270. /* -amutt_cooler_upper_ops- */
  271. /* +amutt_cooler_lower_ops+ */
  272. static int amutt_cooler_lower_get_max_state(struct thermal_cooling_device *cool_dev,
  273. unsigned long *pv)
  274. {
  275. *pv = 1;
  276. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, *pv);
  277. return 0;
  278. }
  279. static int amutt_cooler_lower_get_cur_state(struct thermal_cooling_device *cool_dev,
  280. unsigned long *pv)
  281. {
  282. *pv = cl_lower_dev_state;
  283. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, *pv);
  284. return 0;
  285. }
  286. static int amutt_cooler_lower_set_cur_state(struct thermal_cooling_device *cool_dev,
  287. unsigned long v)
  288. {
  289. int ret = 0;
  290. mtk_cooler_amutt_dprintk("[%s] %lu\n", __func__, v);
  291. cl_lower_dev_state = (unsigned int)v;
  292. if (cl_lower_dev_state == 1)
  293. ret = judge_throttling(0, 1, polling_interval);
  294. else
  295. ret = judge_throttling(0, 0, polling_interval);
  296. if (ret != 0)
  297. mtk_cooler_amutt_dprintk_always("[%s] ret=%d\n", __func__, ret);
  298. return ret;
  299. }
  300. static struct thermal_cooling_device_ops amutt_cooler_lower_ops = {
  301. .get_max_state = amutt_cooler_lower_get_max_state,
  302. .get_cur_state = amutt_cooler_lower_get_cur_state,
  303. .set_cur_state = amutt_cooler_lower_set_cur_state,
  304. };
  305. /* -amutt_cooler_lower_ops- */
  306. static int mtk_cooler_amutt_register_ltf(void)
  307. {
  308. mtk_cooler_amutt_dprintk("[%s]\n", __func__);
  309. cl_upper_dev = mtk_thermal_cooling_device_register("cl-amutt-upper", NULL,
  310. &amutt_cooler_upper_ops);
  311. cl_lower_dev = mtk_thermal_cooling_device_register("cl-amutt-lower", NULL,
  312. &amutt_cooler_lower_ops);
  313. return 0;
  314. }
  315. static void mtk_cooler_amutt_unregister_ltf(void)
  316. {
  317. mtk_cooler_amutt_dprintk("[%s]\n", __func__);
  318. if (cl_upper_dev) {
  319. mtk_thermal_cooling_device_unregister(cl_upper_dev);
  320. cl_upper_dev = NULL;
  321. }
  322. if (cl_lower_dev) {
  323. mtk_thermal_cooling_device_unregister(cl_lower_dev);
  324. cl_lower_dev = NULL;
  325. }
  326. }
  327. int amutt_param_read(struct seq_file *m, void *v)
  328. {
  329. seq_printf(m,
  330. "[up]\t%3d(sec)\t%2d\n[low]\t%3d(sec)\t%2d\nrst=%2d\ninterval=%d\nmax_step=%d\n",
  331. up_duration, up_step, low_duration, low_step, low_rst_max, polling_interval,
  332. amutt.max_level);
  333. mtk_cooler_amutt_dprintk_always
  334. ("[%s] [up]%d %d, [low]%d %d, rst=%d, interval=%d, max_step=%d\n", __func__,
  335. up_duration, up_step, low_duration, low_step, low_rst_max, polling_interval,
  336. amutt.max_level);
  337. return 0;
  338. }
  339. ssize_t amutt_param_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
  340. {
  341. char desc[MAX_LEN] = { 0 };
  342. unsigned int tmp_up_dur = 10;
  343. unsigned int tmp_up_step = 1;
  344. unsigned int tmp_low_dur = 10;
  345. unsigned int tmp_low_step = 1;
  346. unsigned int tmp_low_rst_max = 6;
  347. int tmp_polling_interval = 1;
  348. unsigned int tmp_deepest_step = COOLER_STEPS - 1;
  349. unsigned int tmp_log = 0;
  350. len = (len < (sizeof(desc) - 1)) ? len : (sizeof(desc) - 1);
  351. /* write data to the buffer */
  352. if (copy_from_user(desc, buf, len))
  353. return -EFAULT;
  354. if (sscanf(desc, "%d %d %d %d %d %d %d", &tmp_up_dur, &tmp_up_step, &tmp_low_dur,
  355. &tmp_low_step, &tmp_low_rst_max, &tmp_polling_interval,
  356. &tmp_deepest_step) >= 6) {
  357. up_duration = tmp_up_dur;
  358. up_step = tmp_up_step;
  359. low_duration = tmp_low_dur;
  360. low_step = tmp_low_step;
  361. low_rst_max = tmp_low_rst_max;
  362. polling_interval = tmp_polling_interval;
  363. if (tmp_deepest_step > 0 && tmp_deepest_step < COOLER_STEPS)
  364. amutt.max_level = tmp_deepest_step;
  365. over_up_time = 0;
  366. below_low_time = 0;
  367. low_rst_time = 0;
  368. mtk_cooler_amutt_dprintk_always
  369. ("[%s] %s [up]%d %d, [low]%d %d, rst=%d, interval=%d, max_step=%d\n", __func__,
  370. desc, up_duration, up_step, low_duration, low_step, low_rst_max,
  371. polling_interval, amutt.max_level);
  372. return len;
  373. } else if (sscanf(desc, "log=%d", &tmp_log) == 1) {
  374. if (tmp_log == 1)
  375. cl_amutt_klog_on = 1;
  376. else
  377. cl_amutt_klog_on = 0;
  378. return len;
  379. }
  380. mtk_cooler_amutt_dprintk_always("[%s] bad argument = %s\n", __func__, desc);
  381. return -EINVAL;
  382. }
  383. static int amutt_param_open(struct inode *inode, struct file *file)
  384. {
  385. return single_open(file, amutt_param_read, NULL);
  386. }
  387. static const struct file_operations amutt_param_fops = {
  388. .owner = THIS_MODULE,
  389. .open = amutt_param_open,
  390. .read = seq_read,
  391. .llseek = seq_lseek,
  392. .write = amutt_param_write,
  393. .release = single_release,
  394. };
  395. int amutt_asparam_read(struct seq_file *m, void *v)
  396. {
  397. int i = 0;
  398. for (; i < COOLER_STEPS; i++) {
  399. unsigned int active;
  400. unsigned int suspend;
  401. active = (amutt_param[i] & 0x0000FF00) >> 8;
  402. suspend = (amutt_param[i] & 0x00FF0000) >> 16;
  403. seq_printf(m, "%02d %u %u %x\n", i, active, suspend, amutt_param[i]);
  404. }
  405. mtk_cooler_amutt_dprintk_always("[%s]\n", __func__);
  406. return 0;
  407. }
  408. ssize_t amutt_asparam_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
  409. {
  410. char desc[MAX_LEN] = { 0 };
  411. unsigned int tmp_step = 0;
  412. unsigned int active_ms = 0;
  413. unsigned int suspend_ms = 0;
  414. len = (len < (sizeof(desc) - 1)) ? len : (sizeof(desc) - 1);
  415. /* write data to the buffer */
  416. if (copy_from_user(desc, buf, len))
  417. return -EFAULT;
  418. if (sscanf(desc, "%d %d %d", &tmp_step, &active_ms, &suspend_ms) == 3) {
  419. if (tmp_step > 0 && tmp_step < COOLER_STEPS) {
  420. if (active_ms == 0 || suspend_ms == 0)
  421. amutt_param[tmp_step] = 0;
  422. else if (active_ms >= 100 && active_ms <= 25500 && suspend_ms >= 100
  423. && suspend_ms <= 25500)
  424. amutt_param[tmp_step] =
  425. ((suspend_ms / 100) << 16) | ((active_ms / 100) << 8) | 1;
  426. mtk_cooler_amutt_dprintk_always("[%s] %s %u %u %u %x\n", __func__, desc,
  427. tmp_step, active_ms, suspend_ms,
  428. amutt_param[tmp_step]);
  429. }
  430. return len;
  431. } else {
  432. mtk_cooler_amutt_dprintk_always("[%s] bad arg = %s\n", __func__, desc);
  433. }
  434. return -EINVAL;
  435. }
  436. static int amutt_asparam_open(struct inode *inode, struct file *file)
  437. {
  438. return single_open(file, amutt_asparam_read, NULL);
  439. }
  440. static const struct file_operations amutt_asparam_fops = {
  441. .owner = THIS_MODULE,
  442. .open = amutt_asparam_open,
  443. .read = seq_read,
  444. .llseek = seq_lseek,
  445. .write = amutt_asparam_write,
  446. .release = single_release,
  447. };
  448. int amutt_dbg_read(struct seq_file *m, void *v)
  449. {
  450. seq_printf(m, "cur=%d max=%d\n", amutt.cur_level, amutt.max_level);
  451. mtk_cooler_amutt_dprintk_always("[%s] cur=%d max=%d\n", __func__, amutt.cur_level,
  452. amutt.max_level);
  453. return 0;
  454. }
  455. ssize_t amutt_dbg_write(struct file *filp, const char __user *buf, size_t len, loff_t *data)
  456. {
  457. char desc[MAX_LEN] = { 0 };
  458. int new_level = -1;
  459. len = (len < (sizeof(desc) - 1)) ? len : (sizeof(desc) - 1);
  460. /* write data to the buffer */
  461. if (copy_from_user(desc, buf, len))
  462. return -EFAULT;
  463. if (kstrtoint(desc, 10, &new_level) == 0) {
  464. if (new_level >= 0 && new_level < COOLER_STEPS) {
  465. /* valid input */
  466. mtk_cooler_amutt_dprintk_always("[%s] new level %d\n", __func__, new_level);
  467. amutt.cur_level = new_level;
  468. amutt.opp_func_array[new_level] (new_level);
  469. } else
  470. mtk_cooler_amutt_dprintk_always("[%s] invalid %d\n", __func__, new_level);
  471. return len;
  472. }
  473. mtk_cooler_amutt_dprintk_always("[%s] bad argument = %s\n", __func__, desc);
  474. return -EINVAL;
  475. }
  476. static int amutt_dbg_open(struct inode *inode, struct file *file)
  477. {
  478. return single_open(file, amutt_dbg_read, NULL);
  479. }
  480. static const struct file_operations amutt_dbg_fops = {
  481. .owner = THIS_MODULE,
  482. .open = amutt_dbg_open,
  483. .read = seq_read,
  484. .llseek = seq_lseek,
  485. .write = amutt_dbg_write,
  486. .release = single_release,
  487. };
  488. static int amutt_proc_register(void)
  489. {
  490. struct proc_dir_entry *entry = NULL;
  491. struct proc_dir_entry *amutt_proc_dir = NULL;
  492. mtk_cooler_amutt_dprintk("[%s]\n", __func__);
  493. amutt_proc_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
  494. if (!amutt_proc_dir) {
  495. mtk_cooler_amutt_dprintk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
  496. } else {
  497. entry =
  498. proc_create("clamutt_param", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
  499. amutt_proc_dir, &amutt_param_fops);
  500. if (entry)
  501. proc_set_user(entry, uid, gid);
  502. entry =
  503. proc_create("clamutt_asparam", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
  504. amutt_proc_dir, &amutt_asparam_fops);
  505. if (entry)
  506. proc_set_user(entry, uid, gid);
  507. entry =
  508. proc_create("clamutt_dbg", S_IRUSR | S_IWUSR, amutt_proc_dir, &amutt_dbg_fops);
  509. if (entry)
  510. proc_set_user(entry, uid, gid);
  511. }
  512. return 0;
  513. }
  514. static int __init mtk_cooler_amutt_init(void)
  515. {
  516. int err = 0, i = 0;
  517. mtk_cooler_amutt_dprintk("[%s]\n", __func__);
  518. for (; i < COOLER_STEPS; i++)
  519. opp_func[i] = amutt_backoff;
  520. amutt.cur_level = 0;
  521. amutt.max_level = COOLER_STEPS - 1;
  522. amutt.opp_func_array = &opp_func[0];
  523. err = amutt_proc_register();
  524. if (err)
  525. return err;
  526. err = mtk_cooler_amutt_register_ltf();
  527. if (err)
  528. goto err_unreg;
  529. return 0;
  530. err_unreg:
  531. mtk_cooler_amutt_unregister_ltf();
  532. return err;
  533. }
  534. static void __exit mtk_cooler_amutt_exit(void)
  535. {
  536. mtk_cooler_amutt_dprintk("[%s]\n", __func__);
  537. /* remove the proc file */
  538. /* remove_proc_entry("amutt", NULL); */
  539. mtk_cooler_amutt_unregister_ltf();
  540. }
  541. module_init(mtk_cooler_amutt_init);
  542. module_exit(mtk_cooler_amutt_exit);