init
[cpufrequi] / sysfs.c
1 /*
2  *  (C) 2004-2009  Dominik Brodowski <linux@dominikbrodowski.de>
3  *
4  *  Licensed under the terms of the GNU GPL License version 2.
5  */
6
7 #include <stdio.h>
8 #include <errno.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <limits.h>
12 #include <limits.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17
18 #include "cpufreq.h"
19
20 #define PATH_TO_CPU "/sys/devices/system/cpu/"
21 #define MAX_LINE_LEN 255
22 #define SYSFS_PATH_MAX 255
23
24 /* helper function to read file from /sys into given buffer */
25 /* fname is a relative path under "cpuX/cpufreq" dir */
26 unsigned int sysfs_read_file(unsigned int cpu, const char *fname, char *buf, size_t buflen)
27 {
28         char path[SYSFS_PATH_MAX];
29         int fd;
30         size_t numread;
31
32         snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
33                          cpu, fname);
34
35         if ( ( fd = open(path, O_RDONLY) ) == -1 )
36                 return 0;
37
38         numread = read(fd, buf, buflen - 1);
39         if ( numread < 1 )
40         {
41                 close(fd);
42                 return 0;
43         }
44
45         buf[numread] = '\0';
46         close(fd);
47
48         return numread;
49 }
50
51 /* helper function to write a new value to a /sys file */
52 /* fname is a relative path under "cpuX/cpufreq" dir */
53 unsigned int sysfs_write_file(unsigned int cpu, const char *fname, const char *value, size_t len)
54 {
55         char path[SYSFS_PATH_MAX];
56         int fd;
57         size_t numwrite;
58
59         snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
60                          cpu, fname);
61
62         if ( ( fd = open(path, O_WRONLY) ) == -1 )
63                 return 0;
64
65         numwrite = write(fd, value, len);
66         if ( numwrite < 1 )
67         {
68                 close(fd);
69                 return 0;
70         }
71
72         close(fd);
73
74         return numwrite;
75 }
76
77 /* read access to files which contain one numeric value */
78
79 enum {
80         CPUINFO_CUR_FREQ,
81         CPUINFO_MIN_FREQ,
82         CPUINFO_MAX_FREQ,
83         CPUINFO_LATENCY,
84         SCALING_CUR_FREQ,
85         SCALING_MIN_FREQ,
86         SCALING_MAX_FREQ,
87         STATS_NUM_TRANSITIONS,
88         ONDEMAND_UP_THRESHOLD,
89         ONDEMAND_SAMPLING_RATE,
90         ONDEMAND_SAMPLING_RATE_MIN,
91         ONDEMAND_SAMPLING_RATE_MAX,
92         ONDEMAND_IGNORE_NICE_LOAD,
93         MAX_VALUE_FILES
94 };
95
96 static const char *value_files[MAX_VALUE_FILES] = {
97         [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq",
98         [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq",
99         [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq",
100         [CPUINFO_LATENCY]  = "cpuinfo_transition_latency",
101         [SCALING_CUR_FREQ] = "scaling_cur_freq",
102         [SCALING_MIN_FREQ] = "scaling_min_freq",
103         [SCALING_MAX_FREQ] = "scaling_max_freq",
104         [STATS_NUM_TRANSITIONS] = "stats/total_trans",
105         [ONDEMAND_UP_THRESHOLD] = "ondemand/up_threshold",
106         [ONDEMAND_SAMPLING_RATE] = "ondemand/sampling_rate",
107         [ONDEMAND_SAMPLING_RATE_MIN] = "ondemand/sampling_rate_min",
108         [ONDEMAND_SAMPLING_RATE_MAX] = "ondemand/sampling_rate_max",
109         [ONDEMAND_IGNORE_NICE_LOAD] = "ondemand/ignore_nice_load"
110 };
111
112
113 static unsigned long sysfs_get_one_value(unsigned int cpu, unsigned int which)
114 {
115         unsigned long value;
116         unsigned int len;
117         char linebuf[MAX_LINE_LEN];
118         char *endp;
119
120         if ( which >= MAX_VALUE_FILES )
121                 return 0;
122
123         if ( ( len = sysfs_read_file(cpu, value_files[which], linebuf, sizeof(linebuf))) == 0 )
124         {
125                 return 0;
126         }
127
128         value = strtoul(linebuf, &endp, 0);
129
130         if ( endp == linebuf || errno == ERANGE )
131                 return 0;
132
133         return value;
134 }
135
136 /* read access to files which contain one string */
137
138 enum {
139         SCALING_DRIVER,
140         SCALING_GOVERNOR,
141         MAX_STRING_FILES
142 };
143
144 static const char *string_files[MAX_STRING_FILES] = {
145         [SCALING_DRIVER] = "scaling_driver",
146         [SCALING_GOVERNOR] = "scaling_governor",
147 };
148
149
150 static char * sysfs_get_one_string(unsigned int cpu, unsigned int which)
151 {
152         char linebuf[MAX_LINE_LEN];
153         char *result;
154         unsigned int len;
155
156         if (which >= MAX_STRING_FILES)
157                 return NULL;
158
159         if ( ( len = sysfs_read_file(cpu, string_files[which], linebuf, sizeof(linebuf))) == 0 )
160         {
161                 return NULL;
162         }
163
164         if ( ( result = strdup(linebuf) ) == NULL )
165                 return NULL;
166
167         if (result[strlen(result) - 1] == '\n')
168                 result[strlen(result) - 1] = '\0';
169
170         return result;
171 }
172
173 /* write access */
174
175 enum {
176         WRITE_SCALING_MIN_FREQ,
177         WRITE_SCALING_MAX_FREQ,
178         WRITE_SCALING_GOVERNOR,
179         WRITE_SCALING_SET_SPEED,
180         WRITE_ONDEMAND_UP_THRESHOLD,
181         WRITE_ONDEMAND_SAMPLING_RATE,
182         WRITE_ONDEMAND_IGNORE_NICE_LOAD,
183         MAX_WRITE_FILES
184 };
185
186 static const char *write_files[MAX_VALUE_FILES] = {
187         [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq",
188         [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq",
189         [WRITE_SCALING_GOVERNOR] = "scaling_governor",
190         [WRITE_SCALING_SET_SPEED] = "scaling_setspeed",
191         [WRITE_ONDEMAND_UP_THRESHOLD] = "ondemand/up_threshold",
192         [WRITE_ONDEMAND_SAMPLING_RATE] = "ondemand/sampling_rate",
193         [WRITE_ONDEMAND_IGNORE_NICE_LOAD] = "ondemand/ignore_nice_load"
194 };
195
196 static int sysfs_write_one_value(unsigned int cpu, unsigned int which,
197                                  const char *new_value, size_t len)
198 {
199         if (which >= MAX_WRITE_FILES)
200                 return 0;
201
202         if ( sysfs_write_file(cpu, write_files[which], new_value, len) != len )
203                 return -ENODEV;
204
205         return 0;
206 };
207
208
209 int sysfs_cpu_exists(unsigned int cpu)
210 {
211         char file[SYSFS_PATH_MAX];
212         struct stat statbuf;
213
214         snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu);
215
216         if ( stat(file, &statbuf) != 0 )
217                 return -ENOSYS;
218
219         return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS;
220 }
221
222
223 unsigned long sysfs_get_freq_kernel(unsigned int cpu)
224 {
225         return sysfs_get_one_value(cpu, SCALING_CUR_FREQ);
226 }
227
228 unsigned long sysfs_get_freq_hardware(unsigned int cpu)
229 {
230         return sysfs_get_one_value(cpu, CPUINFO_CUR_FREQ);
231 }
232
233 unsigned long sysfs_get_transition_latency(unsigned int cpu)
234 {
235         return sysfs_get_one_value(cpu, CPUINFO_LATENCY);
236 }
237
238 int sysfs_get_hardware_limits(unsigned int cpu,
239                               unsigned long *min,
240                               unsigned long *max)
241 {
242         if ((!min) || (!max))
243                 return -EINVAL;
244
245         *min = sysfs_get_one_value(cpu, CPUINFO_MIN_FREQ);
246         if (!*min)
247                 return -ENODEV;
248
249         *max = sysfs_get_one_value(cpu, CPUINFO_MAX_FREQ);
250         if (!*max)
251                 return -ENODEV;
252
253         return 0;
254 }
255
256 char * sysfs_get_driver(unsigned int cpu) {
257         return sysfs_get_one_string(cpu, SCALING_DRIVER);
258 }
259
260 struct cpufreq_policy * sysfs_get_policy(unsigned int cpu) {
261         struct cpufreq_policy *policy;
262
263         policy = malloc(sizeof(struct cpufreq_policy));
264         if (!policy)
265                 return NULL;
266
267         policy->governor = sysfs_get_one_string(cpu, SCALING_GOVERNOR);
268         if (!policy->governor) {
269                 free(policy);
270                 return NULL;
271         }
272         policy->min = sysfs_get_one_value(cpu, SCALING_MIN_FREQ);
273         policy->max = sysfs_get_one_value(cpu, SCALING_MAX_FREQ);
274         if ((!policy->min) || (!policy->max)) {
275                 free(policy->governor);
276                 free(policy);
277                 return NULL;
278         }
279
280         return policy;
281 }
282
283 struct cpufreq_available_governors * sysfs_get_available_governors(unsigned int cpu) {
284         struct cpufreq_available_governors *first = NULL;
285         struct cpufreq_available_governors *current = NULL;
286         char linebuf[MAX_LINE_LEN];
287         unsigned int pos, i;
288         unsigned int len;
289
290         if ( ( len = sysfs_read_file(cpu, "scaling_available_governors", linebuf, sizeof(linebuf))) == 0 )
291         {
292                 return NULL;
293         }
294
295         pos = 0;
296         for ( i = 0; i < len; i++ )
297         {
298                 if ( linebuf[i] == ' ' || linebuf[i] == '\n' )
299                 {
300                         if ( i - pos < 2 )
301                                 continue;
302                         if ( current ) {
303                                 current->next = malloc(sizeof *current );
304                                 if ( ! current->next )
305                                         goto error_out;
306                                 current = current->next;
307                         } else {
308                                 first = malloc( sizeof *first );
309                                 if ( ! first )
310                                         goto error_out;
311                                 current = first;
312                         }
313                         current->first = first;
314                         current->next = NULL;
315
316                         current->governor = malloc(i - pos + 1);
317                         if ( ! current->governor )
318                                 goto error_out;
319
320                         memcpy( current->governor, linebuf + pos, i - pos);
321                         current->governor[i - pos] = '\0';
322                         pos = i + 1;
323                 }
324         }
325
326         return first;
327
328  error_out:
329         while ( first ) {
330                 current = first->next;
331                 if ( first->governor )
332                         free( first->governor );
333                 free( first );
334                 first = current;
335         }
336         return NULL;
337 }
338
339
340 struct cpufreq_available_frequencies * sysfs_get_available_frequencies(unsigned int cpu) {
341         struct cpufreq_available_frequencies *first = NULL;
342         struct cpufreq_available_frequencies *current = NULL;
343         char one_value[SYSFS_PATH_MAX];
344         char linebuf[MAX_LINE_LEN];
345         unsigned int pos, i;
346         unsigned int len;
347
348         if ( ( len = sysfs_read_file(cpu, "scaling_available_frequencies", linebuf, sizeof(linebuf))) == 0 )
349         {
350                 return NULL;
351         }
352
353         pos = 0;
354         for ( i = 0; i < len; i++ )
355         {
356                 if ( linebuf[i] == ' ' || linebuf[i] == '\n' )
357                 {
358                         if ( i - pos < 2 )
359                                 continue;
360                         if ( i - pos >= SYSFS_PATH_MAX )
361                                 goto error_out;
362                         if ( current ) {
363                                 current->next = malloc(sizeof *current );
364                                 if ( ! current->next )
365                                         goto error_out;
366                                 current = current->next;
367                         } else {
368                                 first = malloc(sizeof *first );
369                                 if ( ! first )
370                                         goto error_out;
371                                 current = first;
372                         }
373                         current->first = first;
374                         current->next = NULL;
375
376                         memcpy(one_value, linebuf + pos, i - pos);
377                         one_value[i - pos] = '\0';
378                         if ( sscanf(one_value, "%lu", &current->frequency) != 1 )
379                                 goto error_out;
380
381                         pos = i + 1;
382                 }
383         }
384
385         return first;
386
387  error_out:
388         while ( first ) {
389                 current = first->next;
390                 free(first);
391                 first = current;
392         }
393         return NULL;
394 }
395
396 static struct cpufreq_affected_cpus * sysfs_get_cpu_list(unsigned int cpu,
397                                                          const char *file) {
398         struct cpufreq_affected_cpus *first = NULL;
399         struct cpufreq_affected_cpus *current = NULL;
400         char one_value[SYSFS_PATH_MAX];
401         char linebuf[MAX_LINE_LEN];
402         unsigned int pos, i;
403         unsigned int len;
404
405         if ( ( len = sysfs_read_file(cpu, file, linebuf, sizeof(linebuf))) == 0 )
406         {
407                 return NULL;
408         }
409
410         pos = 0;
411         for ( i = 0; i < len; i++ )
412         {
413                 if ( i == len || linebuf[i] == ' ' || linebuf[i] == '\n' )
414                 {
415                         if ( i - pos  < 1 )
416                                 continue;
417                         if ( i - pos >= SYSFS_PATH_MAX )
418                                 goto error_out;
419                         if ( current ) {
420                                 current->next = malloc(sizeof *current);
421                                 if ( ! current->next )
422                                         goto error_out;
423                                 current = current->next;
424                         } else {
425                                 first = malloc(sizeof *first);
426                                 if ( ! first )
427                                         goto error_out;
428                                 current = first;
429                         }
430                         current->first = first;
431                         current->next = NULL;
432
433                         memcpy(one_value, linebuf + pos, i - pos);
434                         one_value[i - pos] = '\0';
435
436                         if ( sscanf(one_value, "%u", &current->cpu) != 1 )
437                                 goto error_out;
438
439                         pos = i + 1;
440                 }
441         }
442
443         return first;
444
445  error_out:
446         while (first) {
447                 current = first->next;
448                 free(first);
449                 first = current;
450         }
451         return NULL;
452 }
453
454 struct cpufreq_affected_cpus * sysfs_get_affected_cpus(unsigned int cpu) {
455         return sysfs_get_cpu_list(cpu, "affected_cpus");
456 }
457
458 struct cpufreq_affected_cpus * sysfs_get_related_cpus(unsigned int cpu) {
459         return sysfs_get_cpu_list(cpu, "related_cpus");
460 }
461
462 struct cpufreq_stats * sysfs_get_stats(unsigned int cpu, unsigned long long *total_time) {
463         struct cpufreq_stats *first = NULL;
464         struct cpufreq_stats *current = NULL;
465         char one_value[SYSFS_PATH_MAX];
466         char linebuf[MAX_LINE_LEN];
467         unsigned int pos, i;
468         unsigned int len;
469
470         if ( ( len = sysfs_read_file(cpu, "stats/time_in_state", linebuf, sizeof(linebuf))) == 0 )
471                 return NULL;
472
473         *total_time = 0;
474         pos = 0;
475         for ( i = 0; i < len; i++ )
476         {
477                 if ( i == strlen(linebuf) || linebuf[i] == '\n' )
478                 {
479                         if ( i - pos < 2 )
480                                 continue;
481                         if ( (i - pos) >= SYSFS_PATH_MAX )
482                                 goto error_out;
483                         if ( current ) {
484                                 current->next = malloc(sizeof *current );
485                                 if ( ! current->next )
486                                         goto error_out;
487                                 current = current->next;
488                         } else {
489                                 first = malloc(sizeof *first );
490                                 if ( ! first )
491                                         goto error_out;
492                                 current = first;
493                         }
494                         current->first = first;
495                         current->next = NULL;
496
497                         memcpy(one_value, linebuf + pos, i - pos);
498                         one_value[i - pos] = '\0';
499                         if ( sscanf(one_value, "%lu %llu", &current->frequency, &current->time_in_state) != 2 )
500                                 goto error_out;
501
502                         *total_time = *total_time + current->time_in_state;
503                         pos = i + 1;
504                 }
505         }
506
507         return first;
508
509  error_out:
510         while ( first ) {
511                 current = first->next;
512                 free(first);
513                 first = current;
514         }
515         return NULL;
516 }
517
518 unsigned long sysfs_get_transitions(unsigned int cpu)
519 {
520         return sysfs_get_one_value(cpu, STATS_NUM_TRANSITIONS);
521 }
522
523 static int verify_gov(char *new_gov, char *passed_gov)
524 {
525         unsigned int i, j=0;
526
527         if (!passed_gov || (strlen(passed_gov) > 19))
528                 return -EINVAL;
529
530         strncpy(new_gov, passed_gov, 20);
531         for (i=0;i<20;i++) {
532                 if (j) {
533                         new_gov[i] = '\0';
534                         continue;
535                 }
536                 if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z')) {
537                         continue;
538                 }
539                 if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z')) {
540                         continue;
541                 }
542                 if (new_gov[i] == '-') {
543                         continue;
544                 }
545                 if (new_gov[i] == '_') {
546                         continue;
547                 }
548                 if (new_gov[i] == '\0') {
549                         j = 1;
550                         continue;
551                 }
552                 return -EINVAL;
553         }
554         new_gov[19] = '\0';
555         return 0;
556 }
557
558 int sysfs_modify_policy_governor(unsigned int cpu, char *governor)
559 {
560         char new_gov[SYSFS_PATH_MAX];
561
562         if (!governor)
563                 return -EINVAL;
564
565         if (verify_gov(new_gov, governor))
566                 return -EINVAL;
567
568         return sysfs_write_one_value(cpu, WRITE_SCALING_GOVERNOR, new_gov, strlen(new_gov));
569 };
570
571 int sysfs_modify_policy_max(unsigned int cpu, unsigned long max_freq)
572 {
573         char value[SYSFS_PATH_MAX];
574
575         snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq);
576
577         return sysfs_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, value, strlen(value));
578 };
579
580
581 int sysfs_modify_policy_min(unsigned int cpu, unsigned long min_freq)
582 {
583         char value[SYSFS_PATH_MAX];
584
585         snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq);
586
587         return sysfs_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, value, strlen(value));
588 };
589
590
591 int sysfs_set_policy(unsigned int cpu, struct cpufreq_policy *policy)
592 {
593         char min[SYSFS_PATH_MAX];
594         char max[SYSFS_PATH_MAX];
595         char gov[SYSFS_PATH_MAX];
596         int ret;
597         unsigned long old_min;
598         int write_max_first;
599
600         if (!policy || !(policy->governor))
601                 return -EINVAL;
602
603         if (policy->max < policy->min)
604                 return -EINVAL;
605
606         if (verify_gov(gov, policy->governor))
607                 return -EINVAL;
608
609         snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min);
610         snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max);
611
612         old_min = sysfs_get_one_value(cpu, SCALING_MIN_FREQ);
613         write_max_first = (old_min && (policy->max < old_min) ? 0 : 1);
614
615         if (write_max_first) {
616                 ret = sysfs_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, max, strlen(max));
617                 if (ret)
618                         return ret;
619         }
620
621         ret = sysfs_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min, strlen(min));
622         if (ret)
623                 return ret;
624
625         if (!write_max_first) {
626                 ret = sysfs_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, max, strlen(max));
627                 if (ret)
628                         return ret;
629         }
630
631         return sysfs_write_one_value(cpu, WRITE_SCALING_GOVERNOR, gov, strlen(gov));
632 }
633
634 int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency) {
635         struct cpufreq_policy *pol = sysfs_get_policy(cpu);
636         char userspace_gov[] = "userspace";
637         char freq[SYSFS_PATH_MAX];
638         int ret;
639
640         if (!pol)
641                 return -ENODEV;
642
643         if (strncmp(pol->governor, userspace_gov, 9) != 0) {
644                 ret = sysfs_modify_policy_governor(cpu, userspace_gov);
645                 if (ret) {
646                         cpufreq_put_policy(pol);
647                         return (ret);
648                 }
649         }
650
651         cpufreq_put_policy(pol);
652
653         snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency);
654
655         return sysfs_write_one_value(cpu, WRITE_SCALING_SET_SPEED, freq, strlen(freq));
656 }
657
658 unsigned long sysfs_get_up_threshold(unsigned int cpu)
659 {
660 //    unsigned int len;
661 //    char linebuf[MAX_LINE_LEN];
662 //    int result;
663 //    if ( ( len = sysfs_read_file(cpu, "ondemand/up_threshold", linebuf, sizeof(linebuf))) == 0 )
664 //    {
665 //            return -ENODEV;
666 //    }
667 //    if ( ( result = strdup(linebuf) ) == NULL )
668 //            return NULL;
669 //
670 //    if (result[strlen(result) - 1] == '\n')
671 //            result[strlen(result) - 1] = '\0';
672
673     return sysfs_get_one_value(cpu, ONDEMAND_UP_THRESHOLD);
674 }
675
676 unsigned long sysfs_get_sampling_rate(unsigned int cpu)
677 {
678     return sysfs_get_one_value(cpu, ONDEMAND_SAMPLING_RATE);
679 }
680
681 int sysfs_set_up_threshold(unsigned int cpu, unsigned long target_up_threshold)
682 {
683     char upthreshold[SYSFS_PATH_MAX];
684     unsigned long upthreshold_target;
685     upthreshold_target = target_up_threshold;
686     if(upthreshold_target < 15)
687         upthreshold_target = 15;
688     if(upthreshold_target > 100)
689         upthreshold_target = 100;
690     snprintf(upthreshold, SYSFS_PATH_MAX, "%lu", upthreshold_target);
691     return sysfs_write_one_value(cpu, WRITE_ONDEMAND_UP_THRESHOLD, upthreshold, strlen(upthreshold));
692 }
693
694 int sysfs_set_sampling_rate(unsigned int cpu, unsigned long target_sampling_rate)
695 {
696     char samplingrate[SYSFS_PATH_MAX];
697     unsigned long samplingrate_min, samplingrate_max, samplingrate_target;
698     samplingrate_target = target_sampling_rate;
699     samplingrate_min = sysfs_get_one_value(cpu, ONDEMAND_SAMPLING_RATE_MIN);
700     samplingrate_max = sysfs_get_one_value(cpu, ONDEMAND_SAMPLING_RATE_MAX);
701     if(samplingrate_target < samplingrate_min)
702         samplingrate_target = samplingrate_min;
703     if(samplingrate_target > samplingrate_max)
704         samplingrate_target = samplingrate_max;
705     snprintf(samplingrate, SYSFS_PATH_MAX, "%lu", samplingrate_target);
706     return sysfs_write_one_value(cpu, WRITE_ONDEMAND_SAMPLING_RATE, samplingrate, strlen(samplingrate));
707 }
708
709 int sysfs_get_ignore_nice_load(unsigned int cpu)
710 {
711     char file[SYSFS_PATH_MAX];
712     struct stat statbuf;
713     int ret;
714
715     snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpufreq/ondemand/ignore_nice_load", cpu);
716
717     if ( stat(file, &statbuf) != 0 )
718             return -1;
719     ret = (int) sysfs_get_one_value(cpu, ONDEMAND_IGNORE_NICE_LOAD);
720     return ret;
721 }
722
723 int sysfs_set_ignore_nice_load(unsigned int cpu, int target_ignore_nice_load)
724 {
725     /* In addition:
726      *  echo "1" > /sys/devices/system/cpu/cpu0/cpufreq/ondemand/ignore_nice_load
727      * renice 1 `cat /syspart/applications/standby/background/tasks`
728      * renice 1 `ps | grep modest | cut -c1-5`
729      */
730
731     char file[SYSFS_PATH_MAX];
732     struct stat statbuf;
733
734     snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpufreq/ondemand/ignore_nice_load", cpu);
735
736     if ( stat(file, &statbuf) != 0 )
737             return -1;
738     else {
739         if(target_ignore_nice_load)
740             return sysfs_write_one_value(cpu, WRITE_ONDEMAND_IGNORE_NICE_LOAD, "1", strlen("1"));
741         else
742             return sysfs_write_one_value(cpu, WRITE_ONDEMAND_IGNORE_NICE_LOAD, "0", strlen("0"));
743     }
744 }
745
746 int sysfs_get_SmartReflex()
747 {
748     char buf[MAX_LINE_LEN];
749     struct stat statbuf;
750     unsigned long value;
751     char *endp;
752     int fd;
753     size_t numread;
754
755     /* TODO add  /sys/power/sr_vdd2_autocomp */
756
757     if ( stat("/sys/power/sr_vdd1_autocomp", &statbuf) != 0 )
758             return -1;
759
760     if ( ( fd = open("/sys/power/sr_vdd1_autocomp", O_RDONLY) ) == -1 )
761             return -1;
762
763     numread = read(fd, buf, MAX_LINE_LEN - 1);
764     if ( numread < 1 )
765     {
766             close(fd);
767             return -1;
768     }
769
770     buf[numread] = '\0';
771     close(fd);
772
773     value = strtoul(buf, &endp, 0);
774
775     if ( endp == buf || errno == ERANGE )
776             return -1;
777
778     return value;
779 }
780
781 int sysfs_set_SmartReflex(int target_ignore_nice_load)
782 {
783     struct stat statbuf;
784     int fd;
785     size_t numwrite;
786
787     if ( stat("/sys/power/sr_vdd1_autocomp", &statbuf) != 0 )
788             return -1;
789     if ( stat("/sys/power/sr_vdd2_autocomp", &statbuf) != 0 )
790             return -1;
791
792     if ( ( fd = open("/sys/power/sr_vdd1_autocomp", O_WRONLY) ) == -1 )
793             return -1;
794
795     if((target_ignore_nice_load==1) || (target_ignore_nice_load==3))
796         numwrite = write(fd, "1", strlen("1"));
797     else
798         numwrite = write(fd, "0", strlen("0"));
799     if ( numwrite < 1 ) {
800             close(fd);
801             return -1;
802     }
803
804     close(fd);
805
806     if ( ( fd = open("/sys/power/sr_vdd2_autocomp", O_WRONLY) ) == -1 )
807             return -2;
808
809     if((target_ignore_nice_load==2) || (target_ignore_nice_load==3))
810         numwrite = write(fd, "1", strlen("1"));
811     else
812         numwrite = write(fd, "0", strlen("0"));
813     if ( numwrite < 1 ) {
814             close(fd);
815             return -2;
816     }
817
818     close(fd);
819
820     return 0;
821 }