2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/sched.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/slab.h>
14 #include <linux/proc_fs.h>
15 #include <linux/miscdevice.h>
16 #include <linux/platform_device.h>
17 #include <linux/earlysuspend.h>
18 #include <linux/spinlock.h>
19 #include <linux/kthread.h>
20 #include <linux/hrtimer.h>
21 #include <linux/ktime.h>
22 #include <linux/xlog.h>
23 #include <linux/jiffies.h>
25 #include <linux/version.h>
26 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
27 #include <linux/seq_file.h>
30 #include <asm/system.h>
31 #include <asm/uaccess.h>
33 #include "mach/mt_typedefs.h"
34 #include "mach/mt_freqhopping.h"
35 #include "mach/mt_emifreq.h"
36 #include "mach/upmu_common.h"
38 /***************************
40 ****************************/
41 #define dprintk(fmt, args...) \
43 if (mt_emifreq_debug) { \
44 xlog_printk(ANDROID_LOG_INFO, "Power/EMI_DFS", fmt, ##args); \
48 #ifdef CONFIG_HAS_EARLYSUSPEND
49 static struct early_suspend mt_emifreq_early_suspend_handler
=
51 .level
= EARLY_SUSPEND_LEVEL_DISABLE_FB
+ 200,
57 /**************************
59 ***************************/
60 static bool mt_emifreq_debug
= false;
61 static bool mt_emifreq_pause
= true;
63 /******************************
64 * Extern Function Declaration
65 *******************************/
68 /******************************
69 * show current EMI DFS stauts
70 *******************************/
71 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
72 static int mt_emifreq_state_read(char *buf
, char **start
, off_t off
, int count
, int *eof
, void *data
)
77 if (!mt_emifreq_pause
)
78 p
+= sprintf(p
, "EMI DFS enabled\n");
80 p
+= sprintf(p
, "EMI DFS disabled\n");
87 /****************************************
88 * set EMI DFS stauts by sysfs interface
89 *****************************************/
90 static ssize_t
mt_emifreq_state_write(struct file
*file
, const char *buffer
, size_t count
, loff_t
*data
)
94 if (sscanf(buffer
, "%d", &enabled
) == 1)
98 mt_emifreq_pause
= false;
100 else if (enabled
== 0)
102 mt_emifreq_pause
= true;
106 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "bad argument!! argument should be \"1\" or \"0\"\n");
111 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "bad argument!! argument should be \"1\" or \"0\"\n");
117 /***************************
118 * show current debug status
119 ****************************/
120 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
121 static int mt_emifreq_debug_read(char *buf
, char **start
, off_t off
, int count
, int *eof
, void *data
)
126 if (mt_emifreq_debug
)
127 p
+= sprintf(p
, "emifreq debug enabled\n");
129 p
+= sprintf(p
, "emifreq debug disabled\n");
136 /***********************
137 * enable debug message
138 ************************/
139 static ssize_t
mt_emifreq_debug_write(struct file
*file
, const char *buffer
, size_t count
, loff_t
*data
)
143 if (sscanf(buffer
, "%d", &debug
) == 1)
147 mt_emifreq_debug
= 0;
152 mt_emifreq_debug
= 1;
157 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n");
162 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "bad argument!! should be 0 or 1 [0: disable, 1: enable]\n");
169 /*********************************
170 * early suspend callback function
171 **********************************/
172 void mt_emifreq_early_suspend(struct early_suspend
*h
)
174 if(mt_emifreq_pause
== false)
176 mt_h2l_dvfs_mempll();
177 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "mt_emifreq_early_suspend\n");
181 /*******************************
182 * late resume callback function
183 ********************************/
184 void mt_emifreq_late_resume(struct early_suspend
*h
)
186 if(mt_emifreq_pause
== false)
188 mt_l2h_dvfs_mempll();
189 xlog_printk(ANDROID_LOG_INFO
, "Power/EMI_DFS", "mt_emifreq_late_resume\n");
193 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
194 static int mt_emifreq_debug_show(struct seq_file
* s
, void* v
)
196 if (mt_emifreq_debug
)
197 seq_printf(s
, "emifreq debug enabled\n");
199 seq_printf(s
, "emifreq debug disabled\n");
205 static int mt_emifreq_debug_open(struct inode
*inode
, struct file
*file
)
207 return single_open(file
, mt_emifreq_debug_show
, NULL
);
211 static const struct file_operations mt_emifreq_debug_fops
= {
212 .owner
= THIS_MODULE
,
213 .write
= mt_emifreq_debug_write
,
214 .open
= mt_emifreq_debug_open
,
217 .release
= single_release
,
220 static int mt_emifreq_state_show(struct seq_file
* s
, void* v
)
222 if (mt_emifreq_debug
)
223 seq_printf(s
, "emifreq debug enabled\n");
225 seq_printf(s
, "emifreq debug disabled\n");
231 static int mt_emifreq_state_open(struct inode
*inode
, struct file
*file
)
233 return single_open(file
, mt_emifreq_state_show
, NULL
);
237 static const struct file_operations mt_emifreq_state_fops
= {
238 .owner
= THIS_MODULE
,
239 .write
= mt_emifreq_state_write
,
240 .open
= mt_emifreq_state_open
,
243 .release
= single_release
,
247 /**********************************
248 * mediatek emifreq initialization
249 ***********************************/
250 static int __init
mt_emifreq_init(void)
252 struct proc_dir_entry
*mt_entry
= NULL
;
253 struct proc_dir_entry
*mt_emifreq_dir
= NULL
;
255 #ifdef CONFIG_HAS_EARLYSUSPEND
256 mt_emifreq_early_suspend_handler
.suspend
= mt_emifreq_early_suspend
;
257 mt_emifreq_early_suspend_handler
.resume
= mt_emifreq_late_resume
;
258 register_early_suspend(&mt_emifreq_early_suspend_handler
);
261 mt_emifreq_dir
= proc_mkdir("emifreq", NULL
);
264 pr_err("[%s]: mkdir /proc/emifreq failed\n", __FUNCTION__
);
268 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
269 mt_entry
= proc_create("emifreq_debug", S_IRUGO
| S_IWUSR
| S_IWGRP
, mt_emifreq_dir
, &mt_emifreq_debug_fops
);
272 pr_err("[%s]: mkdir /proc/emifreq/emifreq_debug failed\n", __FUNCTION__
);
275 mt_entry
= proc_create("emifreq_state", S_IRUGO
| S_IWUSR
| S_IWGRP
, mt_emifreq_dir
, &mt_emifreq_state_fops
);
278 pr_err("[%s]: mkdir /proc/emifreq/emifreq_state failed\n", __FUNCTION__
);
281 mt_entry
= create_proc_entry("emifreq_debug", S_IRUGO
| S_IWUSR
| S_IWGRP
, mt_emifreq_dir
);
284 mt_entry
->read_proc
= mt_emifreq_debug_read
;
285 mt_entry
->write_proc
= mt_emifreq_debug_write
;
288 mt_entry
= create_proc_entry("emifreq_state", S_IRUGO
| S_IWUSR
| S_IWGRP
, mt_emifreq_dir
);
291 mt_entry
->read_proc
= mt_emifreq_state_read
;
292 mt_entry
->write_proc
= mt_emifreq_state_write
;
300 static void __exit
mt_emifreq_exit(void)
305 module_init(mt_emifreq_init
);
306 module_exit(mt_emifreq_exit
);
307 MODULE_DESCRIPTION("MediaTek EMI Frequency Scaling driver");
308 MODULE_LICENSE("GPL");