blob: a30ba4d151b5a7aea311e88b1befd614342e64cd [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (C) 2019 MediaTek Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/sched/clock.h>
15#include <linux/fs.h>
16#include <linux/sched.h>
17#include <linux/module.h>
18#include <linux/device.h>
19#include <linux/miscdevice.h>
20#include <linux/kallsyms.h>
21#include <linux/syscore_ops.h>
22#include <linux/dma-mapping.h>
23#include "interface.h"
24#include "sampler.h"
25#include "util.h"
26
27#include "ondiemet.h"
28
29#include "met_drv.h"
30#include "met_tag.h"
31#include "met_kernel_symbol.h"
32#include "met_power.h"
33#include "met_api_tbl.h"
34#include "version.h"
35
36extern int enable_met_backlight_tag(void);
37extern int output_met_backlight_tag(int level);
38
39static int run = -1;
40static int sample_rate = 1000; /* Default: 1000 Hz */
41static int met_suspend_compensation_mode;
42static int met_suspend_compensation_flag;
43
44/*
45 * met_cpu_pmu_method:
46 * 0: MET pmu driver
47 * 1: perf APIs
48 */
49unsigned int met_cpu_pmu_method = 1;
50/*
51 * controls whether re-configuring pmu events after leaving cpu off state
52 */
53unsigned int met_cpu_pm_pmu_reconfig = 1;
54
55int met_hrtimer_expire; /* in ns */
56int met_timer_expire; /* in jiffies */
57unsigned int ctrl_flags;
58int met_mode;
59EXPORT_SYMBOL(met_mode);
60
61DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_nmi);
62EXPORT_SYMBOL(met_strbuf_nmi);
63
64DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_irq);
65EXPORT_SYMBOL(met_strbuf_irq);
66
67DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf_sirq);
68EXPORT_SYMBOL(met_strbuf_sirq);
69
70DEFINE_PER_CPU(char[MET_STRBUF_SIZE], met_strbuf);
71EXPORT_SYMBOL(met_strbuf);
72
73static void calc_timer_value(int rate)
74{
75 sample_rate = rate;
76
77 if (rate == 0) {
78 met_hrtimer_expire = 0;
79 met_timer_expire = 0;
80 return;
81 }
82
83 met_hrtimer_expire = 1000000000 / rate;
84
85 /* Case 1: hrtimer < 1 OS tick, met_timer_expire = 1 OS tick */
86 if (rate > HZ)
87 met_timer_expire = 1;
88 /* Case 2: hrtimer > 1 OS tick, met_timer_expire is hrtimer + 1 OS tick */
89 else
90 met_timer_expire = (HZ / rate) + 1;
91
92 /* pr_debug("JBK HZ=%d, met_hrtimer_expire=%d ns, met_timer_expire=%d ticks\n", */
93 /* HZ, met_hrtimer_expire, met_timer_expire); */
94}
95
96int met_parse_num(const char *str, unsigned int *value, int len)
97{
98 int ret;
99
100 if (len <= 0)
101 return -1;
102
103 if ((len > 2) &&
104 ((str[0] == '0') &&
105 ((str[1] == 'x') || (str[1] == 'X')))) {
106 ret = kstrtoint(str, 16, value);
107 } else {
108 ret = kstrtoint(str, 10, value);
109 }
110
111 if (ret != 0)
112 return -1;
113
114 return 0;
115}
116
117void met_set_suspend_notify(int flag)
118{
119 if (met_suspend_compensation_mode == 1)
120 met_suspend_compensation_flag = flag;
121 else
122 met_suspend_compensation_flag = 0;
123}
124
125LIST_HEAD(met_list);
126static struct kobject *kobj_misc;
127static struct kobject *kobj_pmu;
128static struct kobject *kobj_bus;
129
130static ssize_t ver_show(struct device *dev, struct device_attribute *attr, char *buf);
131static DEVICE_ATTR(ver, 0444, ver_show, NULL);
132
133static ssize_t plf_show(struct device *dev, struct device_attribute *attr, char *buf);
134static DEVICE_ATTR(plf, 0444, plf_show, NULL);
135
136static ssize_t chip_id_show(struct device *dev, struct device_attribute *attr, char *buf);
137static DEVICE_ATTR(chip_id, 0444, chip_id_show, NULL);
138
139static ssize_t core_topology_show(struct device *dev, struct device_attribute *attr, char *buf);
140static DEVICE_ATTR(core_topology, 0444, core_topology_show, NULL);
141
142static ssize_t devices_show(struct device *dev, struct device_attribute *attr, char *buf);
143static DEVICE_ATTR(devices, 0444, devices_show, NULL);
144
145static ssize_t ctrl_show(struct device *dev, struct device_attribute *attr, char *buf);
146static ssize_t ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf,
147 size_t count);
148static DEVICE_ATTR(ctrl, 0664, ctrl_show, ctrl_store);
149
150static ssize_t spr_show(struct device *dev, struct device_attribute *attr, char *buf);
151static ssize_t spr_store(struct device *dev, struct device_attribute *attr, const char *buf,
152 size_t count);
153static DEVICE_ATTR(sample_rate, 0664, spr_show, spr_store);
154
155static ssize_t run_show(struct device *dev, struct device_attribute *attr, char *buf);
156static ssize_t run_store(struct device *dev, struct device_attribute *attr, const char *buf,
157 size_t count);
158static DEVICE_ATTR(run, 0664, run_show, run_store);
159
160static ssize_t ksym_show(struct device *dev, struct device_attribute *attr, char *buf);
161static ssize_t ksym_store(struct device *dev, struct device_attribute *attr, const char *buf,
162 size_t count);
163static DEVICE_ATTR(ksym, 0664, ksym_show, ksym_store);
164
165static ssize_t cpu_pmu_method_show(struct device *dev, struct device_attribute *attr, char *buf);
166static ssize_t cpu_pmu_method_store(struct device *dev, struct device_attribute *attr, const char *buf,
167 size_t count);
168static DEVICE_ATTR(cpu_pmu_method, 0664, cpu_pmu_method_show, cpu_pmu_method_store);
169
170static ssize_t cpu_pm_pmu_reconfig_show(struct device *dev,
171 struct device_attribute *attr,
172 char *buf);
173static ssize_t cpu_pm_pmu_reconfig_store(struct device *dev,
174 struct device_attribute *attr,
175 const char *buf,
176 size_t count);
177static DEVICE_ATTR(cpu_pm_pmu_reconfig,
178 0664,
179 cpu_pm_pmu_reconfig_show,
180 cpu_pm_pmu_reconfig_store);
181
182#ifdef PR_CPU_NOTIFY
183int met_cpu_notify;
184static ssize_t cpu_notify_show(struct device *dev, struct device_attribute *attr, char *buf);
185static ssize_t cpu_notify_store(struct device *dev, struct device_attribute *attr, const char *buf,
186 size_t count);
187static DEVICE_ATTR(cpu_notify, 0664, cpu_notify_show, cpu_notify_store);
188#endif
189
190#ifdef CONFIG_CPU_FREQ
191static ssize_t dvfs_show(struct device *dev, struct device_attribute *attr, char *buf);
192static ssize_t dvfs_store(struct device *dev, struct device_attribute *attr, const char *buf,
193 size_t count);
194static DEVICE_ATTR(dvfs, 0664, dvfs_show, dvfs_store);
195#endif
196
197static ssize_t suspend_compensation_enable_show(struct device *dev, struct device_attribute *attr, char *buf);
198static ssize_t suspend_compensation_enable_store(struct device *dev, struct device_attribute *attr,
199 const char *buf, size_t count);
200static DEVICE_ATTR(suspend_compensation_enable, 0664, suspend_compensation_enable_show,
201 suspend_compensation_enable_store);
202
203static ssize_t suspend_compensation_flag_show(struct device *dev, struct device_attribute *attr, char *buf);
204static DEVICE_ATTR(suspend_compensation_flag, 0444, suspend_compensation_flag_show, NULL);
205
206static ssize_t ipi_test_store(struct device *dev, struct device_attribute *attr, const char *buf,
207 size_t count);
208static DEVICE_ATTR(ipi_test, 0220, NULL, ipi_test_store);
209
210static const struct file_operations met_file_ops = {
211 .owner = THIS_MODULE
212};
213
214struct miscdevice met_device = {
215 .minor = MISC_DYNAMIC_MINOR,
216 .name = "met",
217 .mode = 0664,
218 .fops = &met_file_ops
219};
220EXPORT_SYMBOL(met_device);
221
222static int met_run(void)
223{
224 sampler_start();
225#ifdef MET_USER_EVENT_SUPPORT
226 bltab.flag &= (~MET_CLASS_ALL);
227#endif
228 ondiemet_start();
229 return 0;
230}
231
232static void met_stop(void)
233{
234#ifdef MET_USER_EVENT_SUPPORT
235 bltab.flag |= MET_CLASS_ALL;
236#endif
237 sampler_stop();
238 /* the met.ko will be use by script "cat ...", release it */
239 if ((ondiemet_module[ONDIEMET_SSPM] == 0) || (sspm_buffer_size == -1))
240 ondiemet_log_manager_stop();
241 ondiemet_stop();
242 ondiemet_extract();
243}
244
245static ssize_t ver_show(struct device *dev, struct device_attribute *attr, char *buf)
246{
247 int i;
248
249 mutex_lock(&dev->mutex);
250 i = snprintf(buf, PAGE_SIZE, "%s\n", MET_BACKEND_VERSION);
251 mutex_unlock(&dev->mutex);
252 return i;
253}
254
255static ssize_t devices_show(struct device *dev, struct device_attribute *attr, char *buf)
256{
257 int len, total_len = 0;
258 struct metdevice *c = NULL;
259
260 mutex_lock(&dev->mutex);
261 list_for_each_entry(c, &met_list, list) {
262 len = 0;
263 if (c->type == MET_TYPE_PMU)
264 len = snprintf(buf, PAGE_SIZE - total_len, "pmu/%s:0\n", c->name);
265 else if (c->type == MET_TYPE_BUS)
266 len = snprintf(buf, PAGE_SIZE - total_len, "bus/%s:0\n", c->name);
267 else if (c->type == MET_TYPE_MISC)
268 len = snprintf(buf, PAGE_SIZE - total_len, "misc/%s:0\n", c->name);
269
270 if (c->ondiemet_mode == 0) {
271 if (c->process_argument)
272 buf[len - 2]++;
273 } else if (c->ondiemet_mode == 1) {
274 if (c->ondiemet_process_argument)
275 buf[len - 2]++;
276 } else if (c->ondiemet_mode == 2) {
277 if (c->process_argument)
278 buf[len - 2]++;
279 if (c->ondiemet_process_argument)
280 buf[len - 2]++;
281 }
282
283 buf += len;
284 total_len += len;
285 }
286
287 mutex_unlock(&dev->mutex);
288 return total_len;
289}
290
291static char met_platform[16] = "none";
292static ssize_t plf_show(struct device *dev, struct device_attribute *attr, char *buf)
293{
294 int i;
295
296 mutex_lock(&dev->mutex);
297 i = snprintf(buf, PAGE_SIZE, "%s\n", met_platform);
298 mutex_unlock(&dev->mutex);
299 return i;
300}
301
302static unsigned int met_chip_id = 0;
303static ssize_t chip_id_show(struct device *dev, struct device_attribute *attr, char *buf)
304{
305 int i;
306
307 mutex_lock(&dev->mutex);
308 i = snprintf(buf, PAGE_SIZE, "0x%08X\n", met_chip_id);
309 mutex_unlock(&dev->mutex);
310 return i;
311}
312
313static char met_topology[64] = "none";
314static ssize_t core_topology_show(struct device *dev, struct device_attribute *attr, char *buf)
315{
316 int i;
317
318 mutex_lock(&dev->mutex);
319 i = snprintf(buf, PAGE_SIZE, "%s\n", met_topology);
320 mutex_unlock(&dev->mutex);
321 return i;
322}
323
324static ssize_t ctrl_show(struct device *dev, struct device_attribute *attr, char *buf)
325{
326 return snprintf(buf, PAGE_SIZE, "%d\n", ctrl_flags);
327}
328
329static ssize_t ctrl_store(struct device *dev, struct device_attribute *attr, const char *buf,
330 size_t count)
331{
332 unsigned int value = 0;
333
334 if (met_parse_num(buf, &value, count) < 0)
335 return -EINVAL;
336
337 ctrl_flags = value;
338 return count;
339}
340
341static ssize_t cpu_pmu_method_show(struct device *dev, struct device_attribute *attr, char *buf)
342{
343 return snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_pmu_method);
344}
345
346static ssize_t cpu_pmu_method_store(struct device *dev, struct device_attribute *attr, const char *buf,
347 size_t count)
348{
349 unsigned int value;
350
351 if (met_parse_num(buf, &value, count) < 0)
352 return -EINVAL;
353
354 met_cpu_pmu_method = value;
355 return count;
356}
357
358static ssize_t cpu_pm_pmu_reconfig_show(struct device *dev,
359 struct device_attribute *attr,
360 char *buf)
361{
362 return snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_pm_pmu_reconfig);
363}
364
365static ssize_t cpu_pm_pmu_reconfig_store(struct device *dev,
366 struct device_attribute *attr,
367 const char *buf,
368 size_t count)
369{
370 unsigned int value;
371
372 if (met_parse_num(buf, &value, count) < 0)
373 return -EINVAL;
374
375 met_cpu_pm_pmu_reconfig = value;
376 return count;
377}
378
379static void _test_trace_ipi_raise(void *info)
380{
381 unsigned int *cpu = (unsigned int *)info;
382 void (*arch_send_call_function_single_ipi_sym)(int cpu) = NULL;
383
384 arch_send_call_function_single_ipi_sym = (void *)symbol_get(met_arch_send_call_function_single_ipi);
385 if (arch_send_call_function_single_ipi_sym)
386 arch_send_call_function_single_ipi_sym(*cpu);
387}
388
389
390static ssize_t ipi_test_store(struct device *dev, struct device_attribute *attr, const char *buf,
391 size_t count)
392{
393 int this_cpu = smp_processor_id();
394 unsigned int cpu = 0;
395 unsigned int value;
396
397 if (met_parse_num(buf, &value, count) < 0)
398 return -EINVAL;
399
400 cpu = value;
401 if (cpu == this_cpu)
402 _test_trace_ipi_raise(&cpu);
403 else
404 met_smp_call_function_single_symbol(cpu, _test_trace_ipi_raise, &cpu, 1);
405
406 return count;
407}
408
409
410#if defined(MET_BOOT_MSG)
411char met_boot_msg_tmp[256];
412char met_boot_msg[PAGE_SIZE];
413int met_boot_msg_idx;
414
415int pr_bootmsg(int str_len, char *str)
416{
417 if (met_boot_msg_idx+str_len+1 > PAGE_SIZE)
418 return -1;
419 memcpy(met_boot_msg+met_boot_msg_idx, str, str_len);
420 met_boot_msg_idx += str_len;
421 return 0;
422}
423
424static ssize_t bootmsg_show(struct device *dev, struct device_attribute *attr, char *buf)
425{
426 int i;
427
428 mutex_lock(&dev->mutex);
429 i = snprintf(buf, PAGE_SIZE, "%s\n", met_boot_msg);
430 mutex_unlock(&dev->mutex);
431 return i;
432}
433
434static DEVICE_ATTR_RO(bootmsg);
435EXPORT_SYMBOL(met_boot_msg_tmp);
436EXPORT_SYMBOL(pr_bootmsg);
437#endif
438
439static ssize_t spr_show(struct device *dev, struct device_attribute *attr, char *buf)
440{
441 int i;
442
443 mutex_lock(&dev->mutex);
444 i = snprintf(buf, PAGE_SIZE, "%d\n", sample_rate);
445 mutex_unlock(&dev->mutex);
446 return i;
447}
448
449static ssize_t spr_store(struct device *dev, struct device_attribute *attr, const char *buf,
450 size_t count)
451{
452 int value;
453 struct metdevice *c = NULL;
454
455 mutex_lock(&dev->mutex);
456
457 if ((run == 1) || (count == 0) || (buf == NULL)) {
458 mutex_unlock(&dev->mutex);
459 return -EINVAL;
460 }
461 if (kstrtoint(buf, 0, &value) != 0) {
462 mutex_unlock(&dev->mutex);
463 return -EINVAL;
464 }
465
466 if ((value < 0) || (value > 10000)) {
467 mutex_unlock(&dev->mutex);
468 return -EINVAL;
469 }
470
471 calc_timer_value(value);
472
473 list_for_each_entry(c, &met_list, list) {
474 if (c->polling_interval > 0)
475 c->polling_count_reload = ((c->polling_interval * sample_rate) - 1) / 1000;
476 else
477 c->polling_count_reload = 0;
478 }
479
480 mutex_unlock(&dev->mutex);
481
482 return count;
483}
484
485static ssize_t run_show(struct device *dev, struct device_attribute *attr, char *buf)
486{
487 int i;
488
489 mutex_lock(&dev->mutex);
490 i = snprintf(buf, PAGE_SIZE, "%d\n", run);
491 mutex_unlock(&dev->mutex);
492 return i;
493}
494
495static ssize_t run_store(struct device *dev, struct device_attribute *attr, const char *buf,
496 size_t count)
497{
498 int value;
499
500 mutex_lock(&dev->mutex);
501
502 if ((count == 0) || (buf == NULL)) {
503 mutex_unlock(&dev->mutex);
504 return -EINVAL;
505 }
506 if (kstrtoint(buf, 0, &value) != 0) {
507 mutex_unlock(&dev->mutex);
508 return -EINVAL;
509 }
510
511 switch (value) {
512 case 1:
513 if (run != 1) {
514 run = 1;
515 met_run();
516 }
517 break;
518 case 0:
519 if (run != 0) {
520 if (run == 1) {
521 met_stop();
522#ifdef MET_USER_EVENT_SUPPORT
523#ifdef CONFIG_MET_MODULE
524 met_save_dump_buffer_real("/data/trace.dump");
525#else
526 met_save_dump_buffer("/data/trace.dump");
527#endif
528#endif
529 run = 0;
530 } else
531 /* run == -1 */
532 run = 0;
533 }
534 break;
535 case -1:
536 if (run != -1) {
537 if (run == 1)
538 met_stop();
539
540 run = -1;
541 }
542 break;
543 default:
544 mutex_unlock(&dev->mutex);
545 return -EINVAL;
546 }
547
548 mutex_unlock(&dev->mutex);
549
550 return count;
551}
552
553static unsigned int met_ksym_addr;
554static char met_func_name[512];
555static ssize_t ksym_show(struct device *dev, struct device_attribute *attr, char *buf)
556{
557 int i;
558 int len = 0;
559 int idx = 0;
560
561 mutex_lock(&dev->mutex);
562 if (met_ksym_addr != 0)
563 len = sprint_symbol_no_offset(met_func_name, met_ksym_addr);
564 if (len != 0) {
565 for (idx = 0; idx < 512; idx++)
566 if (met_func_name[idx] == ' ')
567 met_func_name[idx] = '\0';
568 i = snprintf(buf, PAGE_SIZE, "%s\n", met_func_name);
569 } else
570 i = snprintf(buf, PAGE_SIZE, "ksymlookup fail(%x)\n", met_ksym_addr);
571
572 mutex_unlock(&dev->mutex);
573 return i;
574}
575
576static ssize_t ksym_store(struct device *dev, struct device_attribute *attr, const char *buf,
577 size_t count)
578{
579 mutex_lock(&dev->mutex);
580
581 if ((count == 0) || (buf == NULL)) {
582 mutex_unlock(&dev->mutex);
583 return -EINVAL;
584 }
585 if (kstrtoint(buf, 16, &met_ksym_addr) != 0) {
586 mutex_unlock(&dev->mutex);
587 return -EINVAL;
588 }
589
590 mutex_unlock(&dev->mutex);
591
592 return count;
593}
594
595#if defined(PR_CPU_NOTIFY)
596static ssize_t cpu_notify_show(struct device *dev, struct device_attribute *attr, char *buf)
597{
598 int i;
599
600 i = snprintf(buf, PAGE_SIZE, "%d\n", met_cpu_notify);
601 return i;
602}
603
604static ssize_t cpu_notify_store(struct device *dev, struct device_attribute *attr, const char *buf,
605 size_t count)
606{
607 if ((count == 0) || (buf == NULL))
608 return -EINVAL;
609
610 if (kstrtoint(buf, 0, &met_cpu_notify) != 0)
611 return -EINVAL;
612
613 return count;
614}
615#endif
616
617#ifdef CONFIG_CPU_FREQ
618static ssize_t dvfs_show(struct device *dev, struct device_attribute *attr, char *buf)
619{
620 int i;
621
622 i = snprintf(buf, PAGE_SIZE, "%d\n", 0);
623 return i;
624}
625
626static ssize_t dvfs_store(struct device *dev, struct device_attribute *attr, const char *buf,
627 size_t count)
628{
629 return count;
630}
631#endif
632
633static ssize_t suspend_compensation_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
634{
635 int ret;
636
637 ret = snprintf(buf, PAGE_SIZE, "%d\n", met_suspend_compensation_mode);
638
639 return ret;
640}
641
642static ssize_t suspend_compensation_enable_store(struct device *dev, struct device_attribute *attr,
643 const char *buf, size_t count)
644{
645 int value;
646
647 if ((count == 0) || (buf == NULL))
648 return -EINVAL;
649
650 if (kstrtoint(buf, 0, &value) != 0)
651 return -EINVAL;
652
653 if (value < 0)
654 return -EINVAL;
655
656 met_suspend_compensation_mode = value;
657
658 return count;
659}
660
661static ssize_t suspend_compensation_flag_show(struct device *dev, struct device_attribute *attr, char *buf)
662{
663 int ret;
664
665 ret = snprintf(buf, PAGE_SIZE, "%d\n", met_suspend_compensation_flag);
666
667 return ret;
668}
669
670static ssize_t hash_show(struct device *dev, struct device_attribute *attr, char *buf)
671{
672 return 0;
673}
674
675static ssize_t hash_store(struct device *dev, struct device_attribute *attr, const char *buf,
676 size_t count)
677{
678 return 0;
679}
680
681static DEVICE_ATTR(hash, 0664, hash_show, hash_store);
682
683static ssize_t mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
684{
685 struct metdevice *c = NULL;
686
687 list_for_each_entry(c, &met_list, list) {
688 if (c->kobj == kobj)
689 break;
690 }
691 if (c == NULL)
692 return -ENOENT;
693
694 return snprintf(buf, PAGE_SIZE, "%d\n", c->mode);
695}
696
697static ssize_t mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf,
698 size_t n)
699{
700 struct metdevice *c = NULL;
701
702 list_for_each_entry(c, &met_list, list) {
703 if (c->kobj == kobj)
704 break;
705 }
706 if (c == NULL)
707 return -ENOENT;
708
709 if (kstrtoint(buf, 0, &(c->mode)) != 0)
710 return -EINVAL;
711
712 return n;
713}
714
715static struct kobj_attribute mode_attr = __ATTR(mode, 0664, mode_show, mode_store);
716
717static ssize_t ondiemet_mode_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
718{
719 struct metdevice *c = NULL;
720
721 list_for_each_entry(c, &met_list, list) {
722 if (c->kobj == kobj)
723 break;
724 }
725 if (c == NULL)
726 return -ENOENT;
727
728 return snprintf(buf, PAGE_SIZE, "%d\n", c->ondiemet_mode);
729}
730
731static ssize_t ondiemet_mode_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf,
732 size_t n)
733{
734 struct metdevice *c = NULL;
735
736 list_for_each_entry(c, &met_list, list) {
737 if (c->kobj == kobj)
738 break;
739 }
740 if (c == NULL)
741 return -ENOENT;
742
743 if (kstrtoint(buf, 0, &(c->ondiemet_mode)) != 0)
744 return -EINVAL;
745
746 return n;
747}
748
749static struct kobj_attribute ondiemet_mode_attr = __ATTR(ondiemet_mode, 0664, ondiemet_mode_show, ondiemet_mode_store);
750
751static ssize_t polling_interval_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
752{
753 int interval = 1;
754 struct metdevice *c = NULL;
755
756 list_for_each_entry(c, &met_list, list) {
757 if (c->kobj == kobj)
758 break;
759 }
760 if (c == NULL)
761 return -ENOENT;
762
763 if (c->polling_interval)
764 interval = c->polling_interval;
765
766 return snprintf(buf, PAGE_SIZE, "%d\n", interval);
767}
768
769static ssize_t polling_interval_store(struct kobject *kobj, struct kobj_attribute *attr,
770 const char *buf, size_t n)
771{
772 struct metdevice *c = NULL;
773
774 list_for_each_entry(c, &met_list, list) {
775 if (c->kobj == kobj)
776 break;
777 }
778 if (c == NULL)
779 return -ENOENT;
780
781 if (kstrtoint(buf, 0, &(c->polling_interval)) != 0)
782 return -EINVAL;
783
784 if (c->polling_interval > 0)
785 c->polling_count_reload = ((c->polling_interval * sample_rate) - 1) / 1000;
786 else
787 c->polling_count_reload = 0;
788
789 return n;
790}
791
792static struct kobj_attribute polling_interval_attr =
793__ATTR(polling_ms, 0664, polling_interval_show, polling_interval_store);
794
795static ssize_t header_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
796{
797 struct metdevice *c = NULL;
798 ssize_t count = 0;
799
800 list_for_each_entry(c, &met_list, list) {
801 if (c->kobj == kobj)
802 break;
803 }
804 if (c == NULL)
805 return -ENOENT;
806
807 if (c->ondiemet_mode == 0) {
808 if ((c->mode) && (c->print_header))
809 return c->print_header(buf, PAGE_SIZE);
810 } else if (c->ondiemet_mode == 1) {
811 if ((c->mode) && (c->ondiemet_print_header))
812 return c->ondiemet_print_header(buf, PAGE_SIZE);
813 } else if (c->ondiemet_mode == 2) {
814 if ((c->mode) && (c->print_header))
815 count = c->print_header(buf, PAGE_SIZE);
816 if (count < PAGE_SIZE) {
817 if ((c->mode) && (c->ondiemet_print_header))
818 count += c->ondiemet_print_header(buf+count, PAGE_SIZE - count);
819 }
820 return count;
821 }
822
823 return 0;
824}
825
826static struct kobj_attribute header_attr = __ATTR(header, 0444, header_show, NULL);
827
828static ssize_t help_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
829{
830 struct metdevice *c = NULL;
831 ssize_t count = 0;
832
833 list_for_each_entry(c, &met_list, list) {
834 if (c->kobj == kobj)
835 break;
836 }
837 if (c == NULL)
838 return -ENOENT;
839
840 if (c->ondiemet_mode == 0) {
841 if (c->print_help)
842 return c->print_help(buf, PAGE_SIZE);
843 } else if (c->ondiemet_mode == 1) {
844 if (c->ondiemet_print_help)
845 return c->ondiemet_print_help(buf, PAGE_SIZE);
846 } else if (c->ondiemet_mode == 2) {
847 if (c->print_help)
848 count = c->print_help(buf, PAGE_SIZE);
849 if (count < PAGE_SIZE) {
850 if (c->ondiemet_print_help)
851 count += c->ondiemet_print_help(buf+count, PAGE_SIZE - count);
852 }
853 return count;
854 }
855
856 return 0;
857}
858
859static struct kobj_attribute help_attr = __ATTR(help, 0444, help_show, NULL);
860
861static int argu_status = -1;
862static ssize_t argu_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf,
863 size_t n)
864{
865 int ret = 0;
866 struct metdevice *c = NULL;
867
868 argu_status = -1;
869
870 list_for_each_entry(c, &met_list, list) {
871 if (c->kobj == kobj)
872 break;
873 }
874 if (c == NULL)
875 return -ENOENT;
876
877 if (c->ondiemet_mode == 0) {
878 if (c->process_argument)
879 ret = c->process_argument(buf, (int)n);
880 } else if (c->ondiemet_mode == 1) {
881 if (c->ondiemet_process_argument)
882 ret = c->ondiemet_process_argument(buf, (int)n);
883 } else if (c->ondiemet_mode == 2) {
884 if (c->process_argument)
885 ret = c->process_argument(buf, (int)n);
886 if (c->ondiemet_process_argument)
887 ret = c->ondiemet_process_argument(buf, (int)n);
888 }
889
890 if (ret != 0)
891 return -EINVAL;
892
893 argu_status = 0;
894 return n;
895}
896
897static ssize_t argu_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
898{
899 return snprintf(buf, PAGE_SIZE, "%d\n", argu_status);
900}
901
902static struct kobj_attribute argu_attr = __ATTR(argu, 0664, argu_show, argu_store);
903
904static ssize_t reset_store(struct kobject *kobj,
905 struct kobj_attribute *attr,
906 const char *buf,
907 size_t n)
908{
909 int ret = 0;
910 struct metdevice *c = NULL;
911
912 list_for_each_entry(c, &met_list, list) {
913 if (c->kobj == kobj)
914 break;
915 }
916 if (c == NULL)
917 return -ENOENT;
918
919 if (c->ondiemet_mode == 0) {
920 if (c->reset)
921 ret = c->reset();
922 else
923 c->mode = 0;
924 } else if (c->ondiemet_mode == 1) {
925 if (c->ondiemet_reset)
926 ret = c->ondiemet_reset();
927 } else if (c->ondiemet_mode == 2) {
928 if (c->reset)
929 ret = c->reset();
930 else
931 c->mode = 0;
932 if (c->ondiemet_reset)
933 ret = c->ondiemet_reset();
934 }
935
936 if (ret != 0)
937 return -EINVAL;
938
939 return n;
940}
941
942static struct kobj_attribute reset_attr = __ATTR(reset, 0220, NULL, reset_store);
943
944static ssize_t header_read_again_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
945{
946 struct metdevice *c = NULL;
947
948 list_for_each_entry(c, &met_list, list) {
949 if (c->kobj == kobj)
950 break;
951 }
952 if (c == NULL)
953 return -ENOENT;
954
955 return snprintf(buf, PAGE_SIZE, "%d\n", c->header_read_again);
956}
957
958static struct kobj_attribute header_read_again_attr = __ATTR(header_read_again, 0664, header_read_again_show, NULL);
959
960
961int met_register(struct metdevice *met)
962{
963 int ret, cpu;
964 struct metdevice *c;
965
966 list_for_each_entry(c, &met_list, list) {
967 if (!strcmp(c->name, met->name))
968 return -EEXIST;
969 }
970
971 PR_BOOTMSG("met_register %s ...\n", met->name);
972
973 INIT_LIST_HEAD(&met->list);
974
975 /* Allocate timer count for per CPU */
976 met->polling_count = alloc_percpu(int);
977 if (met->polling_count == NULL)
978 return -EINVAL;
979
980 for_each_possible_cpu(cpu)
981 *(per_cpu_ptr(met->polling_count, cpu)) = 0;
982
983 if (met->polling_interval > 0) {
984 ret = ((met->polling_interval * sample_rate) - 1) / 1000;
985 met->polling_count_reload = ret;
986 } else
987 met->polling_count_reload = 0;
988
989 met->kobj = NULL;
990
991 if (met->type == MET_TYPE_BUS)
992 met->kobj = kobject_create_and_add(met->name, kobj_bus);
993 else if (met->type == MET_TYPE_PMU)
994 met->kobj = kobject_create_and_add(met->name, kobj_pmu);
995 else if (met->type == MET_TYPE_MISC)
996 met->kobj = kobject_create_and_add(met->name, kobj_misc);
997 else {
998 ret = -EINVAL;
999 goto err_out;
1000 }
1001
1002 if (met->kobj == NULL) {
1003 ret = -EINVAL;
1004 goto err_out;
1005 }
1006
1007 if (met->create_subfs) {
1008 ret = met->create_subfs(met->kobj);
1009 if (ret)
1010 goto err_out;
1011 }
1012
1013 ret = sysfs_create_file(met->kobj, &mode_attr.attr);
1014 if (ret)
1015 goto err_out;
1016
1017
1018 ret = sysfs_create_file(met->kobj, &ondiemet_mode_attr.attr);
1019 if (ret)
1020 goto err_out;
1021
1022 ret = sysfs_create_file(met->kobj, &polling_interval_attr.attr);
1023 if (ret)
1024 goto err_out;
1025
1026 ret = sysfs_create_file(met->kobj, &header_read_again_attr.attr);
1027 if (ret)
1028 goto err_out;
1029
1030 if (met->print_header || met->ondiemet_print_header) {
1031 ret = sysfs_create_file(met->kobj, &header_attr.attr);
1032 if (ret)
1033 goto err_out;
1034 }
1035
1036 if (met->print_help || met->ondiemet_print_help) {
1037 ret = sysfs_create_file(met->kobj, &help_attr.attr);
1038 if (ret)
1039 goto err_out;
1040 }
1041
1042 if (met->process_argument || met->ondiemet_process_argument) {
1043 ret = sysfs_create_file(met->kobj, &argu_attr.attr);
1044 if (ret)
1045 goto err_out;
1046 }
1047
1048 if (met->reset) {
1049 ret = sysfs_create_file(met->kobj, &reset_attr.attr);
1050 if (ret)
1051 goto err_out;
1052 }
1053
1054 spin_lock_init(&met->my_lock);
1055
1056 list_add(&met->list, &met_list);
1057 return 0;
1058
1059 err_out:
1060
1061 if (met->polling_count)
1062 free_percpu(met->polling_count);
1063
1064 if (met->kobj) {
1065 kobject_del(met->kobj);
1066 kobject_put(met->kobj);
1067 met->kobj = NULL;
1068 }
1069
1070 return ret;
1071}
1072EXPORT_SYMBOL(met_register);
1073
1074int met_deregister(struct metdevice *met)
1075{
1076 struct metdevice *c = NULL;
1077
1078 list_for_each_entry(c, &met_list, list) {
1079 if (c == met)
1080 break;
1081 }
1082 if (c != met)
1083 return -ENOENT;
1084
1085 if (met->print_header || met->ondiemet_print_header)
1086 sysfs_remove_file(met->kobj, &header_attr.attr);
1087
1088 if (met->print_help || met->ondiemet_print_help)
1089 sysfs_remove_file(met->kobj, &help_attr.attr);
1090
1091 if (met->process_argument || met->ondiemet_process_argument)
1092 sysfs_remove_file(met->kobj, &argu_attr.attr);
1093
1094 sysfs_remove_file(met->kobj, &reset_attr.attr);
1095 sysfs_remove_file(met->kobj, &header_read_again_attr.attr);
1096 sysfs_remove_file(met->kobj, &polling_interval_attr.attr);
1097 sysfs_remove_file(met->kobj, &mode_attr.attr);
1098 sysfs_remove_file(met->kobj, &ondiemet_mode_attr.attr);
1099
1100 if (met->delete_subfs)
1101 met->delete_subfs();
1102
1103 kobject_del(met->kobj);
1104 kobject_put(met->kobj);
1105 met->kobj = NULL;
1106
1107 if (met->polling_count)
1108 free_percpu(met->polling_count);
1109
1110 list_del(&met->list);
1111 return 0;
1112}
1113EXPORT_SYMBOL(met_deregister);
1114
1115int met_set_platform(const char *plf_name, int flag)
1116{
1117 strncpy(met_platform, plf_name, sizeof(met_platform) - 1);
1118#if 0
1119 int ret;
1120
1121 if (flag) {
1122 ret = device_create_file(met_device.this_device, &dev_attr_plf);
1123 if (ret != 0) {
1124 pr_debug("can not create device file: plf\n");
1125 return ret;
1126 }
1127 strncpy(met_platform, plf_name, sizeof(met_platform) - 1);
1128 } else
1129 device_remove_file(met_device.this_device, &dev_attr_plf);
1130
1131#endif
1132 return 0;
1133}
1134EXPORT_SYMBOL(met_set_platform);
1135
1136char *met_get_platform(void)
1137{
1138 return met_platform;
1139}
1140EXPORT_SYMBOL(met_get_platform);
1141
1142int met_set_chip_id(const unsigned int chip_id)
1143{
1144 met_chip_id = chip_id;
1145
1146 return 0;
1147}
1148EXPORT_SYMBOL(met_set_chip_id);
1149
1150const unsigned int met_get_chip_id(void)
1151{
1152 return met_chip_id;
1153}
1154EXPORT_SYMBOL(met_get_chip_id);
1155
1156int met_set_topology(const char *topology_name, int flag)
1157{
1158 strncpy(met_topology, topology_name, sizeof(met_topology) - 1);
1159#if 0
1160 int ret;
1161
1162 if (flag) {
1163 ret = device_create_file(met_device.this_device, &dev_attr_core_topology);
1164 if (ret != 0) {
1165 pr_debug("can not create device file: topology\n");
1166 return ret;
1167 }
1168 strncpy(met_topology, topology_name, sizeof(met_topology) - 1);
1169 } else {
1170 device_remove_file(met_device.this_device, &dev_attr_core_topology);
1171 }
1172#endif
1173 return 0;
1174}
1175EXPORT_SYMBOL(met_set_topology);
1176
1177#include "met_struct.h"
1178
1179void force_sample(void *unused)
1180{
1181 int cpu;
1182 unsigned long long stamp;
1183 struct metdevice *c;
1184 struct met_cpu_struct *met_cpu_ptr;
1185
1186 if ((run != 1) || (sample_rate == 0))
1187 return;
1188
1189 /* to avoid met tag is coming after __met_hrtimer_stop and before run=-1 */
1190 met_cpu_ptr = this_cpu_ptr(&met_cpu);
1191 if (met_cpu_ptr->work_enabled == 0)
1192 return;
1193
1194 cpu = smp_processor_id();
1195
1196 stamp = cpu_clock(cpu);
1197
1198 list_for_each_entry(c, &met_list, list) {
1199 if (c->ondiemet_mode == 0) {
1200 if ((c->mode != 0) && (c->tagged_polling != NULL))
1201 c->tagged_polling(stamp, 0);
1202 } else if (c->ondiemet_mode == 1) {
1203 if ((c->mode != 0) && (c->ondiemet_tagged_polling != NULL))
1204 c->ondiemet_tagged_polling(stamp, 0);
1205 } else if (c->ondiemet_mode == 2) {
1206 if ((c->mode != 0) && (c->tagged_polling != NULL))
1207 c->tagged_polling(stamp, 0);
1208 if ((c->mode != 0) && (c->ondiemet_tagged_polling != NULL))
1209 c->ondiemet_tagged_polling(stamp, 0);
1210 }
1211 }
1212}
1213
1214#define MET_SUSPEND_HAND
1215#ifdef MET_SUSPEND_HAND
1216static struct syscore_ops met_hrtimer_ops = {
1217 .suspend = met_hrtimer_suspend,
1218 .resume = met_hrtimer_resume,
1219};
1220#endif
1221
1222int fs_reg(int met_minor)
1223{
1224 int ret = -1;
1225
1226 ctrl_flags = 0;
1227 met_mode = 0;
1228
1229#ifdef MET_SUSPEND_HAND
1230 /* suspend/resume function handle register */
1231 register_syscore_ops(&met_hrtimer_ops);
1232#endif
1233
1234 calc_timer_value(sample_rate);
1235
1236 if ( met_minor != -1)
1237 met_device.minor = met_minor;
1238 ret = misc_register(&met_device);
1239 if (ret != 0) {
1240 pr_debug("misc register failed, minor = %d \n", met_device.minor);
1241 return ret;
1242 }
1243
1244 /* dma map config */
1245 /* arch_setup_dma_ops(met_device.this_device, 0, 0, NULL, false); */
1246 met_arch_setup_dma_ops_symbol(met_device.this_device);
1247
1248 ret = device_create_file(met_device.this_device, &dev_attr_ksym);
1249 if (ret != 0) {
1250 pr_debug("can not create device file: ksym\n");
1251 return ret;
1252 }
1253
1254 ret = device_create_file(met_device.this_device, &dev_attr_run);
1255 if (ret != 0) {
1256 pr_debug("can not create device file: run\n");
1257 return ret;
1258 }
1259
1260#if defined(PR_CPU_NOTIFY)
1261 ret = device_create_file(met_device.this_device, &dev_attr_cpu_notify);
1262 if (ret != 0) {
1263 pr_debug("can not create device file: cpu_notify\n");
1264 return ret;
1265 }
1266#endif
1267
1268#ifdef CONFIG_CPU_FREQ
1269 ret = device_create_file(met_device.this_device, &dev_attr_dvfs);
1270 if (ret != 0) {
1271 pr_debug("can not create device file: dvfs\n");
1272 return ret;
1273 }
1274#endif
1275
1276 ret = device_create_file(met_device.this_device, &dev_attr_suspend_compensation_enable);
1277 if (ret != 0) {
1278 pr_debug("can not create device file: suspend_compensation_enable\n");
1279 return ret;
1280 }
1281
1282 ret = device_create_file(met_device.this_device, &dev_attr_suspend_compensation_flag);
1283 if (ret != 0) {
1284 pr_debug("can not create device file: suspend_compensation_enable\n");
1285 return ret;
1286 }
1287
1288 ret = device_create_file(met_device.this_device, &dev_attr_ver);
1289 if (ret != 0) {
1290 pr_debug("can not create device file: ver\n");
1291 return ret;
1292 }
1293
1294 ret = device_create_file(met_device.this_device, &dev_attr_devices);
1295 if (ret != 0) {
1296 pr_debug("can not create device file: devices\n");
1297 return ret;
1298 }
1299
1300 ret = device_create_file(met_device.this_device, &dev_attr_ctrl);
1301 if (ret != 0) {
1302 pr_debug("can not create device file: ctrl\n");
1303 return ret;
1304 }
1305
1306 ret = device_create_file(met_device.this_device, &dev_attr_cpu_pmu_method);
1307 if (ret != 0) {
1308 pr_debug("can not create device file: cpu_pmu_method\n");
1309 return ret;
1310 }
1311
1312 ret = device_create_file(met_device.this_device, &dev_attr_cpu_pm_pmu_reconfig);
1313 if (ret != 0) {
1314 pr_debug("can not create device file: cpu_pm_pmu_reconfig\n");
1315 return ret;
1316 }
1317
1318#if defined(MET_BOOT_MSG)
1319 ret = device_create_file(met_device.this_device, &dev_attr_bootmsg);
1320 if (ret != 0) {
1321 pr_debug("can not create device file: bootmsg\n");
1322 return ret;
1323 }
1324#endif
1325
1326 ret = device_create_file(met_device.this_device, &dev_attr_sample_rate);
1327 if (ret != 0) {
1328 pr_debug("can not create device file: sample_rate\n");
1329 return ret;
1330 }
1331
1332 ret = device_create_file(met_device.this_device, &dev_attr_core_topology);
1333 if (ret != 0) {
1334 pr_debug("can not create device file: topology\n");
1335 return ret;
1336 }
1337
1338 ret = device_create_file(met_device.this_device, &dev_attr_plf);
1339 if (ret != 0) {
1340 pr_debug("can not create device file: plf\n");
1341 return ret;
1342 }
1343
1344 ret = device_create_file(met_device.this_device, &dev_attr_chip_id);
1345 if (ret != 0) {
1346 pr_debug("can not create device file: chip_id\n");
1347 return ret;
1348 }
1349
1350 ret = device_create_file(met_device.this_device, &dev_attr_hash);
1351 if (ret != 0) {
1352 pr_debug("can not create device file: hash\n");
1353 return ret;
1354 }
1355
1356 ret = device_create_file(met_device.this_device, &dev_attr_ipi_test);
1357 if (ret != 0) {
1358 pr_debug("can not create device file: ipi_test\n");
1359 return ret;
1360 }
1361
1362 kobj_misc = kobject_create_and_add("misc", &met_device.this_device->kobj);
1363 if (kobj_misc == NULL) {
1364 pr_debug("can not create kobject: kobj_misc\n");
1365 return -1;
1366 }
1367
1368 kobj_pmu = kobject_create_and_add("pmu", &met_device.this_device->kobj);
1369 if (kobj_pmu == NULL) {
1370 pr_debug("can not create kobject: kobj_pmu\n");
1371 return -1;
1372 }
1373
1374 kobj_bus = kobject_create_and_add("bus", &met_device.this_device->kobj);
1375 if (kobj_bus == NULL) {
1376 pr_debug("can not create kobject: kobj_bus\n");
1377 return -1;
1378 }
1379
1380 met_register(&met_cookie);
1381 met_register(&met_cpupmu);
1382 met_register(&met_memstat);
1383 met_register(&met_switch);
1384#ifdef MET_EVENT_POWER_SUPPORT
1385 met_register(&met_trace_event);
1386 met_ext_api.met_pm_qos_update_request = pm_qos_update_request;
1387 met_ext_api.met_pm_qos_update_target = pm_qos_update_target;
1388#endif
1389
1390 met_register(&met_dummy_header);
1391
1392 met_register(&met_backlight);
1393 met_ext_api.enable_met_backlight_tag = enable_met_backlight_tag_real;
1394 met_ext_api.output_met_backlight_tag = output_met_backlight_tag_real;
1395
1396#ifdef MET_USER_EVENT_SUPPORT
1397 tag_reg((struct file_operations * const) met_device.fops, &met_device.this_device->kobj);
1398#endif
1399
1400 met_register(&met_stat);
1401
1402 ondiemet_log_manager_init(met_device.this_device);
1403 ondiemet_attr_init(met_device.this_device);
1404
1405 return 0;
1406}
1407
1408void fs_unreg(void)
1409{
1410 if (run == 1)
1411 met_stop();
1412
1413 run = -1;
1414
1415 met_deregister(&met_stat);
1416
1417#ifdef MET_USER_EVENT_SUPPORT
1418 tag_unreg();
1419#endif
1420
1421 met_deregister(&met_dummy_header);
1422#ifdef MET_EVENT_POWER_SUPPORT
1423 met_deregister(&met_trace_event);
1424 met_ext_api.met_pm_qos_update_request = NULL;
1425 met_ext_api.met_pm_qos_update_target = NULL;
1426#endif
1427 met_deregister(&met_switch);
1428 met_deregister(&met_memstat);
1429 met_deregister(&met_cpupmu);
1430 met_deregister(&met_cookie);
1431 met_deregister(&met_backlight);
1432 met_ext_api.enable_met_backlight_tag = NULL;
1433 met_ext_api.output_met_backlight_tag = NULL;
1434
1435 kobject_del(kobj_misc);
1436 kobject_put(kobj_misc);
1437 kobj_misc = NULL;
1438 kobject_del(kobj_pmu);
1439 kobject_put(kobj_pmu);
1440 kobj_pmu = NULL;
1441 kobject_del(kobj_bus);
1442 kobject_put(kobj_bus);
1443 kobj_bus = NULL;
1444
1445 device_remove_file(met_device.this_device, &dev_attr_ksym);
1446
1447 device_remove_file(met_device.this_device, &dev_attr_run);
1448#ifdef PR_CPU_NOTIFY
1449 device_remove_file(met_device.this_device, &dev_attr_cpu_notify);
1450#endif
1451#ifdef CONFIG_CPU_FREQ
1452 device_remove_file(met_device.this_device, &dev_attr_dvfs);
1453#endif
1454 device_remove_file(met_device.this_device, &dev_attr_suspend_compensation_enable);
1455 device_remove_file(met_device.this_device, &dev_attr_suspend_compensation_flag);
1456
1457 device_remove_file(met_device.this_device, &dev_attr_ver);
1458 device_remove_file(met_device.this_device, &dev_attr_devices);
1459 device_remove_file(met_device.this_device, &dev_attr_sample_rate);
1460
1461 device_remove_file(met_device.this_device, &dev_attr_ctrl);
1462 device_remove_file(met_device.this_device, &dev_attr_cpu_pmu_method);
1463 device_remove_file(met_device.this_device, &dev_attr_cpu_pm_pmu_reconfig);
1464
1465 device_remove_file(met_device.this_device, &dev_attr_core_topology);
1466 device_remove_file(met_device.this_device, &dev_attr_plf);
1467 device_remove_file(met_device.this_device, &dev_attr_chip_id);
1468 device_remove_file(met_device.this_device, &dev_attr_hash);
1469 device_remove_file(met_device.this_device, &dev_attr_ipi_test);
1470
1471 ondiemet_log_manager_uninit(met_device.this_device);
1472 ondiemet_attr_uninit(met_device.this_device);
1473
1474 misc_deregister(&met_device);
1475#ifdef MET_SUSPEND_HAND
1476 /* suspend/resume function handle register */
1477 unregister_syscore_ops(&met_hrtimer_ops);
1478#endif
1479}
1480
1481unsigned int get_ctrl_flags(void)
1482{
1483 return ctrl_flags;
1484}