drm: Cocci spatch "memdup.spatch"
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / cpufreq / cpufreq_pmqos.c
1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/init.h>
4 #include <linux/cpufreq.h>
5 #include <linux/cpu.h>
6 #include <linux/pm_qos.h>
7 #include <linux/sched.h>
8 #include <linux/cpuidle.h>
9
10 #include <linux/trm.h>
11 #if defined(CONFIG_SYSTEM_LOAD_ANALYZER)
12 #include <linux/load_analyzer.h>
13 #endif
14
15 #if defined(TRM_INPUT_BOOSTER_EN)
16 #include "cpufreq_pmqos_input.c"
17 #include "cpufreq_pmqos_z3.c"
18 #endif
19
20 /* below macro indicates the name of the model */
21 #define DEVICE_NAME "KIRANZ3"
22
23
24 #define define_one_root_rw(_name)               \
25 static struct global_attr _name =               \
26 __ATTR(_name, 0600, show_##_name, store_##_name)
27
28 #define __ATTR_ROOT_RO(_name) { \
29         .attr   = { .name = __stringify(_name), .mode = 0400 }, \
30         .show   = show_##_name,                                 \
31 }
32
33 #define define_one_root_ro(_name)               \
34 static struct global_attr _name =               \
35 __ATTR_ROOT_RO(_name)
36
37 static int atoi(const char *str)
38 {
39         int result = 0;
40         int count = 0;
41         if (str == NULL)
42                 return -1;
43         while (str[count] && str[count] >= '0' && str[count] <= '9') {
44                 result = result * 10 + str[count] - '0';
45                 ++count;
46         }
47         return result;
48 }
49
50 struct kobject *cpufreq_pmqos_kobject;
51
52 struct pm_qos_lock_tag {
53         int cpufreq_min_value;
54         int cpufreq_max_value;
55
56         int cpu_online_min_value;
57         int cpu_online_max_value;
58 };
59
60 int min_cpu_freq, max_cpu_freq;
61
62
63 /* CPUFREQ */
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];
68
69
70 /* CPU ONLINE */
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];
73
74 /* BUS */
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];
77
78 /* CHECK LOCK STATE */
79 static struct pm_qos_lock_tag trm_pm_qos_lock[NUMBER_OF_LOCK];
80
81
82 static void pmqos_saving_data(int pmqos_type, int id, int value)
83 {
84         switch (pmqos_type) {
85
86         case PM_QOS_CPU_FREQ_MIN:
87                 trm_pm_qos_lock[id].cpufreq_min_value = value;
88                 break;
89
90         case PM_QOS_CPU_FREQ_MAX:
91                 trm_pm_qos_lock[id].cpufreq_max_value = value;
92                 break;
93
94         case PM_QOS_CPU_ONLINE_MIN:
95                 trm_pm_qos_lock[id].cpu_online_min_value = value;
96                 break;
97
98         case PM_QOS_CPU_ONLINE_MAX:
99                 trm_pm_qos_lock[id].cpu_online_max_value = value;
100                 break;
101
102         }
103 }
104
105
106 int set_pmqos_data(struct pm_qos_request *any_qos_array, int pmqos_type, const char *buf)
107 {
108         int lock_id = KERNEL_RESERVED00, lock_value = 0;
109         char *p2 = NULL;
110
111         p2 = strstr(buf, "ID");
112
113         if (p2 == NULL)
114                 p2 = strstr(buf, "id");
115
116         if (p2 != NULL)
117                 lock_id = atoi(p2+2);
118         else
119                 lock_id = KERNEL_RESERVED00;
120
121         if (lock_id >= NUMBER_OF_LOCK) {
122                 pr_err("%s lock_id=%d is wrong", __FUNCTION__ ,lock_id);
123                 return -EINVAL;
124         }
125
126         if (strstr(buf, "-1")!=NULL)
127                 lock_value = -1;
128         else
129                 lock_value = atoi(buf);
130
131         pmqos_saving_data(pmqos_type, lock_id ,lock_value);
132
133         printk(KERN_DEBUG "%s %s/%d id=%d value=%d\n", __FUNCTION__
134                 , get_current()->comm ,get_current()->pid ,lock_id ,lock_value);
135
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]);
139
140         } else {
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);
144                 } else
145                         pm_qos_update_request(&any_qos_array[lock_id], lock_value);
146         }
147
148         return 0;
149 }
150
151
152 static ssize_t show_cpufreq_max(struct kobject *kobj,
153                                 struct attribute *attr, char *buf)
154 {
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);
158
159         return ret;
160 }
161
162 static ssize_t store_cpufreq_max(struct kobject *a, struct attribute *b,
163                                 const char *buf, size_t count)
164 {
165         int ret = 0;
166         ret = set_pmqos_data(cpufreq_max_qos_array, PM_QOS_CPU_FREQ_MAX, buf);
167         if (ret)
168                 return ret;
169         else
170                 return count;
171 }
172 static ssize_t show_cpufreq_min(struct kobject *kobj,
173                                 struct attribute *attr, char *buf)
174 {
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);
178
179         return ret;
180 }
181
182 static ssize_t store_cpufreq_min(struct kobject *a, struct attribute *b,
183                                 const char *buf, size_t count)
184 {
185         int ret = 0;
186         ret = set_pmqos_data(cpufreq_min_qos_array, PM_QOS_CPU_FREQ_MIN, buf);
187         if (ret)
188                 return ret;
189         else
190                 return count;
191 }
192
193 static ssize_t show_pmqos_lock_state(struct kobject *kobj,
194                                 struct attribute *attr, char *buf)
195 {
196         unsigned int i, ret = 0;
197
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);
203
204         }
205
206         return ret;
207 }
208
209 static ssize_t store_pmqos_lock_state(struct kobject *a, struct attribute *b,
210                                   const char *buf, size_t count)
211 {
212         return count;
213 }
214
215
216 static ssize_t show_cpu_online_max(struct kobject *kobj,
217                                 struct attribute *attr, char *buf)
218 {
219         unsigned int ret = 0;
220         ret =  sprintf(buf, "%d\n", pm_qos_request(PM_QOS_CPU_ONLINE_MAX));
221         return ret;
222 }
223
224 static ssize_t store_cpu_online_max(struct kobject *a, struct attribute *b,
225                                 const char *buf, size_t count)
226 {
227         set_pmqos_data(cpu_online_max_qos_array, PM_QOS_CPU_ONLINE_MAX, buf);
228
229         return count;
230 }
231
232 static ssize_t show_cpu_online_min(struct kobject *kobj,
233                                 struct attribute *attr, char *buf)
234 {
235         unsigned int ret = 0;
236         ret =  sprintf(buf, "%d\n", pm_qos_request(PM_QOS_CPU_ONLINE_MIN));
237         return ret;
238 }
239
240 static ssize_t store_cpu_online_min(struct kobject *a, struct attribute *b,
241                                 const char *buf, size_t count)
242 {
243         set_pmqos_data(cpu_online_min_qos_array, PM_QOS_CPU_ONLINE_MIN, buf);
244
245         return count;
246 }
247
248
249 /* BUS ++ */
250 static ssize_t show_bus_mif_freq_min(struct kobject *kobj,
251                                 struct attribute *attr, char *buf)
252 {
253         unsigned int ret = 0;
254         ret =  sprintf(buf, "%d\n", pm_qos_request(PM_QOS_BUS_THROUGHPUT));
255         return ret;
256 }
257
258 static ssize_t store_bus_mif_freq_min(struct kobject *a, struct attribute *b,
259                                   const char *buf, size_t count)
260 {
261         set_pmqos_data(bus_mif_min_qos_array, PM_QOS_BUS_THROUGHPUT, buf);
262
263         return count;
264 }
265
266
267 static ssize_t show_bus_int_freq_min(struct kobject *kobj,
268                                 struct attribute *attr, char *buf)
269 {
270         unsigned int ret = 0;
271         ret =  sprintf(buf, "%d\n", pm_qos_request(PM_QOS_DEVICE_THROUGHPUT));
272         return ret;
273 }
274
275 static ssize_t store_bus_int_freq_min(struct kobject *a, struct attribute *b,
276                                   const char *buf, size_t count)
277 {
278         set_pmqos_data(bus_int_min_qos_array, PM_QOS_DEVICE_THROUGHPUT, buf);
279
280         return count;
281 }
282
283 /* BUS -- */
284
285
286 static ssize_t show_device_name(struct kobject *kobj,
287                                 struct attribute *attr, char *buf)
288 {
289         unsigned int ret = 0;
290         ret =  sprintf(buf, "%s\n", DEVICE_NAME);
291         return ret;
292 }
293
294 static ssize_t store_device_name(struct kobject *a, struct attribute *b,
295                                   const char *buf, size_t count)
296 {
297         return count;
298 }
299
300
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)
304 {
305         unsigned int ret = 0;
306         ret =  sprintf(buf, "%d\n", cpuidle_get_w_after_enable_state());
307         return ret;
308 }
309
310 static ssize_t store_cpuidle_w_aftr_en(struct kobject *a, struct attribute *b,
311                                   const char *buf, size_t count)
312 {
313         int input;
314         input = atoi(buf);
315
316         if ((input == 0 ) || (input == 1 ))
317                 cpuidle_set_w_aftr_enable(input);
318
319         return count;
320 }
321
322 static ssize_t show_cpuidle_w_aftr_jig_check_en(struct kobject *kobj,
323                                 struct attribute *attr, char *buf)
324 {
325         unsigned int ret = 0;
326         ret =  sprintf(buf, "%d\n", cpuidle_get_w_aftr_jig_check_enable());
327         return ret;
328 }
329
330 static ssize_t store_cpuidle_w_aftr_jig_check_en(struct kobject *a, struct attribute *b,
331                                   const char *buf, size_t count)
332 {
333         int input;
334         input = atoi(buf);
335
336         if ((input == 0 ) || (input == 1 ))
337                 cpuidle_set_w_aftr_jig_check_enable(input);
338
339         return count;
340 }
341 #endif
342
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)
345 {
346         cpu_gov_up_level_value = pm_qos_request(PM_QOS_CPU_GOV_UP_LEVEL);
347
348         return cpu_gov_up_level_value;
349 }
350
351 static ssize_t show_cpu_gov_up_level(struct kobject *kobj,
352                                 struct attribute *attr, char *buf)
353 {
354         unsigned int ret = 0;
355         ret =  sprintf(buf, "%d\n", cpu_gov_get_up_level());
356         return ret;
357 }
358
359 static ssize_t store_cpu_gov_up_level(struct kobject *a, struct attribute *b,
360                                   const char *buf, size_t count)
361 {
362
363         set_pmqos_data(cpu_gov_up_level_array, PM_QOS_CPU_GOV_UP_LEVEL, buf);
364
365         return count;
366 }
367
368
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)
371 {
372         cpu_freq_up_threshold_value = pm_qos_request(PM_QOS_CPU_FREQ_UP_THRESHOLD);
373
374         return cpu_freq_up_threshold_value;
375 }
376
377 static ssize_t show_cpu_freq_up_threshold(struct kobject *kobj,
378                                 struct attribute *attr, char *buf)
379 {
380         unsigned int ret = 0;
381         ret =  sprintf(buf, "%d\n", cpu_freq_get_threshold());
382         return ret;
383 }
384
385 static ssize_t store_cpu_freq_up_threshold(struct kobject *a, struct attribute *b,
386                                   const char *buf, size_t count)
387 {
388
389         set_pmqos_data(cpu_freq_up_threshold_array, PM_QOS_CPU_FREQ_UP_THRESHOLD, buf);
390
391         return count;
392 }
393
394
395
396 #if defined(CONFIG_SLP_CURRENT_MONITOR)
397 char current_log_req_str[64];
398 void update_current_log_req(void)
399 {
400         sysfs_notify(cpufreq_pmqos_kobject, NULL, "current_log_req");
401
402 #if defined(CONFIG_SLP_MINI_TRACER)
403         kernel_mini_tracer("update_current_log_req\n", TIME_ON | FLUSH_CACHE);
404 #endif
405 }
406
407
408 static ssize_t show_current_log_req(struct kobject *kobj,
409                                 struct attribute *attr, char *buf)
410 {
411         unsigned int ret = 0;
412         ret =  sprintf(buf, "%s\n", current_log_req_str);
413
414         return ret;
415 }
416
417 static ssize_t store_current_log_req(struct kobject *a, struct attribute *b,
418                                   const char *buf, size_t count)
419 {
420         strcpy(current_log_req_str, buf);
421
422         update_current_log_req();
423
424         return count;
425 }
426 #endif
427
428
429 #if defined (CONFIG_SLP_BUSY_LEVEL)
430 void update_cpu_busy_level(void)
431 {
432         sysfs_notify(cpufreq_pmqos_kobject, NULL, "cpu_busy_level_value");
433
434         pr_info("%s\n", __FUNCTION__);
435 }
436
437 static ssize_t show_cpu_busy_level_value(struct kobject *kobj,
438                                 struct attribute *attr, char *buf)
439 {
440         unsigned int ret = 0;
441         ret =  sprintf(buf, "%d\n", la_get_cpu_busy_level());
442         return ret;
443 }
444
445 static ssize_t store_cpu_busy_level_value(struct kobject *a, struct attribute *b,
446                                   const char *buf, size_t count)
447 {
448         int input;
449
450         input = atoi(buf);
451
452         if ((input >= 0) && (input <= 9 )) {
453                 la_set_cpu_busy_level(input);
454                 update_cpu_busy_level();
455         }
456
457         return count;
458 }
459
460 #endif
461
462 define_one_root_rw(device_name);
463
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);
469
470 define_one_root_rw(bus_mif_freq_min);
471 define_one_root_rw(bus_int_freq_min);
472
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);
476 #endif
477
478 define_one_root_rw(cpu_gov_up_level);
479 define_one_root_rw(cpu_freq_up_threshold);
480
481
482 #if defined(CONFIG_SLP_CURRENT_MONITOR)
483 define_one_root_rw(current_log_req);
484 #endif
485
486 #if defined (CONFIG_SLP_BUSY_LEVEL)
487 define_one_root_rw(cpu_busy_level_value);
488 #endif
489
490 static struct attribute *pmqos_attributes[] = {
491         &cpufreq_min.attr,
492         &cpufreq_max.attr,
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,
499 #endif
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,
506 #endif
507         &device_name.attr,
508 #if defined(CONFIG_SLP_CURRENT_MONITOR)
509         &current_log_req.attr,
510 #endif
511 #if defined (CONFIG_SLP_BUSY_LEVEL)
512         &cpu_busy_level_value.attr,
513 #endif
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,
519 #endif
520         NULL
521 };
522
523 static struct attribute_group pmqos_attr_group = {
524         .attrs = pmqos_attributes,
525 };
526
527 static int __ref cpu_online_min_qos_handler(struct notifier_block *b, unsigned long val, void *v)
528 {
529         int cpu;
530         int online_num_now = num_online_cpus();
531         unsigned int turn_on_cpu_num, cpu_online_min;
532
533         if (val == -1)
534                 goto success;
535
536         cpu_online_min = min((unsigned int)pm_qos_request(PM_QOS_CPU_ONLINE_MAX), (unsigned int)val);
537
538         if (cpu_online_min  <= online_num_now)
539                 goto success;
540
541         turn_on_cpu_num = cpu_online_min -online_num_now;
542
543         for_each_cpu_not(cpu, cpu_online_mask) {
544                 if (turn_on_cpu_num-- == 0)
545                         break;
546                 if (cpu == 0)
547                         continue;
548                 pr_info("CPU_UP %d\n", cpu);
549                 cpu_up(cpu);
550         }
551 success:
552         return NOTIFY_OK;
553 }
554
555 static int __ref cpu_online_max_qos_handler(struct notifier_block *b, unsigned long val, void *v)
556 {
557         int cpu;
558         int online_num_now = num_online_cpus();
559         unsigned int turn_off_cpu_num, cpu_online_max;
560
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);
563         }
564
565         cpu_online_max = val;
566
567         if (cpu_online_max  >= online_num_now)
568                 goto success;
569
570         turn_off_cpu_num = online_num_now - cpu_online_max;
571
572         for_each_online_cpu(cpu) {
573                 if (cpu == 0)
574                         continue;
575                 pr_info("CPU_DOWN %d\n", cpu);
576                 cpu_down(cpu);
577                 if (--turn_off_cpu_num == 0)
578                         break;
579         }
580 success:
581         return NOTIFY_OK;
582 }
583
584
585 static struct notifier_block cpu_online_min_qos_notifier = {
586         .notifier_call = cpu_online_min_qos_handler,
587 };
588
589 static struct notifier_block cpu_online_max_qos_notifier = {
590         .notifier_call = cpu_online_max_qos_handler,
591 };
592
593 static int __init cpufreq_pmqos_init(void)
594 {
595         int err;
596
597         cpufreq_pmqos_kobject= kobject_create_and_add("pmqos",
598                         cpufreq_global_kobject);
599         if (!cpufreq_pmqos_kobject)
600                 return -ENOMEM;
601
602         err = sysfs_create_group(cpufreq_pmqos_kobject, &pmqos_attr_group);
603         if (err)
604                 kobject_put(cpufreq_pmqos_kobject);
605         else
606                 kobject_uevent(cpufreq_pmqos_kobject, KOBJ_ADD);
607
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);
610
611 #if defined(TRM_INPUT_BOOSTER_EN)
612         input_booster_init();
613 #endif
614
615         return err;
616 }
617
618 MODULE_AUTHOR("Yong-U Baek <yu.baek@samsung.com>");
619 MODULE_DESCRIPTION("cpufreq_pmqos");
620 MODULE_LICENSE("GPL");
621
622 late_initcall(cpufreq_pmqos_init);
623
624
625