1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/init.h>
4 #include <linux/cpufreq.h>
6 #include <linux/pm_qos.h>
7 #include <linux/sched.h>
8 #include <linux/cpuidle.h>
10 #include <linux/trm.h>
11 #if defined(CONFIG_SYSTEM_LOAD_ANALYZER)
12 #include <linux/load_analyzer.h>
15 #if defined(TRM_INPUT_BOOSTER_EN)
16 #include "cpufreq_pmqos_input.c"
17 #include "cpufreq_pmqos_z3.c"
20 /* below macro indicates the name of the model */
21 #define DEVICE_NAME "KIRANZ3"
24 #define define_one_root_rw(_name) \
25 static struct global_attr _name = \
26 __ATTR(_name, 0600, show_##_name, store_##_name)
28 #define __ATTR_ROOT_RO(_name) { \
29 .attr = { .name = __stringify(_name), .mode = 0400 }, \
30 .show = show_##_name, \
33 #define define_one_root_ro(_name) \
34 static struct global_attr _name = \
37 static int atoi(const char *str)
43 while (str[count] && str[count] >= '0' && str[count] <= '9') {
44 result = result * 10 + str[count] - '0';
50 struct kobject *cpufreq_pmqos_kobject;
52 struct pm_qos_lock_tag {
53 int cpufreq_min_value;
54 int cpufreq_max_value;
56 int cpu_online_min_value;
57 int cpu_online_max_value;
60 int min_cpu_freq, max_cpu_freq;
64 static struct pm_qos_request cpufreq_min_qos_array[NUMBER_OF_LOCK];
65 static struct pm_qos_request cpufreq_max_qos_array[NUMBER_OF_LOCK];
66 static struct pm_qos_request cpu_gov_up_level_array[NUMBER_OF_LOCK];
67 static struct pm_qos_request cpu_freq_up_threshold_array[NUMBER_OF_LOCK];
71 static struct pm_qos_request cpu_online_min_qos_array[NUMBER_OF_LOCK];
72 static struct pm_qos_request cpu_online_max_qos_array[NUMBER_OF_LOCK];
75 static struct pm_qos_request bus_mif_min_qos_array[NUMBER_OF_LOCK];
76 static struct pm_qos_request bus_int_min_qos_array[NUMBER_OF_LOCK];
78 /* CHECK LOCK STATE */
79 static struct pm_qos_lock_tag trm_pm_qos_lock[NUMBER_OF_LOCK];
82 static void pmqos_saving_data(int pmqos_type, int id, int value)
86 case PM_QOS_CPU_FREQ_MIN:
87 trm_pm_qos_lock[id].cpufreq_min_value = value;
90 case PM_QOS_CPU_FREQ_MAX:
91 trm_pm_qos_lock[id].cpufreq_max_value = value;
94 case PM_QOS_CPU_ONLINE_MIN:
95 trm_pm_qos_lock[id].cpu_online_min_value = value;
98 case PM_QOS_CPU_ONLINE_MAX:
99 trm_pm_qos_lock[id].cpu_online_max_value = value;
106 int set_pmqos_data(struct pm_qos_request *any_qos_array, int pmqos_type, const char *buf)
108 int lock_id = KERNEL_RESERVED00, lock_value = 0;
111 p2 = strstr(buf, "ID");
114 p2 = strstr(buf, "id");
117 lock_id = atoi(p2+2);
119 lock_id = KERNEL_RESERVED00;
121 if (lock_id >= NUMBER_OF_LOCK) {
122 pr_err("%s lock_id=%d is wrong", __FUNCTION__ ,lock_id);
126 if (strstr(buf, "-1")!=NULL)
129 lock_value = atoi(buf);
131 pmqos_saving_data(pmqos_type, lock_id ,lock_value);
133 printk(KERN_DEBUG "%s %s/%d id=%d value=%d\n", __FUNCTION__
134 , get_current()->comm ,get_current()->pid ,lock_id ,lock_value);
136 if (lock_value == -1) {
137 if (pm_qos_request_active(&any_qos_array[lock_id]))
138 pm_qos_remove_request(&any_qos_array[lock_id]);
141 if (!pm_qos_request_active(&any_qos_array[lock_id])) {
142 pm_qos_add_request(&any_qos_array[lock_id]
143 , pmqos_type, lock_value);
145 pm_qos_update_request(&any_qos_array[lock_id], lock_value);
152 static ssize_t show_cpufreq_max(struct kobject *kobj,
153 struct attribute *attr, char *buf)
155 unsigned int ret = 0;
156 max_cpu_freq = pm_qos_request(PM_QOS_CPU_FREQ_MAX);
157 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d\n", max_cpu_freq);
162 static ssize_t store_cpufreq_max(struct kobject *a, struct attribute *b,
163 const char *buf, size_t count)
166 ret = set_pmqos_data(cpufreq_max_qos_array, PM_QOS_CPU_FREQ_MAX, buf);
172 static ssize_t show_cpufreq_min(struct kobject *kobj,
173 struct attribute *attr, char *buf)
175 unsigned int ret = 0;
176 min_cpu_freq = pm_qos_request(PM_QOS_CPU_FREQ_MIN);
177 ret += snprintf(buf + ret, PAGE_SIZE - ret, "%d\n", min_cpu_freq);
182 static ssize_t store_cpufreq_min(struct kobject *a, struct attribute *b,
183 const char *buf, size_t count)
186 ret = set_pmqos_data(cpufreq_min_qos_array, PM_QOS_CPU_FREQ_MIN, buf);
193 static ssize_t show_pmqos_lock_state(struct kobject *kobj,
194 struct attribute *attr, char *buf)
196 unsigned int i, ret = 0;
198 for(i=0; i<NUMBER_OF_LOCK; i++) {
199 ret += snprintf(buf + ret, PAGE_SIZE - ret
200 , "[%2d] CPU FREQ MIN:%7d MAX:%7d | ONLINE MIN:%d MAX:%d\n"
201 ,i ,trm_pm_qos_lock[i].cpufreq_min_value, trm_pm_qos_lock[i].cpufreq_max_value
202 ,trm_pm_qos_lock[i].cpu_online_min_value, trm_pm_qos_lock[i].cpu_online_max_value);
209 static ssize_t store_pmqos_lock_state(struct kobject *a, struct attribute *b,
210 const char *buf, size_t count)
216 static ssize_t show_cpu_online_max(struct kobject *kobj,
217 struct attribute *attr, char *buf)
219 unsigned int ret = 0;
220 ret = sprintf(buf, "%d\n", pm_qos_request(PM_QOS_CPU_ONLINE_MAX));
224 static ssize_t store_cpu_online_max(struct kobject *a, struct attribute *b,
225 const char *buf, size_t count)
227 set_pmqos_data(cpu_online_max_qos_array, PM_QOS_CPU_ONLINE_MAX, buf);
232 static ssize_t show_cpu_online_min(struct kobject *kobj,
233 struct attribute *attr, char *buf)
235 unsigned int ret = 0;
236 ret = sprintf(buf, "%d\n", pm_qos_request(PM_QOS_CPU_ONLINE_MIN));
240 static ssize_t store_cpu_online_min(struct kobject *a, struct attribute *b,
241 const char *buf, size_t count)
243 set_pmqos_data(cpu_online_min_qos_array, PM_QOS_CPU_ONLINE_MIN, buf);
250 static ssize_t show_bus_mif_freq_min(struct kobject *kobj,
251 struct attribute *attr, char *buf)
253 unsigned int ret = 0;
254 ret = sprintf(buf, "%d\n", pm_qos_request(PM_QOS_BUS_THROUGHPUT));
258 static ssize_t store_bus_mif_freq_min(struct kobject *a, struct attribute *b,
259 const char *buf, size_t count)
261 set_pmqos_data(bus_mif_min_qos_array, PM_QOS_BUS_THROUGHPUT, buf);
267 static ssize_t show_bus_int_freq_min(struct kobject *kobj,
268 struct attribute *attr, char *buf)
270 unsigned int ret = 0;
271 ret = sprintf(buf, "%d\n", pm_qos_request(PM_QOS_DEVICE_THROUGHPUT));
275 static ssize_t store_bus_int_freq_min(struct kobject *a, struct attribute *b,
276 const char *buf, size_t count)
278 set_pmqos_data(bus_int_min_qos_array, PM_QOS_DEVICE_THROUGHPUT, buf);
286 static ssize_t show_device_name(struct kobject *kobj,
287 struct attribute *attr, char *buf)
289 unsigned int ret = 0;
290 ret = sprintf(buf, "%s\n", DEVICE_NAME);
294 static ssize_t store_device_name(struct kobject *a, struct attribute *b,
295 const char *buf, size_t count)
301 #if defined(CONFIG_CHECK_ENTER_AFTR)
302 static ssize_t show_cpuidle_w_aftr_en(struct kobject *kobj,
303 struct attribute *attr, char *buf)
305 unsigned int ret = 0;
306 ret = sprintf(buf, "%d\n", cpuidle_get_w_after_enable_state());
310 static ssize_t store_cpuidle_w_aftr_en(struct kobject *a, struct attribute *b,
311 const char *buf, size_t count)
316 if ((input == 0 ) || (input == 1 ))
317 cpuidle_set_w_aftr_enable(input);
322 static ssize_t show_cpuidle_w_aftr_jig_check_en(struct kobject *kobj,
323 struct attribute *attr, char *buf)
325 unsigned int ret = 0;
326 ret = sprintf(buf, "%d\n", cpuidle_get_w_aftr_jig_check_enable());
330 static ssize_t store_cpuidle_w_aftr_jig_check_en(struct kobject *a, struct attribute *b,
331 const char *buf, size_t count)
336 if ((input == 0 ) || (input == 1 ))
337 cpuidle_set_w_aftr_jig_check_enable(input);
343 static unsigned int cpu_gov_up_level_value = PM_QOS_CPU_GOV_UP_LEVEL_DEFAULT_VALUE;
344 unsigned int cpu_gov_get_up_level(void)
346 cpu_gov_up_level_value = pm_qos_request(PM_QOS_CPU_GOV_UP_LEVEL);
348 return cpu_gov_up_level_value;
351 static ssize_t show_cpu_gov_up_level(struct kobject *kobj,
352 struct attribute *attr, char *buf)
354 unsigned int ret = 0;
355 ret = sprintf(buf, "%d\n", cpu_gov_get_up_level());
359 static ssize_t store_cpu_gov_up_level(struct kobject *a, struct attribute *b,
360 const char *buf, size_t count)
363 set_pmqos_data(cpu_gov_up_level_array, PM_QOS_CPU_GOV_UP_LEVEL, buf);
369 static unsigned int cpu_freq_up_threshold_value = PM_QOS_CPU_FREQ_UP_THRESHOLD_DEFAULT_VALUE;
370 unsigned int cpu_freq_get_threshold(void)
372 cpu_freq_up_threshold_value = pm_qos_request(PM_QOS_CPU_FREQ_UP_THRESHOLD);
374 return cpu_freq_up_threshold_value;
377 static ssize_t show_cpu_freq_up_threshold(struct kobject *kobj,
378 struct attribute *attr, char *buf)
380 unsigned int ret = 0;
381 ret = sprintf(buf, "%d\n", cpu_freq_get_threshold());
385 static ssize_t store_cpu_freq_up_threshold(struct kobject *a, struct attribute *b,
386 const char *buf, size_t count)
389 set_pmqos_data(cpu_freq_up_threshold_array, PM_QOS_CPU_FREQ_UP_THRESHOLD, buf);
396 #if defined(CONFIG_SLP_CURRENT_MONITOR)
397 char current_log_req_str[64];
398 void update_current_log_req(void)
400 sysfs_notify(cpufreq_pmqos_kobject, NULL, "current_log_req");
402 #if defined(CONFIG_SLP_MINI_TRACER)
403 kernel_mini_tracer("update_current_log_req\n", TIME_ON | FLUSH_CACHE);
408 static ssize_t show_current_log_req(struct kobject *kobj,
409 struct attribute *attr, char *buf)
411 unsigned int ret = 0;
412 ret = sprintf(buf, "%s\n", current_log_req_str);
417 static ssize_t store_current_log_req(struct kobject *a, struct attribute *b,
418 const char *buf, size_t count)
420 strcpy(current_log_req_str, buf);
422 update_current_log_req();
429 #if defined (CONFIG_SLP_BUSY_LEVEL)
430 void update_cpu_busy_level(void)
432 sysfs_notify(cpufreq_pmqos_kobject, NULL, "cpu_busy_level_value");
434 pr_info("%s\n", __FUNCTION__);
437 static ssize_t show_cpu_busy_level_value(struct kobject *kobj,
438 struct attribute *attr, char *buf)
440 unsigned int ret = 0;
441 ret = sprintf(buf, "%d\n", la_get_cpu_busy_level());
445 static ssize_t store_cpu_busy_level_value(struct kobject *a, struct attribute *b,
446 const char *buf, size_t count)
452 if ((input >= 0) && (input <= 9 )) {
453 la_set_cpu_busy_level(input);
454 update_cpu_busy_level();
462 define_one_root_rw(device_name);
464 define_one_root_rw(cpufreq_max);
465 define_one_root_rw(cpufreq_min);
466 define_one_root_rw(cpu_online_max);
467 define_one_root_rw(cpu_online_min);
468 define_one_root_rw(pmqos_lock_state);
470 define_one_root_rw(bus_mif_freq_min);
471 define_one_root_rw(bus_int_freq_min);
473 #if defined(CONFIG_CHECK_ENTER_AFTR)
474 define_one_root_rw(cpuidle_w_aftr_en);
475 define_one_root_rw(cpuidle_w_aftr_jig_check_en);
478 define_one_root_rw(cpu_gov_up_level);
479 define_one_root_rw(cpu_freq_up_threshold);
482 #if defined(CONFIG_SLP_CURRENT_MONITOR)
483 define_one_root_rw(current_log_req);
486 #if defined (CONFIG_SLP_BUSY_LEVEL)
487 define_one_root_rw(cpu_busy_level_value);
490 static struct attribute *pmqos_attributes[] = {
493 &cpu_gov_up_level.attr,
494 &cpu_freq_up_threshold.attr,
495 &cpu_online_min.attr,
496 &cpu_online_max.attr,
497 #if defined(TRM_INPUT_BOOSTER_EN)
498 &touch_cpu_online_min.attr,
500 &pmqos_lock_state.attr,
501 &bus_mif_freq_min.attr,
502 &bus_int_freq_min.attr,
503 #if defined(CONFIG_CHECK_ENTER_AFTR)
504 &cpuidle_w_aftr_en.attr,
505 &cpuidle_w_aftr_jig_check_en.attr,
508 #if defined(CONFIG_SLP_CURRENT_MONITOR)
509 ¤t_log_req.attr,
511 #if defined (CONFIG_SLP_BUSY_LEVEL)
512 &cpu_busy_level_value.attr,
514 #if defined(TRM_TOUCH_BOOSTER_EN)
515 &touch_boost_en.attr,
516 &touch_boost_press.attr,
517 &touch_boost_move.attr,
518 &touch_boost_release.attr,
523 static struct attribute_group pmqos_attr_group = {
524 .attrs = pmqos_attributes,
527 static int __ref cpu_online_min_qos_handler(struct notifier_block *b, unsigned long val, void *v)
530 int online_num_now = num_online_cpus();
531 unsigned int turn_on_cpu_num, cpu_online_min;
536 cpu_online_min = min((unsigned int)pm_qos_request(PM_QOS_CPU_ONLINE_MAX), (unsigned int)val);
538 if (cpu_online_min <= online_num_now)
541 turn_on_cpu_num = cpu_online_min -online_num_now;
543 for_each_cpu_not(cpu, cpu_online_mask) {
544 if (turn_on_cpu_num-- == 0)
548 pr_info("CPU_UP %d\n", cpu);
555 static int __ref cpu_online_max_qos_handler(struct notifier_block *b, unsigned long val, void *v)
558 int online_num_now = num_online_cpus();
559 unsigned int turn_off_cpu_num, cpu_online_max;
561 if (pm_qos_request(PM_QOS_CPU_ONLINE_MIN) > 1) {
562 cpu_online_min_qos_handler(NULL, pm_qos_request(PM_QOS_CPU_ONLINE_MIN), NULL);
565 cpu_online_max = val;
567 if (cpu_online_max >= online_num_now)
570 turn_off_cpu_num = online_num_now - cpu_online_max;
572 for_each_online_cpu(cpu) {
575 pr_info("CPU_DOWN %d\n", cpu);
577 if (--turn_off_cpu_num == 0)
585 static struct notifier_block cpu_online_min_qos_notifier = {
586 .notifier_call = cpu_online_min_qos_handler,
589 static struct notifier_block cpu_online_max_qos_notifier = {
590 .notifier_call = cpu_online_max_qos_handler,
593 static int __init cpufreq_pmqos_init(void)
597 cpufreq_pmqos_kobject= kobject_create_and_add("pmqos",
598 cpufreq_global_kobject);
599 if (!cpufreq_pmqos_kobject)
602 err = sysfs_create_group(cpufreq_pmqos_kobject, &pmqos_attr_group);
604 kobject_put(cpufreq_pmqos_kobject);
606 kobject_uevent(cpufreq_pmqos_kobject, KOBJ_ADD);
608 pm_qos_add_notifier(PM_QOS_CPU_ONLINE_MIN, &cpu_online_min_qos_notifier);
609 pm_qos_add_notifier(PM_QOS_CPU_ONLINE_MAX, &cpu_online_max_qos_notifier);
611 #if defined(TRM_INPUT_BOOSTER_EN)
612 input_booster_init();
618 MODULE_AUTHOR("Yong-U Baek <yu.baek@samsung.com>");
619 MODULE_DESCRIPTION("cpufreq_pmqos");
620 MODULE_LICENSE("GPL");
622 late_initcall(cpufreq_pmqos_init);