]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - resources/acpi_cpu/fra_acpi_cpu.c
Small fixes and added errorchecking in energy management functions.
[frescor/frsh.git] / resources / acpi_cpu / fra_acpi_cpu.c
1 /**
2  * @file   fres_acpi_cpu.c
3  * @author Dario Faggioli <faggioli@gandalf.sssup.it>
4  *         Michael Trimarchi <trimarchimichael@yahoo.it>
5  * 
6  * @brief  Implementation of shared CPU related ACPI functions.
7  * 
8  */
9
10 #include "fra_acpi_cpu.h"
11
12 static int frequency_initialized = 0;
13
14 static unsigned long freqs[3];
15
16 int fra_CPU_power_init(int cpu)
17 {
18         int ret;
19         int i, j, freq_num = 0;
20         struct cpufreq_available_governors *governors, *g;
21         struct cpufreq_available_frequencies *frequencies, *f;
22
23         if (frequency_initialized == 1) return 0;
24
25         ret = cpufreq_cpu_exists(cpu);
26         if (ret) return EINVAL;
27
28         governors = cpufreq_get_available_governors(cpu);
29         if (!governors) return EINVAL;
30         for (g = governors; g != NULL; g = g->next)
31                 if (strncmp("userspace", g->governor, sizeof(*g->governor)) == 0)
32                         break;
33         cpufreq_put_available_governors(governors);
34
35         if (g == NULL) return EINVAL;
36
37         ret = cpufreq_modify_policy_governor(cpu, "userspace");
38         if (ret) return EPERM;
39
40
41         frequencies = cpufreq_get_available_frequencies(cpu);
42         if (!frequencies) return EINVAL;
43         for (f = frequencies; f; f = f->next, freq_num++)
44                 ;
45
46         f = frequencies;
47         i = j = 0;
48         while (f) {
49                 if (i == 0 ||
50                     i == ((int)ceil((double)freq_num / 2.0f)) ||
51                     i == freq_num - 1) {
52                         freqs[j] = f->frequency;
53                         j++;
54                 }
55                 i++;
56                 f = f->next;
57         }
58         cpufreq_put_available_frequencies(frequencies);
59
60         frequency_initialized = 1;
61
62         return 0;
63 }
64
65 int fra_CPU_get_power(int cpu, int *level)
66 {
67         unsigned long freq;
68         int i;
69
70         if (!frequency_initialized) return EINVAL;
71
72         freq = cpufreq_get(cpu);
73         for (i = 0; i < 3; i++)
74                 if (freqs[i] == freq) {
75                         *level = i;
76                         return 0;
77                 }
78
79         return EINVAL;
80 }
81
82 int fra_CPU_set_power(int cpu, int level)
83 {
84         if (!frequency_initialized || level >= 3)
85                 return EINVAL;
86
87         return cpufreq_set_frequency(cpu, freqs[level]);
88 }
89
90 int fra_CPU_get_speed(int cpu, int level, double *ratio)
91 {
92         if (!frequency_initialized || level >= 3)
93                 return EINVAL;
94
95         *ratio = (double) freqs[level] / freqs[0];
96
97         return 0;
98 }
99