mtk_ta.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. #include <linux/version.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/thermal.h>
  5. #include <linux/platform_device.h>
  6. #include <linux/types.h>
  7. #include <linux/proc_fs.h>
  8. #include "mt-plat/mtk_thermal_monitor.h"
  9. #include "mtk_thermal_typedefs.h"
  10. #include "mach/mt_thermal.h"
  11. #include "mt-plat/mtk_thermal_platform.h"
  12. #include <linux/slab.h>
  13. #include <linux/seq_file.h>
  14. #include <tscpu_settings.h>
  15. #include <mt-plat/aee.h>
  16. #include <net/sock.h>
  17. #include <net/genetlink.h>
  18. #include <linux/netlink.h>
  19. #include <linux/socket.h>
  20. #include <linux/skbuff.h>
  21. #include <linux/reboot.h>
  22. #include <linux/vmalloc.h>
  23. static int mtkts_ta_debug_log;
  24. #define tsta_dprintk(fmt, args...) \
  25. do { \
  26. if (mtkts_ta_debug_log) { \
  27. pr_debug("[Thermal_TA]" fmt, ##args); \
  28. } \
  29. } while (0)
  30. #define tsta_warn(fmt, args...) pr_warn("[Thermal_TA]" fmt, ##args)
  31. /*=============================================================
  32. *Local variable definition
  33. *=============================================================*/
  34. static struct sock *daemo_nl_sk;
  35. static void ta_nl_send_to_user(int pid, int seq, struct tad_nl_msg_t *reply_msg);
  36. static int g_tad_pid;
  37. static bool init_flag;
  38. static int g_tad_ttj;
  39. /*=============================================================
  40. *Local function prototype
  41. *=============================================================*/
  42. /*=============================================================
  43. *Weak functions
  44. *=============================================================*/
  45. #define NETLINK_TAD 27
  46. /*=============================================================*/
  47. void atm_ctrl_cmd_from_user(void *nl_data, struct tad_nl_msg_t *ret_msg)
  48. {
  49. struct tad_nl_msg_t *msg;
  50. msg = nl_data;
  51. /*tsta_dprintk("[atm_ctrl_cmd_from_user] tad_cmd = %d, tad_data_len = %d\n" ,
  52. msg->tad_cmd , msg->tad_data_len);*/
  53. ret_msg->tad_cmd = msg->tad_cmd;
  54. switch (msg->tad_cmd) {
  55. case TA_DAEMON_CMD_NOTIFY_DAEMON_CATMINIT:
  56. {
  57. memcpy(ret_msg->tad_data, &thermal_atm_t, sizeof(thermal_atm_t));
  58. ret_msg->tad_data_len += sizeof(thermal_atm_t);
  59. tsta_dprintk("[atm_ctrl_cmd_from_user] ret_msg->tad_data_len %d\n" , ret_msg->tad_data_len);
  60. }
  61. break;
  62. case TA_DAEMON_CMD_GET_INIT_FLAG:
  63. {
  64. ret_msg->tad_data_len += sizeof(init_flag);
  65. memcpy(ret_msg->tad_data, &init_flag, sizeof(init_flag));
  66. tsta_dprintk("[atm_ctrl_cmd_from_user] init_flag = %d\n" , init_flag);
  67. }
  68. break;
  69. case TA_DAEMON_CMD_GET_TPCB:
  70. {
  71. int curr_tpcb = mtk_thermal_get_temp(MTK_THERMAL_SENSOR_AP);
  72. ret_msg->tad_data_len += sizeof(curr_tpcb);
  73. memcpy(ret_msg->tad_data, &curr_tpcb, sizeof(curr_tpcb));
  74. tsta_dprintk("[atm_ctrl_cmd_from_user] curr_tpcb = %d\n" , curr_tpcb);
  75. }
  76. break;
  77. case TA_DAEMON_CMD_SET_DAEMON_PID:
  78. {
  79. memcpy(&g_tad_pid, &msg->tad_data[0], sizeof(g_tad_pid));
  80. tsta_dprintk("[atm_ctrl_cmd_from_user] g_tad_pid = %d\n", g_tad_pid);
  81. }
  82. break;
  83. case TA_DAEMON_CMD_SET_TTJ:
  84. {
  85. memcpy(&g_tad_ttj, &msg->tad_data[0], sizeof(g_tad_ttj));
  86. tsta_dprintk("[atm_ctrl_cmd_from_user] g_tad_ttj = %d\n", g_tad_ttj);
  87. }
  88. break;
  89. default:
  90. tsta_warn("bad TA_DAEMON_CTRL_CMD_FROM_USER 0x%x\n", msg->tad_cmd);
  91. break;
  92. }
  93. }
  94. int ta_get_ttj(void)
  95. {
  96. tsta_dprintk("g_tad_ttj= %d\n", g_tad_ttj);
  97. return g_tad_ttj;
  98. }
  99. static void ta_nl_send_to_user(int pid, int seq, struct tad_nl_msg_t *reply_msg)
  100. {
  101. struct sk_buff *skb;
  102. struct nlmsghdr *nlh;
  103. int size = reply_msg->tad_data_len + TAD_NL_MSG_T_HDR_LEN;
  104. int len = NLMSG_SPACE(size);
  105. void *data;
  106. int ret;
  107. skb = alloc_skb(len, GFP_ATOMIC);
  108. if (!skb)
  109. return;
  110. nlh = nlmsg_put(skb, pid, seq, 0, size, 0);
  111. data = NLMSG_DATA(nlh);
  112. memcpy(data, reply_msg, size);
  113. NETLINK_CB(skb).portid = 0; /* from kernel */
  114. NETLINK_CB(skb).dst_group = 0; /* unicast */
  115. tsta_dprintk("[ta_nl_send_to_user] netlink_unicast size=%d tad_cmd=%d pid=%d\n",
  116. size, reply_msg->tad_cmd, pid);
  117. ret = netlink_unicast(daemo_nl_sk, skb, pid, MSG_DONTWAIT);
  118. if (ret < 0)
  119. tsta_warn("[ta_nl_send_to_user] send failed %d\n", ret);
  120. tsta_dprintk("[ta_nl_send_to_user] netlink_unicast- ret=%d\n", ret);
  121. }
  122. static void ta_nl_data_handler(struct sk_buff *skb)
  123. {
  124. u32 pid;
  125. kuid_t uid;
  126. int seq;
  127. void *data;
  128. struct nlmsghdr *nlh;
  129. struct tad_nl_msg_t *tad_msg, *tad_ret_msg;
  130. int size = 0;
  131. nlh = (struct nlmsghdr *)skb->data;
  132. pid = NETLINK_CREDS(skb)->pid;
  133. uid = NETLINK_CREDS(skb)->uid;
  134. seq = nlh->nlmsg_seq;
  135. /*tsta_dprintk("[ta_nl_data_handler] recv skb from user space uid:%d pid:%d seq:%d\n", uid, pid, seq);*/
  136. data = NLMSG_DATA(nlh);
  137. tad_msg = (struct tad_nl_msg_t *)data;
  138. size = tad_msg->tad_ret_data_len + TAD_NL_MSG_T_HDR_LEN;
  139. /*tad_ret_msg = (struct tad_nl_msg_t *)vmalloc(size);*/
  140. tad_ret_msg = vmalloc(size);
  141. memset(tad_ret_msg, 0, size);
  142. atm_ctrl_cmd_from_user(data, tad_ret_msg);
  143. ta_nl_send_to_user(pid, seq, tad_ret_msg);
  144. tsta_dprintk("[ta_nl_data_handler] send to user space process done\n");
  145. vfree(tad_ret_msg);
  146. }
  147. int wakeup_ta_algo(int flow_state)
  148. {
  149. tsta_dprintk("[wakeup_ta_algo]g_tad_pid=%d, state=%d\n" , g_tad_pid, flow_state);
  150. if (g_tad_pid != 0) {
  151. struct tad_nl_msg_t *tad_msg;
  152. int size = TAD_NL_MSG_T_HDR_LEN + sizeof(flow_state);
  153. /*tad_msg = (struct tad_nl_msg_t *)vmalloc(size);*/
  154. tad_msg = vmalloc(size);
  155. tsta_dprintk("[wakeup_ta_algo] malloc size=%d\n", size);
  156. memset(tad_msg, 0, size);
  157. tad_msg->tad_cmd = TA_DAEMON_CMD_NOTIFY_DAEMON;
  158. memcpy(tad_msg->tad_data, &flow_state, sizeof(flow_state));
  159. tad_msg->tad_data_len += sizeof(flow_state);
  160. ta_nl_send_to_user(g_tad_pid, 0, tad_msg);
  161. vfree(tad_msg);
  162. return 0;
  163. } else {
  164. return -1;
  165. }
  166. }
  167. static int tsta_read_log(struct seq_file *m, void *v)
  168. {
  169. seq_printf(m, "[ tsta_read_log] log = %d\n", mtkts_ta_debug_log);
  170. return 0;
  171. }
  172. static ssize_t tsta_write_log(struct file *file, const char __user *buffer, size_t count,
  173. loff_t *data)
  174. {
  175. char desc[32];
  176. int log_switch;
  177. int len = 0;
  178. len = (count < (sizeof(desc) - 1)) ? count : (sizeof(desc) - 1);
  179. if (copy_from_user(desc, buffer, len))
  180. return 0;
  181. desc[len] = '\0';
  182. if (kstrtoint(desc, 10, &log_switch) == 0) {
  183. mtkts_ta_debug_log = log_switch;
  184. return count;
  185. }
  186. tsta_warn("tscpu_write_log bad argument\n");
  187. return -EINVAL;
  188. }
  189. static int tsta_open_log(struct inode *inode, struct file *file)
  190. {
  191. return single_open(file, tsta_read_log, NULL);
  192. }
  193. static const struct file_operations mtktsta_log_fops = {
  194. .owner = THIS_MODULE,
  195. .open = tsta_open_log,
  196. .read = seq_read,
  197. .llseek = seq_lseek,
  198. .write = tsta_write_log,
  199. .release = single_release,
  200. };
  201. static void tsta_create_fs(void)
  202. {
  203. struct proc_dir_entry *entry = NULL;
  204. struct proc_dir_entry *mtktsta_dir = NULL;
  205. mtkts_ta_debug_log = 0;
  206. mtktsta_dir = mtk_thermal_get_proc_drv_therm_dir_entry();
  207. if (!mtktsta_dir) {
  208. tscpu_printk("[%s]: mkdir /proc/driver/thermal failed\n", __func__);
  209. } else {
  210. entry =
  211. proc_create("ta_log", S_IRUGO | S_IWUSR, mtktsta_dir, &mtktsta_log_fops);
  212. }
  213. }
  214. static int __init ta_init(void)
  215. {
  216. /*add by willcai for the userspace to kernelspace*/
  217. struct netlink_kernel_cfg cfg = {
  218. .input = ta_nl_data_handler,
  219. };
  220. g_tad_pid = 0;
  221. init_flag = false;
  222. g_tad_ttj = 0;
  223. /*add by willcai for the userspace to kernelspace*/
  224. daemo_nl_sk = NULL;
  225. daemo_nl_sk = netlink_kernel_create(&init_net, NETLINK_TAD, &cfg);
  226. tsta_dprintk("netlink_kernel_create protol= %d\n", NETLINK_TAD);
  227. if (daemo_nl_sk == NULL) {
  228. tsta_warn("[ta_init] netlink_kernel_create error\n");
  229. return -1;
  230. }
  231. tsta_create_fs();
  232. tsta_dprintk("[ta_init] Initialization : DONE\n");
  233. return 0;
  234. }
  235. module_init(ta_init);