aboutsummaryrefslogtreecommitdiffstats
path: root/tools/power/cpupower/lib/sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/power/cpupower/lib/sysfs.c')
-rw-r--r--tools/power/cpupower/lib/sysfs.c221
1 files changed, 111 insertions, 110 deletions
diff --git a/tools/power/cpupower/lib/sysfs.c b/tools/power/cpupower/lib/sysfs.c
index c9b061fe87b1..9a35456ba6b2 100644
--- a/tools/power/cpupower/lib/sysfs.c
+++ b/tools/power/cpupower/lib/sysfs.c
@@ -24,14 +24,14 @@
24static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) 24static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
25{ 25{
26 int fd; 26 int fd;
27 size_t numread; 27 ssize_t numread;
28 28
29 if ( ( fd = open(path, O_RDONLY) ) == -1 ) 29 fd = open(path, O_RDONLY);
30 if (fd == -1)
30 return 0; 31 return 0;
31 32
32 numread = read(fd, buf, buflen - 1); 33 numread = read(fd, buf, buflen - 1);
33 if ( numread < 1 ) 34 if (numread < 1) {
34 {
35 close(fd); 35 close(fd);
36 return 0; 36 return 0;
37 } 37 }
@@ -39,7 +39,7 @@ static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
39 buf[numread] = '\0'; 39 buf[numread] = '\0';
40 close(fd); 40 close(fd);
41 41
42 return numread; 42 return (unsigned int) numread;
43} 43}
44 44
45 45
@@ -65,24 +65,24 @@ static unsigned int sysfs_cpufreq_write_file(unsigned int cpu,
65{ 65{
66 char path[SYSFS_PATH_MAX]; 66 char path[SYSFS_PATH_MAX];
67 int fd; 67 int fd;
68 size_t numwrite; 68 ssize_t numwrite;
69 69
70 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", 70 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s",
71 cpu, fname); 71 cpu, fname);
72 72
73 if ( ( fd = open(path, O_WRONLY) ) == -1 ) 73 fd = open(path, O_WRONLY);
74 if (fd == -1)
74 return 0; 75 return 0;
75 76
76 numwrite = write(fd, value, len); 77 numwrite = write(fd, value, len);
77 if ( numwrite < 1 ) 78 if (numwrite < 1) {
78 {
79 close(fd); 79 close(fd);
80 return 0; 80 return 0;
81 } 81 }
82 82
83 close(fd); 83 close(fd);
84 84
85 return numwrite; 85 return (unsigned int) numwrite;
86} 86}
87 87
88/* read access to files which contain one numeric value */ 88/* read access to files which contain one numeric value */
@@ -114,21 +114,23 @@ static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = {
114static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, 114static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu,
115 enum cpufreq_value which) 115 enum cpufreq_value which)
116{ 116{
117 unsigned long value; 117 unsigned long value;
118 unsigned int len; 118 unsigned int len;
119 char linebuf[MAX_LINE_LEN]; 119 char linebuf[MAX_LINE_LEN];
120 char *endp; 120 char *endp;
121 121
122 if ( which >= MAX_CPUFREQ_VALUE_READ_FILES ) 122 if (which >= MAX_CPUFREQ_VALUE_READ_FILES)
123 return 0; 123 return 0;
124 124
125 if ( ( len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which], 125 len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which],
126 linebuf, sizeof(linebuf))) == 0 ) 126 linebuf, sizeof(linebuf));
127
128 if (len == 0)
127 return 0; 129 return 0;
128 130
129 value = strtoul(linebuf, &endp, 0); 131 value = strtoul(linebuf, &endp, 0);
130 132
131 if ( endp == linebuf || errno == ERANGE ) 133 if (endp == linebuf || errno == ERANGE)
132 return 0; 134 return 0;
133 135
134 return value; 136 return value;
@@ -148,7 +150,7 @@ static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = {
148}; 150};
149 151
150 152
151static char * sysfs_cpufreq_get_one_string(unsigned int cpu, 153static char *sysfs_cpufreq_get_one_string(unsigned int cpu,
152 enum cpufreq_string which) 154 enum cpufreq_string which)
153{ 155{
154 char linebuf[MAX_LINE_LEN]; 156 char linebuf[MAX_LINE_LEN];
@@ -158,11 +160,13 @@ static char * sysfs_cpufreq_get_one_string(unsigned int cpu,
158 if (which >= MAX_CPUFREQ_STRING_FILES) 160 if (which >= MAX_CPUFREQ_STRING_FILES)
159 return NULL; 161 return NULL;
160 162
161 if ( ( len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which], 163 len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which],
162 linebuf, sizeof(linebuf))) == 0 ) 164 linebuf, sizeof(linebuf));
165 if (len == 0)
163 return NULL; 166 return NULL;
164 167
165 if ( ( result = strdup(linebuf) ) == NULL ) 168 result = strdup(linebuf);
169 if (result == NULL)
166 return NULL; 170 return NULL;
167 171
168 if (result[strlen(result) - 1] == '\n') 172 if (result[strlen(result) - 1] == '\n')
@@ -195,8 +199,8 @@ static int sysfs_cpufreq_write_one_value(unsigned int cpu,
195 if (which >= MAX_CPUFREQ_WRITE_FILES) 199 if (which >= MAX_CPUFREQ_WRITE_FILES)
196 return 0; 200 return 0;
197 201
198 if ( sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which], 202 if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which],
199 new_value, len) != len ) 203 new_value, len) != len)
200 return -ENODEV; 204 return -ENODEV;
201 205
202 return 0; 206 return 0;
@@ -235,11 +239,13 @@ int sysfs_get_freq_hardware_limits(unsigned int cpu,
235 return 0; 239 return 0;
236} 240}
237 241
238char * sysfs_get_freq_driver(unsigned int cpu) { 242char *sysfs_get_freq_driver(unsigned int cpu)
243{
239 return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER); 244 return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER);
240} 245}
241 246
242struct cpufreq_policy * sysfs_get_freq_policy(unsigned int cpu) { 247struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu)
248{
243 struct cpufreq_policy *policy; 249 struct cpufreq_policy *policy;
244 250
245 policy = malloc(sizeof(struct cpufreq_policy)); 251 policy = malloc(sizeof(struct cpufreq_policy));
@@ -270,27 +276,24 @@ sysfs_get_freq_available_governors(unsigned int cpu) {
270 unsigned int pos, i; 276 unsigned int pos, i;
271 unsigned int len; 277 unsigned int len;
272 278
273 if ( ( len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors", 279 len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors",
274 linebuf, sizeof(linebuf))) == 0 ) 280 linebuf, sizeof(linebuf));
275 { 281 if (len == 0)
276 return NULL; 282 return NULL;
277 }
278 283
279 pos = 0; 284 pos = 0;
280 for ( i = 0; i < len; i++ ) 285 for (i = 0; i < len; i++) {
281 { 286 if (linebuf[i] == ' ' || linebuf[i] == '\n') {
282 if ( linebuf[i] == ' ' || linebuf[i] == '\n' ) 287 if (i - pos < 2)
283 {
284 if ( i - pos < 2 )
285 continue; 288 continue;
286 if ( current ) { 289 if (current) {
287 current->next = malloc(sizeof *current ); 290 current->next = malloc(sizeof(*current));
288 if ( ! current->next ) 291 if (!current->next)
289 goto error_out; 292 goto error_out;
290 current = current->next; 293 current = current->next;
291 } else { 294 } else {
292 first = malloc( sizeof *first ); 295 first = malloc(sizeof(*first));
293 if ( ! first ) 296 if (!first)
294 goto error_out; 297 goto error_out;
295 current = first; 298 current = first;
296 } 299 }
@@ -298,10 +301,10 @@ sysfs_get_freq_available_governors(unsigned int cpu) {
298 current->next = NULL; 301 current->next = NULL;
299 302
300 current->governor = malloc(i - pos + 1); 303 current->governor = malloc(i - pos + 1);
301 if ( ! current->governor ) 304 if (!current->governor)
302 goto error_out; 305 goto error_out;
303 306
304 memcpy( current->governor, linebuf + pos, i - pos); 307 memcpy(current->governor, linebuf + pos, i - pos);
305 current->governor[i - pos] = '\0'; 308 current->governor[i - pos] = '\0';
306 pos = i + 1; 309 pos = i + 1;
307 } 310 }
@@ -310,11 +313,11 @@ sysfs_get_freq_available_governors(unsigned int cpu) {
310 return first; 313 return first;
311 314
312 error_out: 315 error_out:
313 while ( first ) { 316 while (first) {
314 current = first->next; 317 current = first->next;
315 if ( first->governor ) 318 if (first->governor)
316 free( first->governor ); 319 free(first->governor);
317 free( first ); 320 free(first);
318 first = current; 321 first = current;
319 } 322 }
320 return NULL; 323 return NULL;
@@ -330,30 +333,26 @@ sysfs_get_available_frequencies(unsigned int cpu) {
330 unsigned int pos, i; 333 unsigned int pos, i;
331 unsigned int len; 334 unsigned int len;
332 335
333 if ( ( len = sysfs_cpufreq_read_file(cpu, 336 len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies",
334 "scaling_available_frequencies", 337 linebuf, sizeof(linebuf));
335 linebuf, sizeof(linebuf))) == 0 ) 338 if (len == 0)
336 {
337 return NULL; 339 return NULL;
338 }
339 340
340 pos = 0; 341 pos = 0;
341 for ( i = 0; i < len; i++ ) 342 for (i = 0; i < len; i++) {
342 { 343 if (linebuf[i] == ' ' || linebuf[i] == '\n') {
343 if ( linebuf[i] == ' ' || linebuf[i] == '\n' ) 344 if (i - pos < 2)
344 {
345 if ( i - pos < 2 )
346 continue; 345 continue;
347 if ( i - pos >= SYSFS_PATH_MAX ) 346 if (i - pos >= SYSFS_PATH_MAX)
348 goto error_out; 347 goto error_out;
349 if ( current ) { 348 if (current) {
350 current->next = malloc(sizeof *current ); 349 current->next = malloc(sizeof(*current));
351 if ( ! current->next ) 350 if (!current->next)
352 goto error_out; 351 goto error_out;
353 current = current->next; 352 current = current->next;
354 } else { 353 } else {
355 first = malloc(sizeof *first ); 354 first = malloc(sizeof(*first));
356 if ( ! first ) 355 if (!first)
357 goto error_out; 356 goto error_out;
358 current = first; 357 current = first;
359 } 358 }
@@ -362,7 +361,7 @@ sysfs_get_available_frequencies(unsigned int cpu) {
362 361
363 memcpy(one_value, linebuf + pos, i - pos); 362 memcpy(one_value, linebuf + pos, i - pos);
364 one_value[i - pos] = '\0'; 363 one_value[i - pos] = '\0';
365 if ( sscanf(one_value, "%lu", &current->frequency) != 1 ) 364 if (sscanf(one_value, "%lu", &current->frequency) != 1)
366 goto error_out; 365 goto error_out;
367 366
368 pos = i + 1; 367 pos = i + 1;
@@ -372,7 +371,7 @@ sysfs_get_available_frequencies(unsigned int cpu) {
372 return first; 371 return first;
373 372
374 error_out: 373 error_out:
375 while ( first ) { 374 while (first) {
376 current = first->next; 375 current = first->next;
377 free(first); 376 free(first);
378 first = current; 377 first = current;
@@ -380,8 +379,9 @@ sysfs_get_available_frequencies(unsigned int cpu) {
380 return NULL; 379 return NULL;
381} 380}
382 381
383static struct cpufreq_affected_cpus * sysfs_get_cpu_list(unsigned int cpu, 382static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
384 const char *file) { 383 const char *file)
384{
385 struct cpufreq_affected_cpus *first = NULL; 385 struct cpufreq_affected_cpus *first = NULL;
386 struct cpufreq_affected_cpus *current = NULL; 386 struct cpufreq_affected_cpus *current = NULL;
387 char one_value[SYSFS_PATH_MAX]; 387 char one_value[SYSFS_PATH_MAX];
@@ -389,29 +389,25 @@ static struct cpufreq_affected_cpus * sysfs_get_cpu_list(unsigned int cpu,
389 unsigned int pos, i; 389 unsigned int pos, i;
390 unsigned int len; 390 unsigned int len;
391 391
392 if ( ( len = sysfs_cpufreq_read_file(cpu, file, linebuf, 392 len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf));
393 sizeof(linebuf))) == 0 ) 393 if (len == 0)
394 {
395 return NULL; 394 return NULL;
396 }
397 395
398 pos = 0; 396 pos = 0;
399 for ( i = 0; i < len; i++ ) 397 for (i = 0; i < len; i++) {
400 { 398 if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') {
401 if ( i == len || linebuf[i] == ' ' || linebuf[i] == '\n' ) 399 if (i - pos < 1)
402 {
403 if ( i - pos < 1 )
404 continue; 400 continue;
405 if ( i - pos >= SYSFS_PATH_MAX ) 401 if (i - pos >= SYSFS_PATH_MAX)
406 goto error_out; 402 goto error_out;
407 if ( current ) { 403 if (current) {
408 current->next = malloc(sizeof *current); 404 current->next = malloc(sizeof(*current));
409 if ( ! current->next ) 405 if (!current->next)
410 goto error_out; 406 goto error_out;
411 current = current->next; 407 current = current->next;
412 } else { 408 } else {
413 first = malloc(sizeof *first); 409 first = malloc(sizeof(*first));
414 if ( ! first ) 410 if (!first)
415 goto error_out; 411 goto error_out;
416 current = first; 412 current = first;
417 } 413 }
@@ -421,7 +417,7 @@ static struct cpufreq_affected_cpus * sysfs_get_cpu_list(unsigned int cpu,
421 memcpy(one_value, linebuf + pos, i - pos); 417 memcpy(one_value, linebuf + pos, i - pos);
422 one_value[i - pos] = '\0'; 418 one_value[i - pos] = '\0';
423 419
424 if ( sscanf(one_value, "%u", &current->cpu) != 1 ) 420 if (sscanf(one_value, "%u", &current->cpu) != 1)
425 goto error_out; 421 goto error_out;
426 422
427 pos = i + 1; 423 pos = i + 1;
@@ -439,15 +435,18 @@ static struct cpufreq_affected_cpus * sysfs_get_cpu_list(unsigned int cpu,
439 return NULL; 435 return NULL;
440} 436}
441 437
442struct cpufreq_affected_cpus * sysfs_get_freq_affected_cpus(unsigned int cpu) { 438struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(unsigned int cpu)
439{
443 return sysfs_get_cpu_list(cpu, "affected_cpus"); 440 return sysfs_get_cpu_list(cpu, "affected_cpus");
444} 441}
445 442
446struct cpufreq_affected_cpus * sysfs_get_freq_related_cpus(unsigned int cpu) { 443struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(unsigned int cpu)
444{
447 return sysfs_get_cpu_list(cpu, "related_cpus"); 445 return sysfs_get_cpu_list(cpu, "related_cpus");
448} 446}
449 447
450struct cpufreq_stats * sysfs_get_freq_stats(unsigned int cpu, unsigned long long *total_time) { 448struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu,
449 unsigned long long *total_time) {
451 struct cpufreq_stats *first = NULL; 450 struct cpufreq_stats *first = NULL;
452 struct cpufreq_stats *current = NULL; 451 struct cpufreq_stats *current = NULL;
453 char one_value[SYSFS_PATH_MAX]; 452 char one_value[SYSFS_PATH_MAX];
@@ -455,28 +454,27 @@ struct cpufreq_stats * sysfs_get_freq_stats(unsigned int cpu, unsigned long long
455 unsigned int pos, i; 454 unsigned int pos, i;
456 unsigned int len; 455 unsigned int len;
457 456
458 if ( ( len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state", 457 len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state",
459 linebuf, sizeof(linebuf))) == 0 ) 458 linebuf, sizeof(linebuf));
459 if (len == 0)
460 return NULL; 460 return NULL;
461 461
462 *total_time = 0; 462 *total_time = 0;
463 pos = 0; 463 pos = 0;
464 for ( i = 0; i < len; i++ ) 464 for (i = 0; i < len; i++) {
465 { 465 if (i == strlen(linebuf) || linebuf[i] == '\n') {
466 if ( i == strlen(linebuf) || linebuf[i] == '\n' ) 466 if (i - pos < 2)
467 {
468 if ( i - pos < 2 )
469 continue; 467 continue;
470 if ( (i - pos) >= SYSFS_PATH_MAX ) 468 if ((i - pos) >= SYSFS_PATH_MAX)
471 goto error_out; 469 goto error_out;
472 if ( current ) { 470 if (current) {
473 current->next = malloc(sizeof *current ); 471 current->next = malloc(sizeof(*current));
474 if ( ! current->next ) 472 if (!current->next)
475 goto error_out; 473 goto error_out;
476 current = current->next; 474 current = current->next;
477 } else { 475 } else {
478 first = malloc(sizeof *first ); 476 first = malloc(sizeof(*first));
479 if ( ! first ) 477 if (!first)
480 goto error_out; 478 goto error_out;
481 current = first; 479 current = first;
482 } 480 }
@@ -485,7 +483,9 @@ struct cpufreq_stats * sysfs_get_freq_stats(unsigned int cpu, unsigned long long
485 483
486 memcpy(one_value, linebuf + pos, i - pos); 484 memcpy(one_value, linebuf + pos, i - pos);
487 one_value[i - pos] = '\0'; 485 one_value[i - pos] = '\0';
488 if ( sscanf(one_value, "%lu %llu", &current->frequency, &current->time_in_state) != 2 ) 486 if (sscanf(one_value, "%lu %llu",
487 &current->frequency,
488 &current->time_in_state) != 2)
489 goto error_out; 489 goto error_out;
490 490
491 *total_time = *total_time + current->time_in_state; 491 *total_time = *total_time + current->time_in_state;
@@ -496,7 +496,7 @@ struct cpufreq_stats * sysfs_get_freq_stats(unsigned int cpu, unsigned long long
496 return first; 496 return first;
497 497
498 error_out: 498 error_out:
499 while ( first ) { 499 while (first) {
500 current = first->next; 500 current = first->next;
501 free(first); 501 free(first);
502 first = current; 502 first = current;
@@ -511,29 +511,29 @@ unsigned long sysfs_get_freq_transitions(unsigned int cpu)
511 511
512static int verify_gov(char *new_gov, char *passed_gov) 512static int verify_gov(char *new_gov, char *passed_gov)
513{ 513{
514 unsigned int i, j=0; 514 unsigned int i, j = 0;
515 515
516 if (!passed_gov || (strlen(passed_gov) > 19)) 516 if (!passed_gov || (strlen(passed_gov) > 19))
517 return -EINVAL; 517 return -EINVAL;
518 518
519 strncpy(new_gov, passed_gov, 20); 519 strncpy(new_gov, passed_gov, 20);
520 for (i=0;i<20;i++) { 520 for (i = 0; i < 20; i++) {
521 if (j) { 521 if (j) {
522 new_gov[i] = '\0'; 522 new_gov[i] = '\0';
523 continue; 523 continue;
524 } 524 }
525 if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z')) { 525 if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z'))
526 continue; 526 continue;
527 } 527
528 if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z')) { 528 if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z'))
529 continue; 529 continue;
530 } 530
531 if (new_gov[i] == '-') { 531 if (new_gov[i] == '-')
532 continue; 532 continue;
533 } 533
534 if (new_gov[i] == '_') { 534 if (new_gov[i] == '_')
535 continue; 535 continue;
536 } 536
537 if (new_gov[i] == '\0') { 537 if (new_gov[i] == '\0') {
538 j = 1; 538 j = 1;
539 continue; 539 continue;
@@ -627,7 +627,8 @@ int sysfs_set_freq_policy(unsigned int cpu, struct cpufreq_policy *policy)
627 gov, strlen(gov)); 627 gov, strlen(gov));
628} 628}
629 629
630int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency) { 630int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency)
631{
631 struct cpufreq_policy *pol = sysfs_get_freq_policy(cpu); 632 struct cpufreq_policy *pol = sysfs_get_freq_policy(cpu);
632 char userspace_gov[] = "userspace"; 633 char userspace_gov[] = "userspace";
633 char freq[SYSFS_PATH_MAX]; 634 char freq[SYSFS_PATH_MAX];
@@ -640,7 +641,7 @@ int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency) {
640 ret = sysfs_modify_freq_policy_governor(cpu, userspace_gov); 641 ret = sysfs_modify_freq_policy_governor(cpu, userspace_gov);
641 if (ret) { 642 if (ret) {
642 cpufreq_put_policy(pol); 643 cpufreq_put_policy(pol);
643 return (ret); 644 return ret;
644 } 645 }
645 } 646 }
646 647
@@ -662,7 +663,7 @@ int sysfs_cpu_exists(unsigned int cpu)
662 663
663 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu); 664 snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu);
664 665
665 if ( stat(file, &statbuf) != 0 ) 666 if (stat(file, &statbuf) != 0)
666 return -ENOSYS; 667 return -ENOSYS;
667 668
668 return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS; 669 return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS;