#include <linux/debugfs.h> | |
#include <linux/uaccess.h> | |
#include <linux/module.h> | |
#include <linux/io.h> | |
#include <linux/cpufreq.h> | |
#define CPU_MIPS_LOOP 250000000 | |
static unsigned int get_cpu_mips(void) | |
{ | |
struct timespec64 v1, v2; | |
unsigned long cnt, total; | |
#ifdef CONFIG_ARM64 | |
unsigned long i; | |
#endif | |
cnt = CPU_MIPS_LOOP; | |
raw_local_irq_disable(); | |
ktime_get_real_ts64(&v1); | |
#ifdef CONFIG_ARM64 | |
__asm__ __volatile__( | |
"mov %0, %1\n" | |
"timer_loop: subs %0, %0, #1\n" | |
"bhi timer_loop" | |
: "=&r" (i) | |
: "r" (cnt) | |
: "cc"); | |
#else | |
while (cnt--) | |
barrier(); | |
#endif | |
ktime_get_real_ts64(&v2); | |
raw_local_irq_enable(); | |
total = (v2.tv_sec - v1.tv_sec) * 1000000 + (v2.tv_nsec - v1.tv_nsec) / 1000; | |
return CPU_MIPS_LOOP / total; | |
} | |
static ssize_t mips_read(struct file *filp, char __user *buffer, | |
size_t count, loff_t *ppos) | |
{ | |
unsigned int mips, cpu; | |
mips = get_cpu_mips(); | |
cpu = raw_smp_processor_id(); | |
pr_info("Attention! You need to keep cpufreq don't change!\n"); | |
pr_info("Calculated out MIPS is %dMhz, while setting is %dkhz\n", | |
mips, cpufreq_get(cpu)); | |
return 0; | |
} | |
const struct file_operations show_mips_fops = { | |
.read = mips_read, | |
}; | |
struct dentry *asr_debug_entry; | |
static int __init asr_debugfs_init(void) | |
{ | |
struct dentry *showmips; | |
asr_debug_entry = debugfs_create_dir("asr", NULL); | |
if (!asr_debug_entry) | |
return -ENOENT; | |
showmips = debugfs_create_file("showmips", 0664, | |
asr_debug_entry, NULL, &show_mips_fops); | |
if (!showmips) | |
goto err_mips; | |
return 0; | |
err_mips: | |
debugfs_remove(asr_debug_entry); | |
asr_debug_entry = NULL; | |
return -ENOENT; | |
} | |
core_initcall_sync(asr_debugfs_init); |