Guest User

Untitled

a guest
Oct 17th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.84 KB | None | 0 0
  1. /*
  2. * drivers/cpufreq/cpufreq_alucard.c
  3. *
  4. * Copyright (C) 2011 Samsung Electronics co. ltd
  5. * ByungChang Cha <bc.cha@samsung.com>
  6. *
  7. * Based on ondemand governor
  8. * Copyright (C) 2001 Russell King
  9. * (C) 2003 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>.
  10. * Jun Nakajima <jun.nakajima@intel.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License version 2 as
  14. * published by the Free Software Foundation.
  15. *
  16. * Created by Alucard_24@xda
  17. */
  18.  
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/init.h>
  22. #include <linux/cpufreq.h>
  23. #include <linux/cpu.h>
  24. #include <linux/jiffies.h>
  25. #include <linux/kernel_stat.h>
  26. #include <linux/mutex.h>
  27. #include <linux/hrtimer.h>
  28. #include <linux/tick.h>
  29. #include <linux/ktime.h>
  30. #include <linux/sched.h>
  31. #include <linux/slab.h>
  32. /*
  33. * dbs is used in this file as a shortform for demandbased switching
  34. * It helps to keep variable names smaller, simpler
  35. */
  36.  
  37. /* Tuning Interface */
  38. #define MIN_SAMPLING_RATE 10000
  39. #define SAMPLING_RATE 100000
  40. #define INC_CPU_LOAD_AT_MIN_FREQ 90
  41. #define INC_CPU_LOAD 90
  42. #define DEC_CPU_LOAD_AT_MIN_FREQ 90
  43. #define DEC_CPU_LOAD 90
  44.  
  45. #define CPUS_UP_RATE 1
  46. #define CPUS_DOWN_RATE 2
  47.  
  48. #ifdef CONFIG_MACH_LGE
  49. #define FREQ_RESPONSIVENESS 1574400
  50. #else
  51. #define FREQ_RESPONSIVENESS 1134000
  52. #endif
  53.  
  54. /* Pump Inc/Dec for all cores */
  55. #define PUMP_INC_STEP_AT_MIN_FREQ 6
  56. #define PUMP_INC_STEP 1
  57. #define PUMP_DEC_STEP 1
  58.  
  59. static void do_alucard_timer(struct work_struct *work);
  60.  
  61. struct cpufreq_alucard_cpuinfo {
  62. u64 prev_cpu_wall;
  63. u64 prev_cpu_idle;
  64. struct cpufreq_frequency_table *freq_table;
  65. struct delayed_work work;
  66. struct cpufreq_policy *cur_policy;
  67. int cpu;
  68. int min_index;
  69. int max_index;
  70. int pump_inc_step;
  71. int pump_inc_step_at_min_freq;
  72. int pump_dec_step;
  73. unsigned int cur_freq;
  74. bool governor_enabled;
  75. unsigned int up_rate;
  76. unsigned int down_rate;
  77. /*
  78. * mutex that serializes governor limit change with
  79. * do_alucard_timer invocation. We do not want do_alucard_timer to run
  80. * when user is changing the governor or limits.
  81. */
  82. struct mutex timer_mutex;
  83. };
  84.  
  85. static DEFINE_PER_CPU(struct cpufreq_alucard_cpuinfo, od_alucard_cpuinfo);
  86.  
  87. static unsigned int alucard_enable; /* number of CPUs using this policy */
  88. /*
  89. * alucard_mutex protects alucard_enable in governor start/stop.
  90. */
  91. static DEFINE_MUTEX(alucard_mutex);
  92.  
  93. /* alucard tuners */
  94. static struct alucard_tuners {
  95. unsigned int sampling_rate;
  96. int inc_cpu_load_at_min_freq;
  97. int inc_cpu_load;
  98. int dec_cpu_load_at_min_freq;
  99. int dec_cpu_load;
  100. int freq_responsiveness;
  101. unsigned int io_is_busy;
  102. unsigned int cpus_up_rate;
  103. unsigned int cpus_down_rate;
  104. } alucard_tuners_ins = {
  105. .sampling_rate = SAMPLING_RATE,
  106. .inc_cpu_load_at_min_freq = INC_CPU_LOAD_AT_MIN_FREQ,
  107. .inc_cpu_load = INC_CPU_LOAD,
  108. .dec_cpu_load_at_min_freq = DEC_CPU_LOAD_AT_MIN_FREQ,
  109. .dec_cpu_load = DEC_CPU_LOAD,
  110. .freq_responsiveness = FREQ_RESPONSIVENESS,
  111. .io_is_busy = 0,
  112. .cpus_up_rate = CPUS_UP_RATE,
  113. .cpus_down_rate = CPUS_DOWN_RATE,
  114. };
  115.  
  116. /************************** sysfs interface ************************/
  117.  
  118. /* cpufreq_alucard Governor Tunables */
  119. #define show_one(file_name, object) \
  120. static ssize_t show_##file_name \
  121. (struct kobject *kobj, struct attribute *attr, char *buf) \
  122. { \
  123. return sprintf(buf, "%d\n", alucard_tuners_ins.object); \
  124. }
  125. show_one(sampling_rate, sampling_rate);
  126. show_one(inc_cpu_load_at_min_freq, inc_cpu_load_at_min_freq);
  127. show_one(inc_cpu_load, inc_cpu_load);
  128. show_one(dec_cpu_load_at_min_freq, dec_cpu_load_at_min_freq);
  129. show_one(dec_cpu_load, dec_cpu_load);
  130. show_one(freq_responsiveness, freq_responsiveness);
  131. show_one(io_is_busy, io_is_busy);
  132. show_one(cpus_up_rate, cpus_up_rate);
  133. show_one(cpus_down_rate, cpus_down_rate);
  134.  
  135. #define show_pcpu_param(file_name, num_core) \
  136. static ssize_t show_##file_name##_##num_core \
  137. (struct kobject *kobj, struct attribute *attr, char *buf) \
  138. { \
  139. struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, num_core - 1); \
  140. return sprintf(buf, "%d\n", \
  141. this_alucard_cpuinfo->file_name); \
  142. }
  143.  
  144. show_pcpu_param(pump_inc_step_at_min_freq, 1);
  145. show_pcpu_param(pump_inc_step_at_min_freq, 2);
  146. show_pcpu_param(pump_inc_step_at_min_freq, 3);
  147. show_pcpu_param(pump_inc_step_at_min_freq, 4);
  148. show_pcpu_param(pump_inc_step, 1);
  149. show_pcpu_param(pump_inc_step, 2);
  150. show_pcpu_param(pump_inc_step, 3);
  151. show_pcpu_param(pump_inc_step, 4);
  152. show_pcpu_param(pump_dec_step, 1);
  153. show_pcpu_param(pump_dec_step, 2);
  154. show_pcpu_param(pump_dec_step, 3);
  155. show_pcpu_param(pump_dec_step, 4);
  156.  
  157. #define store_pcpu_param(file_name, num_core) \
  158. static ssize_t store_##file_name##_##num_core \
  159. (struct kobject *kobj, struct attribute *attr, \
  160. const char *buf, size_t count) \
  161. { \
  162. int input; \
  163. struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo; \
  164. int ret; \
  165. \
  166. ret = sscanf(buf, "%d", &input); \
  167. if (ret != 1) \
  168. return -EINVAL; \
  169. \
  170. this_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, num_core - 1); \
  171. \
  172. if (input == this_alucard_cpuinfo->file_name) { \
  173. return count; \
  174. } \
  175. \
  176. this_alucard_cpuinfo->file_name = input; \
  177. return count; \
  178. }
  179.  
  180.  
  181. #define store_pcpu_pump_param(file_name, num_core) \
  182. static ssize_t store_##file_name##_##num_core \
  183. (struct kobject *kobj, struct attribute *attr, \
  184. const char *buf, size_t count) \
  185. { \
  186. int input; \
  187. struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo; \
  188. int ret; \
  189. \
  190. ret = sscanf(buf, "%d", &input); \
  191. if (ret != 1) \
  192. return -EINVAL; \
  193. \
  194. input = min(max(1, input), 6); \
  195. \
  196. this_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, num_core - 1); \
  197. \
  198. if (input == this_alucard_cpuinfo->file_name) { \
  199. return count; \
  200. } \
  201. \
  202. this_alucard_cpuinfo->file_name = input; \
  203. return count; \
  204. }
  205.  
  206. store_pcpu_pump_param(pump_inc_step_at_min_freq, 1);
  207. store_pcpu_pump_param(pump_inc_step_at_min_freq, 2);
  208. store_pcpu_pump_param(pump_inc_step_at_min_freq, 3);
  209. store_pcpu_pump_param(pump_inc_step_at_min_freq, 4);
  210. store_pcpu_pump_param(pump_inc_step, 1);
  211. store_pcpu_pump_param(pump_inc_step, 2);
  212. store_pcpu_pump_param(pump_inc_step, 3);
  213. store_pcpu_pump_param(pump_inc_step, 4);
  214. store_pcpu_pump_param(pump_dec_step, 1);
  215. store_pcpu_pump_param(pump_dec_step, 2);
  216. store_pcpu_pump_param(pump_dec_step, 3);
  217. store_pcpu_pump_param(pump_dec_step, 4);
  218.  
  219. define_one_global_rw(pump_inc_step_at_min_freq_1);
  220. define_one_global_rw(pump_inc_step_at_min_freq_2);
  221. define_one_global_rw(pump_inc_step_at_min_freq_3);
  222. define_one_global_rw(pump_inc_step_at_min_freq_4);
  223. define_one_global_rw(pump_inc_step_1);
  224. define_one_global_rw(pump_inc_step_2);
  225. define_one_global_rw(pump_inc_step_3);
  226. define_one_global_rw(pump_inc_step_4);
  227. define_one_global_rw(pump_dec_step_1);
  228. define_one_global_rw(pump_dec_step_2);
  229. define_one_global_rw(pump_dec_step_3);
  230. define_one_global_rw(pump_dec_step_4);
  231.  
  232. /* sampling_rate */
  233. static ssize_t store_sampling_rate(struct kobject *a, struct attribute *b,
  234. const char *buf, size_t count)
  235. {
  236. int input;
  237. int ret;
  238.  
  239. ret = sscanf(buf, "%u", &input);
  240. if (ret != 1)
  241. return -EINVAL;
  242.  
  243. input = max(input,10000);
  244.  
  245. if (input == alucard_tuners_ins.sampling_rate)
  246. return count;
  247.  
  248. alucard_tuners_ins.sampling_rate = input;
  249.  
  250. return count;
  251. }
  252.  
  253. /* inc_cpu_load_at_min_freq */
  254. static ssize_t store_inc_cpu_load_at_min_freq(struct kobject *a, struct attribute *b,
  255. const char *buf, size_t count)
  256. {
  257. int input;
  258. int ret;
  259.  
  260. ret = sscanf(buf, "%d", &input);
  261. if (ret != 1) {
  262. return -EINVAL;
  263. }
  264.  
  265. input = min(input,alucard_tuners_ins.inc_cpu_load);
  266.  
  267. if (input == alucard_tuners_ins.inc_cpu_load_at_min_freq)
  268. return count;
  269.  
  270. alucard_tuners_ins.inc_cpu_load_at_min_freq = input;
  271.  
  272. return count;
  273. }
  274.  
  275. /* inc_cpu_load */
  276. static ssize_t store_inc_cpu_load(struct kobject *a, struct attribute *b,
  277. const char *buf, size_t count)
  278. {
  279. int input;
  280. int ret;
  281.  
  282. ret = sscanf(buf, "%d", &input);
  283. if (ret != 1)
  284. return -EINVAL;
  285.  
  286. input = max(min(input,100),0);
  287.  
  288. if (input == alucard_tuners_ins.inc_cpu_load)
  289. return count;
  290.  
  291. alucard_tuners_ins.inc_cpu_load = input;
  292.  
  293. return count;
  294. }
  295.  
  296. /* dec_cpu_load_at_min_freq */
  297. static ssize_t store_dec_cpu_load_at_min_freq(struct kobject *a, struct attribute *b,
  298. const char *buf, size_t count)
  299. {
  300. int input;
  301. int ret;
  302.  
  303. ret = sscanf(buf, "%d", &input);
  304. if (ret != 1) {
  305. return -EINVAL;
  306. }
  307.  
  308. input = min(input,alucard_tuners_ins.dec_cpu_load);
  309.  
  310. if (input == alucard_tuners_ins.dec_cpu_load_at_min_freq)
  311. return count;
  312.  
  313. alucard_tuners_ins.dec_cpu_load_at_min_freq = input;
  314.  
  315. return count;
  316. }
  317.  
  318. /* dec_cpu_load */
  319. static ssize_t store_dec_cpu_load(struct kobject *a, struct attribute *b,
  320. const char *buf, size_t count)
  321. {
  322. int input;
  323. int ret;
  324.  
  325. ret = sscanf(buf, "%d", &input);
  326. if (ret != 1)
  327. return -EINVAL;
  328.  
  329. input = max(min(input,95),5);
  330.  
  331. if (input == alucard_tuners_ins.dec_cpu_load)
  332. return count;
  333.  
  334. alucard_tuners_ins.dec_cpu_load = input;
  335.  
  336. return count;
  337. }
  338.  
  339. /* freq_responsiveness */
  340. static ssize_t store_freq_responsiveness(struct kobject *a, struct attribute *b,
  341. const char *buf, size_t count)
  342. {
  343. int input;
  344. int ret;
  345.  
  346. ret = sscanf(buf, "%d", &input);
  347. if (ret != 1)
  348. return -EINVAL;
  349.  
  350. if (input == alucard_tuners_ins.freq_responsiveness)
  351. return count;
  352.  
  353. alucard_tuners_ins.freq_responsiveness = input;
  354.  
  355. return count;
  356. }
  357.  
  358. /* io_is_busy */
  359. static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
  360. const char *buf, size_t count)
  361. {
  362. unsigned int input, j;
  363. int ret;
  364.  
  365. ret = sscanf(buf, "%u", &input);
  366. if (ret != 1)
  367. return -EINVAL;
  368.  
  369. if (input > 1)
  370. input = 1;
  371.  
  372. if (input == alucard_tuners_ins.io_is_busy)
  373. return count;
  374.  
  375. alucard_tuners_ins.io_is_busy = !!input;
  376.  
  377. /* we need to re-evaluate prev_cpu_idle */
  378. for_each_online_cpu(j) {
  379. struct cpufreq_alucard_cpuinfo *j_alucard_cpuinfo;
  380.  
  381. j_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, j);
  382.  
  383. j_alucard_cpuinfo->prev_cpu_idle = get_cpu_idle_time(j,
  384. &j_alucard_cpuinfo->prev_cpu_wall, alucard_tuners_ins.io_is_busy);
  385. }
  386. return count;
  387. }
  388.  
  389. /* cpus_up_rate */
  390. static ssize_t store_cpus_up_rate(struct kobject *a, struct attribute *b,
  391. const char *buf, size_t count)
  392. {
  393. unsigned int input;
  394. int ret;
  395.  
  396. ret = sscanf(buf, "%u", &input);
  397. if (ret != 1)
  398. return -EINVAL;
  399.  
  400. if (input == alucard_tuners_ins.cpus_up_rate)
  401. return count;
  402.  
  403. alucard_tuners_ins.cpus_up_rate = input;
  404.  
  405. return count;
  406. }
  407.  
  408. /* cpus_down_rate */
  409. static ssize_t store_cpus_down_rate(struct kobject *a, struct attribute *b,
  410. const char *buf, size_t count)
  411. {
  412. unsigned int input;
  413. int ret;
  414.  
  415. ret = sscanf(buf, "%u", &input);
  416. if (ret != 1)
  417. return -EINVAL;
  418.  
  419. if (input == alucard_tuners_ins.cpus_down_rate)
  420. return count;
  421.  
  422. alucard_tuners_ins.cpus_down_rate = input;
  423.  
  424. return count;
  425. }
  426.  
  427. define_one_global_rw(sampling_rate);
  428. define_one_global_rw(inc_cpu_load_at_min_freq);
  429. define_one_global_rw(inc_cpu_load);
  430. define_one_global_rw(dec_cpu_load_at_min_freq);
  431. define_one_global_rw(dec_cpu_load);
  432. define_one_global_rw(freq_responsiveness);
  433. define_one_global_rw(io_is_busy);
  434. define_one_global_rw(cpus_up_rate);
  435. define_one_global_rw(cpus_down_rate);
  436.  
  437. static struct attribute *alucard_attributes[] = {
  438. &sampling_rate.attr,
  439. &inc_cpu_load_at_min_freq.attr,
  440. &inc_cpu_load.attr,
  441. &dec_cpu_load_at_min_freq.attr,
  442. &dec_cpu_load.attr,
  443. &freq_responsiveness.attr,
  444. &io_is_busy.attr,
  445. &pump_inc_step_at_min_freq_1.attr,
  446. &pump_inc_step_at_min_freq_2.attr,
  447. &pump_inc_step_at_min_freq_3.attr,
  448. &pump_inc_step_at_min_freq_4.attr,
  449. &pump_inc_step_1.attr,
  450. &pump_inc_step_2.attr,
  451. &pump_inc_step_3.attr,
  452. &pump_inc_step_4.attr,
  453. &pump_dec_step_1.attr,
  454. &pump_dec_step_2.attr,
  455. &pump_dec_step_3.attr,
  456. &pump_dec_step_4.attr,
  457. &cpus_up_rate.attr,
  458. &cpus_down_rate.attr,
  459. NULL
  460. };
  461.  
  462. static struct attribute_group alucard_attr_group = {
  463. .attrs = alucard_attributes,
  464. .name = "alucard",
  465. };
  466.  
  467. /************************** sysfs end ************************/
  468.  
  469. static void alucard_check_cpu(struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo)
  470. {
  471. struct cpufreq_policy *cpu_policy;
  472. unsigned int freq_responsiveness = alucard_tuners_ins.freq_responsiveness;
  473. int dec_cpu_load = alucard_tuners_ins.dec_cpu_load;
  474. int inc_cpu_load = alucard_tuners_ins.inc_cpu_load;
  475. int pump_inc_step = this_alucard_cpuinfo->pump_inc_step;
  476. int pump_dec_step = this_alucard_cpuinfo->pump_dec_step;
  477. u64 cur_wall_time, cur_idle_time;
  478. unsigned int wall_time, idle_time;
  479. unsigned int index = 0;
  480. unsigned int hi_index = 0;
  481. int cur_load = -1;
  482. unsigned int cpu;
  483. int io_busy = alucard_tuners_ins.io_is_busy;
  484. unsigned int cpus_up_rate = alucard_tuners_ins.cpus_up_rate;
  485. unsigned int cpus_down_rate = alucard_tuners_ins.cpus_down_rate;
  486. bool check_up = false, check_down = false;
  487.  
  488. cpu = this_alucard_cpuinfo->cpu;
  489. cpu_policy = this_alucard_cpuinfo->cur_policy;
  490. if (cpu_policy == NULL)
  491. return;
  492.  
  493. cur_idle_time = get_cpu_idle_time(cpu, &cur_wall_time, io_busy);
  494.  
  495. wall_time = (unsigned int)
  496. (cur_wall_time - this_alucard_cpuinfo->prev_cpu_wall);
  497. this_alucard_cpuinfo->prev_cpu_wall = cur_wall_time;
  498.  
  499. idle_time = (unsigned int)
  500. (cur_idle_time - this_alucard_cpuinfo->prev_cpu_idle);
  501. this_alucard_cpuinfo->prev_cpu_idle = cur_idle_time;
  502.  
  503. /*printk(KERN_ERR "TIMER CPU[%u], wall[%u], idle[%u]\n",cpu, wall_time, idle_time);*/
  504. if (wall_time >= idle_time) { /*if wall_time < idle_time, evaluate cpu load next time*/
  505. cur_load = wall_time > idle_time ? (100 * (wall_time - idle_time)) / wall_time : 1;/*if wall_time is equal to idle_time cpu_load is equal to 1*/
  506.  
  507. // cpufreq_notify_utilization(cpu_policy, cur_load);
  508.  
  509. if (this_alucard_cpuinfo->up_rate > cpus_up_rate)
  510. this_alucard_cpuinfo->up_rate = 1;
  511.  
  512. if (this_alucard_cpuinfo->down_rate > cpus_down_rate)
  513. this_alucard_cpuinfo->down_rate = 1;
  514.  
  515. /* Maximum increasing frequency possible */
  516. cpufreq_frequency_table_target(cpu_policy, this_alucard_cpuinfo->freq_table, max(cur_load * (cpu_policy->max / 100), cpu_policy->min),
  517. CPUFREQ_RELATION_L, &hi_index);
  518.  
  519. cpufreq_frequency_table_target(cpu_policy, this_alucard_cpuinfo->freq_table, cpu_policy->cur,
  520. CPUFREQ_RELATION_C, &index);
  521.  
  522. check_up = (this_alucard_cpuinfo->up_rate % cpus_up_rate == 0);
  523. check_down = (this_alucard_cpuinfo->down_rate % cpus_down_rate == 0);
  524.  
  525. /* CPUs Online Scale Frequency*/
  526. if (cpu_policy->cur < freq_responsiveness) {
  527. inc_cpu_load = alucard_tuners_ins.inc_cpu_load_at_min_freq;
  528. dec_cpu_load = alucard_tuners_ins.dec_cpu_load_at_min_freq;
  529. pump_inc_step = this_alucard_cpuinfo->pump_inc_step_at_min_freq;
  530. hi_index = this_alucard_cpuinfo->max_index;
  531. check_up = true;
  532. check_down = true;
  533. }
  534. /* Check for frequency increase or for frequency decrease */
  535. if (cur_load >= inc_cpu_load && index < hi_index) {
  536. ++this_alucard_cpuinfo->up_rate;
  537. if (check_up) {
  538. if ((index + pump_inc_step) >= hi_index)
  539. index = hi_index;
  540. else
  541. index += pump_inc_step;
  542.  
  543. this_alucard_cpuinfo->up_rate = 1;
  544. this_alucard_cpuinfo->down_rate = 1;
  545. }
  546. } else if (cur_load < dec_cpu_load && index > this_alucard_cpuinfo->min_index) {
  547. ++this_alucard_cpuinfo->down_rate;
  548. if (check_down) {
  549. if ((index - pump_dec_step) <= this_alucard_cpuinfo->min_index)
  550. index = this_alucard_cpuinfo->min_index;
  551. else
  552. index -= pump_dec_step;
  553.  
  554. this_alucard_cpuinfo->up_rate = 1;
  555. this_alucard_cpuinfo->down_rate = 1;
  556. }
  557. }
  558.  
  559. this_alucard_cpuinfo->cur_freq = this_alucard_cpuinfo->freq_table[index].frequency;
  560. /*printk(KERN_ERR "FREQ CALC.: CPU[%u], load[%d], target freq[%u], cur freq[%u], min freq[%u], max_freq[%u]\n",cpu, cur_load, this_alucard_cpuinfo->freq_table[index].frequency, cpu_policy->cur, cpu_policy->min, this_alucard_cpuinfo->freq_table[hi_index].frequency);*/
  561. if (this_alucard_cpuinfo->cur_freq != cpu_policy->cur) {
  562. __cpufreq_driver_target(cpu_policy, this_alucard_cpuinfo->cur_freq, CPUFREQ_RELATION_C);
  563. }
  564. }
  565. }
  566.  
  567. static void do_alucard_timer(struct work_struct *work)
  568. {
  569. struct cpufreq_alucard_cpuinfo *alucard_cpuinfo;
  570. int delay;
  571. unsigned int cpu;
  572.  
  573. alucard_cpuinfo = container_of(work, struct cpufreq_alucard_cpuinfo, work.work);
  574. cpu = alucard_cpuinfo->cpu;
  575.  
  576. mutex_lock(&alucard_cpuinfo->timer_mutex);
  577.  
  578. alucard_check_cpu(alucard_cpuinfo);
  579.  
  580. delay = usecs_to_jiffies(alucard_tuners_ins.sampling_rate);
  581.  
  582. /* We want all CPUs to do sampling nearly on same jiffy */
  583. if (num_online_cpus() > 1)
  584. delay -= jiffies % delay;
  585.  
  586. if (delay > 0)
  587. mod_delayed_work_on(cpu, system_wq, &alucard_cpuinfo->work, delay);
  588. else
  589. mod_delayed_work_on(cpu, system_wq, &alucard_cpuinfo->work, usecs_to_jiffies(MIN_SAMPLING_RATE));
  590.  
  591. mutex_unlock(&alucard_cpuinfo->timer_mutex);
  592. }
  593.  
  594. static int cpufreq_governor_alucard(struct cpufreq_policy *policy,
  595. unsigned int event)
  596. {
  597. unsigned int cpu;
  598. struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo;
  599. int rc, delay;
  600. int io_busy;
  601.  
  602. cpu = policy->cpu;
  603. io_busy = alucard_tuners_ins.io_is_busy;
  604. this_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, cpu);
  605. this_alucard_cpuinfo->freq_table = cpufreq_frequency_get_table(cpu);
  606.  
  607. switch (event) {
  608. case CPUFREQ_GOV_START:
  609. if ((!cpu_online(cpu)) || (!policy->cur))
  610. return -EINVAL;
  611.  
  612. mutex_lock(&alucard_mutex);
  613.  
  614. this_alucard_cpuinfo->cpu = cpu;
  615. this_alucard_cpuinfo->cur_policy = policy;
  616.  
  617. this_alucard_cpuinfo->prev_cpu_idle = get_cpu_idle_time(cpu, &this_alucard_cpuinfo->prev_cpu_wall, io_busy);
  618.  
  619. cpufreq_frequency_table_target(policy, this_alucard_cpuinfo->freq_table, policy->min,
  620. CPUFREQ_RELATION_L, &this_alucard_cpuinfo->min_index);
  621.  
  622. cpufreq_frequency_table_target(policy, this_alucard_cpuinfo->freq_table, policy->max,
  623. CPUFREQ_RELATION_H, &this_alucard_cpuinfo->max_index);
  624.  
  625. this_alucard_cpuinfo->cur_freq = policy->cur;
  626.  
  627. alucard_enable++;
  628. /*
  629. * Start the timerschedule work, when this governor
  630. * is used for first time
  631. */
  632. if (alucard_enable == 1) {
  633. rc = sysfs_create_group(cpufreq_global_kobject,
  634. &alucard_attr_group);
  635. if (rc) {
  636. alucard_enable--;
  637. mutex_unlock(&alucard_mutex);
  638. return rc;
  639. }
  640. }
  641. this_alucard_cpuinfo->up_rate = 1;
  642. this_alucard_cpuinfo->down_rate = 1;
  643. this_alucard_cpuinfo->governor_enabled = true;
  644. mutex_unlock(&alucard_mutex);
  645.  
  646. mutex_init(&this_alucard_cpuinfo->timer_mutex);
  647.  
  648. delay = usecs_to_jiffies(alucard_tuners_ins.sampling_rate);
  649. /* We want all CPUs to do sampling nearly on same jiffy */
  650. if (num_online_cpus() > 1)
  651. delay -= jiffies % delay;
  652.  
  653. INIT_DEFERRABLE_WORK(&this_alucard_cpuinfo->work, do_alucard_timer);
  654.  
  655. queue_delayed_work_on(this_alucard_cpuinfo->cpu, system_wq, &this_alucard_cpuinfo->work, delay);
  656.  
  657. break;
  658.  
  659. case CPUFREQ_GOV_STOP:
  660. cancel_delayed_work_sync(&this_alucard_cpuinfo->work);
  661.  
  662. mutex_lock(&alucard_mutex);
  663. mutex_destroy(&this_alucard_cpuinfo->timer_mutex);
  664.  
  665. this_alucard_cpuinfo->governor_enabled = false;
  666.  
  667. this_alucard_cpuinfo->cur_policy = NULL;
  668.  
  669. alucard_enable--;
  670. if (!alucard_enable) {
  671. sysfs_remove_group(cpufreq_global_kobject,
  672. &alucard_attr_group);
  673. }
  674. this_alucard_cpuinfo->cur_freq = 0;
  675. mutex_unlock(&alucard_mutex);
  676.  
  677. break;
  678.  
  679. case CPUFREQ_GOV_LIMITS:
  680. if (!this_alucard_cpuinfo->cur_policy) {
  681. pr_debug("Unable to limit cpu freq due to cur_policy == NULL\n");
  682. return -EPERM;
  683. }
  684. mutex_lock(&this_alucard_cpuinfo->timer_mutex);
  685. cpufreq_frequency_table_target(policy, this_alucard_cpuinfo->freq_table, policy->min,
  686. CPUFREQ_RELATION_L, &this_alucard_cpuinfo->min_index);
  687.  
  688. cpufreq_frequency_table_target(policy, this_alucard_cpuinfo->freq_table, policy->max,
  689. CPUFREQ_RELATION_H, &this_alucard_cpuinfo->max_index);
  690.  
  691. if (policy->max < this_alucard_cpuinfo->cur_policy->cur)
  692. __cpufreq_driver_target(this_alucard_cpuinfo->cur_policy,
  693. policy->max, CPUFREQ_RELATION_H);
  694. else if (policy->min > this_alucard_cpuinfo->cur_policy->cur)
  695. __cpufreq_driver_target(this_alucard_cpuinfo->cur_policy,
  696. policy->min, CPUFREQ_RELATION_L);
  697.  
  698. this_alucard_cpuinfo->cur_freq = policy->cur;
  699. mutex_unlock(&this_alucard_cpuinfo->timer_mutex);
  700.  
  701. break;
  702. }
  703. return 0;
  704. }
  705.  
  706. #ifndef CONFIG_CPU_FREQ_DEFAULT_GOV_ALUCARD
  707. static
  708. #endif
  709. struct cpufreq_governor cpufreq_gov_alucard = {
  710. .name = "alucard",
  711. .governor = cpufreq_governor_alucard,
  712. .owner = THIS_MODULE,
  713. };
  714.  
  715.  
  716. static int __init cpufreq_gov_alucard_init(void)
  717. {
  718. unsigned int cpu;
  719.  
  720. for_each_possible_cpu(cpu) {
  721. struct cpufreq_alucard_cpuinfo *this_alucard_cpuinfo = &per_cpu(od_alucard_cpuinfo, cpu);
  722.  
  723. this_alucard_cpuinfo->pump_inc_step_at_min_freq = PUMP_INC_STEP_AT_MIN_FREQ;
  724. this_alucard_cpuinfo->pump_inc_step = PUMP_INC_STEP;
  725. this_alucard_cpuinfo->pump_dec_step = PUMP_DEC_STEP;
  726. }
  727.  
  728. return cpufreq_register_governor(&cpufreq_gov_alucard);
  729. }
  730.  
  731. static void __exit cpufreq_gov_alucard_exit(void)
  732. {
  733. cpufreq_unregister_governor(&cpufreq_gov_alucard);
  734. }
  735.  
  736. MODULE_AUTHOR("Alucard24@XDA");
  737. MODULE_DESCRIPTION("'cpufreq_alucard' - A dynamic cpufreq governor v1.1 (SnapDragon)");
  738. MODULE_LICENSE("GPL");
  739.  
  740. #ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_ALUCARD
  741. fs_initcall(cpufreq_gov_alucard_init);
  742. #else
  743. module_init(cpufreq_gov_alucard_init);
  744. #endif
  745. module_exit(cpufreq_gov_alucard_exit);
Add Comment
Please, Sign In to add comment