import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / eemcs / eemcs_sysfs.c
CommitLineData
6fa3eb70
S
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/sysfs.h>
4#include <linux/device.h>
5#include <linux/uaccess.h>
6#include <linux/cdev.h>
7#include <linux/timer.h>
8#include <linux/timex.h>
9#include <linux/rtc.h>
10#include <linux/string.h>
11
12#include "eemcs_char.h"
13#include "eemcs_boot.h"
14#include "eemcs_debug.h"
15#include "eemcs_fs_ut.h"
16#include "eemcs_rpc_ut.h"
17#include "eemcs_statistics.h"
18#include "eemcs_state.h"
19#include "eemcs_expt_ut.h"
20
21extern EEMCS_BOOT_SET eemcs_boot_inst;
22
23/*
24 * To show if "bypass CCCI handshake" is enabled
25 */
26static ssize_t eemcs_sysfs_show_ccci_hs_bypass(struct device *dev, struct device_attribute *attr, char *buf)
27{
28 DBGLOG(SYSF, INF, "get CCCI handshake bypassed info: %d", eemcs_boot_inst.ccci_hs_bypass);
29 return 0;
30}
31
32/*
33 * To set "bypass CCCI handshake" flag
34 */
35static ssize_t eemcs_sysfs_set_ccci_hs_bypass(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
36{
37 KAL_UINT32 bypass = 0;
38
39 bypass = simple_strtol(buf, NULL, 10);
40 if (bypass > 0)
41 eemcs_boot_inst.ccci_hs_bypass = 1;
42 else
43 eemcs_boot_inst.ccci_hs_bypass = 0;
44 DBGLOG(SYSF, INF, "set CCCI handshake bypassed info: %d", eemcs_boot_inst.ccci_hs_bypass);
45 return count;
46}
47static DEVICE_ATTR(ccci_hs_bypass, S_IRUGO|S_IWUSR, eemcs_sysfs_show_ccci_hs_bypass, eemcs_sysfs_set_ccci_hs_bypass);
48
49#ifdef _EEMCS_FS_UT
50/*
51 * To dump FS UT information
52 */
53static ssize_t eemcs_sysfs_show_fs_ut(struct device *dev, struct device_attribute *attr, char *buf)
54{
55 eemcs_fs_ut_dump();
56 return 0;
57}
58
59/*
60 * Use a positive value to trigger FS UT
61 */
62static ssize_t eemcs_sysfs_set_fs_ut(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
63{
64 KAL_UINT32 go_ut = 0;
65
66 go_ut = simple_strtol(buf, NULL, 10);
67 if (go_ut >= 1)
68 eemcs_fs_ut_trigger();
69
70 return count;
71}
72
73static DEVICE_ATTR(fs_ut, S_IRUGO|S_IWUSR, eemcs_sysfs_show_fs_ut, eemcs_sysfs_set_fs_ut);
74
75/*
76 * To show the port index currently used in FS UT
77 */
78static ssize_t eemcs_sysfs_show_fs_ut_port(struct device *dev, struct device_attribute *attr, char *buf)
79{
80 DBGLOG(SYSF, INF, "FS UT Get Port_idx=%d", eemcs_fs_ut_get_index());
81 return 0;
82}
83
84/*
85 * To set the port index you want to use in FS UT
86 */
87static ssize_t eemcs_sysfs_set_fs_ut_port(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
88{
89 KAL_UINT32 index = 0;
90
91 index = simple_strtol(buf, NULL, 10);
92 if (eemcs_fs_ut_set_index(index) >= 0)
93 DBGLOG(SYSF, INF, "FS UT Set Port_idx=%d", index);
94 else
95 DBGLOG(SYSF, INF, "FS UT Set Port_idx=%d", index);
96
97 return count;
98}
99static DEVICE_ATTR(fs_ut_port, S_IRUGO|S_IWUSR, eemcs_sysfs_show_fs_ut_port, eemcs_sysfs_set_fs_ut_port);
100
101#endif // _EEMCS_FS_UT
102
103
104#ifdef _EEMCS_RPC_UT
105
106/*
107 * Use a positive value to trigger RPC UT
108 */
109static ssize_t eemcs_sysfs_set_rpc_ut(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
110{
111 KAL_UINT32 go_ut = 0;
112
113 go_ut = simple_strtol(buf, NULL, 10);
114 if (go_ut >= 1)
115 eemcs_rpc_ut_trigger();
116
117 return count;
118}
119static DEVICE_ATTR(rpc_ut, S_IRUGO|S_IWUSR, NULL, eemcs_sysfs_set_rpc_ut);
120
121
122#endif // _EEMCS_RPC_UT
123
124
125/*
126 * Use 1 to print time of EMCSVA test start
127 * 0 to print time of EMCSVA test stop
128 */
129static ssize_t eemcs_sysfs_emcsva_log(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
130{
131 KAL_UINT32 emcsva_log_set = 0;
132 struct timex txc;
133 struct rtc_time tm;
134 char c_time_string[30]={0};
135 do_gettimeofday(&(txc.time));
136 rtc_time_to_tm(txc.time.tv_sec,&tm);
137 sprintf(c_time_string,"%04d-%02d-%02d_%02d:%02d:%02d",tm.tm_year+1900,tm.tm_mon+1, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
138
139 emcsva_log_set = simple_strtol(buf, NULL, 10);
140 if (emcsva_log_set == 1){
141 DBGLOG(SYSF, INF, "++EEMCSVA Start: %s %s++", c_time_string, buf+2);
142 }
143 else if (emcsva_log_set == 0) {
144 DBGLOG(SYSF, INF, "--EEMCSVA Stop : %s %s--", c_time_string, buf+2);
145 }
146 return count;
147}
148static DEVICE_ATTR(emcsva_log, S_IRUGO|S_IWUSR, NULL, eemcs_sysfs_emcsva_log);
149
150
151/*
152 * To dump Boot restet test information
153 */
154extern unsigned char* g_md_sta_str[];
155static ssize_t eemcs_show_boot_state(struct device *dev, struct device_attribute *attr, char *buf)
156{
157 DBGLOG(SYSF, INF, "get md_boot_state=%s(%d)", g_md_sta_str[eemcs_boot_get_state()], eemcs_boot_get_state());
158 return sprintf(buf,"%d\n",eemcs_boot_get_state());
159}
160
161/*
162 * Use a positive value to trigger FS UT
163 */
164static ssize_t eemcs_set_boot_reset_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
165{
166 KAL_UINT32 reset_state = 0;
167
168 reset_state = simple_strtol(buf, NULL, 10);
169 if (reset_state >= 0)
170 DBGLOG(SYSF, INF, "set md_boot_state=%s(%d)", g_md_sta_str[reset_state], reset_state);
171 eemcs_boot_reset_test(reset_state);
172
173 return count;
174}
175
176static DEVICE_ATTR(boot_test, S_IRUGO|S_IWUSR, eemcs_show_boot_state, eemcs_set_boot_reset_state);
177
178/*
179 * To show eemcs port statistics
180 */
181KAL_CHAR *ccci_port_name[CCCI_PORT_NUM_MAX]=
182{
183 "eemcs_ctrl",
184 "eemcs_sys", /* START_OF_NORMAL_PORT */
185 "eemcs_aud",
186 "eemcs_meta",
187 "eemcs_mux",
188 "eemcs_fs",
189 "eemcs_pmic",
190 "eemcs_uem",
191 "eemcs_rpc",
192 "eemcs_ipc",
193 "eemcs_ipc_uart",
194 "eemcs_md_log",
195 "eemcs_imsv", /* ims video */
196 "eemcs_imsc", /* ims control */
197 "eemcs_imsa", /* ims audio */
198 "eemcs_imsdc", /* ims data control */
199 "eemcs_muxrp", /* mux report channel, support ioctl only no i/o*/
200 "eemcs_ioctl", /* ioctl channel, support ioctl only no i/o*/
201 "eemcs_ril", /* rild channel, support ioctl only no i/o*/
202 "eemcs_it", /* END_OF_NORMAL_PORT-1 */
203 "ECCMNI1",
204 "ECCMNI2",
205 "ECCMNI3",
206};
207static ssize_t eemcs_sysfs_show_statistics(struct device *dev, struct device_attribute *attr, char *buf)
208{
209 int i = 0;
210 char line[121]={0};
211 char c_time_string[30]={0};
212 int pos = 0;
213 struct timeval tv;
214 struct rtc_time tm;
215 struct rtc_time tm_now;
216 do_gettimeofday(&tv);
217 rtc_time_to_tm(tv.tv_sec,&tm_now);
218 rtc_time_to_tm(eemcs_statistics[0]->time.tv_sec,&tm);
219 sprintf(c_time_string,"%04d-%02d-%02d_%02d:%02d:%02d ~ %02d:%02d - %d sec",
220 tm.tm_year+1900,tm.tm_mon+1, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec,
221 tm_now.tm_min,tm_now.tm_sec,
222 (unsigned int)(tv.tv_sec - eemcs_statistics[0]->time.tv_sec));
223
224 pos += sprintf(buf+pos, "Record Time: %s\n", c_time_string);
225
226 pos += sprintf(buf+pos, "%15s | %7s | %7s | %9s | %8s | %8s | %7s | %7s |\n",
227 "CCCI PORT", "TX CNT", "RX CNT", "RX Q(MAX)", "TX TOTAL", "RX TOTAL", "TX DROP", "RX DROP");
228 memset(line, '=', 91);
229 pos += sprintf(buf+pos, "%s\n", line);
230 for (i=0; i< CCCI_PORT_NUM_MAX; i++){
231 CCCI_PORT_STATISTICS *port = &eemcs_statistics[0]->port[i];
232 CCCI_PORT_STATISTICS *port_total = &eemcs_statistics[0]->port_total[i];
233 pos += sprintf(buf+pos, "%15s | %7d | %7d | %3d(%4d) | %8d | %8d | %7d | %7d |\n",
234 ccci_port_name[i], port->cnt[TX], port->cnt[RX],
235 port->queue[RX], port_total->queue[RX],
236 port_total->cnt[TX], port_total->cnt[RX],
237 port_total->drop[TX], port_total->drop[RX]
238 );
239 }
240
241 return pos;
242}
243
244/*
245 * To set eemcs port statistics timer
246 */
247static ssize_t eemcs_sysfs_set_statistics(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
248{
249 KAL_UINT32 input = 0;
250
251 input = simple_strtol(buf, NULL, 10);
252
253 switch(input){
254 case 0 :
255 eemcs_statistics[0]->start = 0;
256 break;
257
258 default:
259 eemcs_statistics[0]->inteval = input;
260 eemcs_statistics[0]->start = 1;
261 break;
262 }
263
264 return count;
265}
266static DEVICE_ATTR(eemcs_statistics, S_IRUGO|S_IWUSR, eemcs_sysfs_show_statistics, eemcs_sysfs_set_statistics);
267
268
269//===================================================================
270// Exception Mode sysfs
271//===================================================================
272
273#ifdef __EEMCS_EXPT_SUPPORT__
274
275#define EEMCS_EX_MODE_LEN 16
276
277/*
278 * Show current exception mode (if in exception state)
279 */
280static ssize_t eemcs_sysfs_show_expt_mode(struct device *dev, struct device_attribute *attr, char *buf)
281{
282 EEMCS_EXCEPTION_STATE mode = EEMCS_EX_INVALID;
283 KAL_UINT32 is_exception;
284 extern KAL_INT32 get_exception_mode(void);
285
286 is_exception = is_exception_mode(&mode);
287 mode = get_exception_mode();
288 return snprintf(buf, PAGE_SIZE, "[EXPT] %s in Exception and Exception Mode = 0x%X\n", (is_exception?"IS":"NOT"), mode);
289}
290
291#ifdef _EEMCS_EXCEPTION_UT
292
293/*
294 * Set EEMCS to exception state
295 *
296 * "reset" ==> EEMCS_EX_INVALID = 0,
297 * "none" ==> EEMCS_EX_NONE = 0,
298 * "init" ==> EEMCS_EX_INIT = 1,
299 * "dhl_ready" ==> EEMCS_EX_DHL_DL_RDY = 2,
300 * "init_done" ==> EEMCS_EX_INIT_DONE = 3,
301 */
302static ssize_t eemcs_sysfs_set_expt_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
303{
304 unsigned int ret = -EINVAL;
305 char str_mode[EEMCS_EX_MODE_LEN] = {0};
306 EEMCS_EXCEPTION_STATE mode = EEMCS_EX_INVALID;
307 KAL_UINT32 is_exception;
308 DEBUG_LOG_FUNCTION_ENTRY;
309
310 ret = sscanf(buf, "%15s", str_mode);
311 if (ret != 1)
312 return 0;
313 DBGLOG(EXPT, INF, "exception mode command(%s), count=%d", str_mode, count);
314 if (strnicmp(str_mode, "reset", EEMCS_EX_MODE_LEN) == 0) {
315 change_device_state(EEMCS_INIT);
316 } else if (strnicmp(str_mode, "none", EEMCS_EX_MODE_LEN) == 0) {
317 set_exception_mode(EEMCS_EX_NONE);
318 } else if (strnicmp(str_mode, "init", EEMCS_EX_MODE_LEN) == 0) {
319 eemcs_expt_ut_trigger(EX_INIT);
320 } else if (strnicmp(str_mode, "dhl_ready", EEMCS_EX_MODE_LEN) == 0) {
321 eemcs_expt_ut_trigger(EX_DHL_DL_RDY);
322 } else if (strnicmp(str_mode, "init_done", EEMCS_EX_MODE_LEN) == 0) {
323 eemcs_expt_ut_trigger(EX_INIT_DONE);
324 } else {
325 DBGLOG(EXPT, WAR, "Nothing to do !!");
326 }
327 is_exception = is_exception_mode(&mode);
328 DBGLOG(SYSF, INF, "set Exception_Mode=%d when md %s in exception\n", (is_exception?"IS":"NOT"), mode);
329
330 DEBUG_LOG_FUNCTION_LEAVE;
331 return count;
332}
333static DEVICE_ATTR(expt_mode, S_IRUGO|S_IWUSR, eemcs_sysfs_show_expt_mode, eemcs_sysfs_set_expt_mode);
334#else // _EEMCS_EXCEPTION_UT
335static DEVICE_ATTR(expt_mode, S_IRUGO|S_IWUSR, eemcs_sysfs_show_expt_mode, NULL);
336#endif // _EEMCS_EXCEPTION_UT
337
338/*
339 * Show exception mode statistics
340 */
341static ssize_t eemcs_sysfs_show_expt(struct device *dev, struct device_attribute *attr, char *buf)
342{
343 return eemcs_expt_show_statistics(buf);
344}
345
346/*
347 * Exception mode control
348 */
349static ssize_t eemcs_sysfs_set_expt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
350{
351 unsigned int ret = -EINVAL;
352 char ctrl_cmd[EEMCS_EX_MODE_LEN] = {0};
353 DEBUG_LOG_FUNCTION_ENTRY;
354
355 ret = sscanf(buf, "%15s", ctrl_cmd);
356 if (ret != 1)
357 return 0;
358 DBGLOG(SYSF, INF, "exception control command(%s), count=%d", ctrl_cmd, count);
359 if (strnicmp(ctrl_cmd, "flush", EEMCS_EX_MODE_LEN) == 0) {
360 eemcs_expt_flush();
361 } else {
362 DBGLOG(SYSF, WAR, "[EXPT] Nothing to do!!");
363 }
364
365 DEBUG_LOG_FUNCTION_LEAVE;
366 return count;
367
368}
369static DEVICE_ATTR(expt, S_IRUGO|S_IWUSR, eemcs_sysfs_show_expt, eemcs_sysfs_set_expt);
370
371#ifdef _EEMCS_EXCEPTION_UT
372/*
373 * Showing if loopback to CCCI in exception UT is enabled
374 */
375static ssize_t eemcs_sysfs_show_expt_ut_ccci_lb(struct device *dev, struct device_attribute *attr, char *buf)
376{
377 return eemcs_expt_sysfs_show_ut_ccci_lb(buf);
378}
379
380/*
381 * Disable/Enable loopback to CCCI in exception UT
382 */
383static ssize_t eemcs_sysfs_set_expt_ut_ccci_lb(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
384{
385 KAL_UINT32 enable = 0;
386
387 enable = simple_strtol(buf, NULL, 10);
388 if (enable >= 1)
389 eemcs_expt_enable_ut_ccci_lb(1);
390 else
391 eemcs_expt_enable_ut_ccci_lb(0);
392
393 return count;
394}
395static DEVICE_ATTR(expt_ut_ccci_lb, S_IRUGO|S_IWUSR, eemcs_sysfs_show_expt_ut_ccci_lb, eemcs_sysfs_set_expt_ut_ccci_lb);
396
397#endif // _EEMCS_EXCEPTION_UT
398
399#endif // __EEMCS_EXPT_SUPPORT__
400
401
402void eemcs_sysfs_init(struct class *dev_class)
403{
404 struct device *dev = NULL;
405
406 if (!IS_ERR(dev_class)) {
407 dev = device_create(dev_class, NULL, MKDEV(EEMCS_DEV_MAJOR, END_OF_NORMAL_PORT), NULL, EEMCS_DEV_NAME);
408 if (IS_ERR(dev)) {
409 DBGLOG(SYSF, ERR, "create device(%s) fail", EEMCS_DEV_NAME);
410 } else {
411 if (device_create_file(dev, &dev_attr_ccci_hs_bypass) != 0)
412 DBGLOG(SYSF, ERR, "create sysfs ccci_hs_bypass fail");
413
414 if (device_create_file(dev, &dev_attr_emcsva_log) != 0)
415 DBGLOG(SYSF, ERR, "create sysfs emcsva_log fail");
416
417 if (device_create_file(dev, &dev_attr_boot_test) != 0)
418 DBGLOG(SYSF, ERR, "create sysfs boot_test fail");
419
420 if (device_create_file(dev, &dev_attr_eemcs_statistics) != 0)
421 DBGLOG(SYSF, ERR, "create sysfs eemcs_statistics fail");
422#ifdef _EEMCS_RPC_UT
423 if (device_create_file(dev, &dev_attr_rpc_ut) != 0)
424 DBGLOG(SYSF, ERR, "create sysfs rpc_ut fail");
425#endif // _EEMCS_RPC_UT
426
427#ifdef _EEMCS_FS_UT
428 if (device_create_file(dev, &dev_attr_fs_ut) != 0)
429 DBGLOG(SYSF, ERR, "create sysfs fs_ut fail");
430 if (device_create_file(dev, &dev_attr_fs_ut_port) != 0)
431 DBGLOG(SYSF, ERR, "create sysfs fs_ut_port fail");
432#endif // _EEMCS_FS_UT
433#ifdef __EEMCS_EXPT_SUPPORT__
434 if (device_create_file(dev, &dev_attr_expt_mode) != 0)
435 DBGLOG(SYSF, ERR, "create sysfs expt_mode fail");
436 if (device_create_file(dev, &dev_attr_expt) != 0)
437 DBGLOG(SYSF, ERR, "create sysfs expt_info fail");
438#ifdef _EEMCS_EXCEPTION_UT
439 if (device_create_file(dev, &dev_attr_expt_ut_ccci_lb) != 0)
440 DBGLOG(SYSF, ERR, "create sysfs expt_ut_ccci_lb fail");
441#endif // _EEMCS_EXCEPTION_UT
442#endif // __EEMCS_EXPT_SUPPORT__
443
444
445 }
446 }
447}
448
449void eemcs_sysfs_exit(struct class *dev_class)
450{
451 if (!IS_ERR(dev_class)) {
452 device_destroy(dev_class, MKDEV(EEMCS_DEV_MAJOR, END_OF_NORMAL_PORT));
453 }
454}
455