]> rtime.felk.cvut.cz Git - frescor/frsh.git/blob - frsh_api/frsh_power.c
Make the framework compilable without acpi_xxx libraries
[frescor/frsh.git] / frsh_api / frsh_power.c
1 /**
2  * @file   frsh_power.c
3  * @author Michael Trimarchi <trimarchimichael@yahoo.it>
4  *         Dario Faggioli <faggioli@gandalf.sssup.it>
5  *
6  * @brief  FRSH core thread related functions not implamented in managers..
7  *
8  *
9  */
10
11 #include <string.h>
12
13 #include <fres_contract.h>
14 #include <fres_contract_idl.h>
15 #include <fres_blocks.h>
16 #include <fcb.h>
17 #include <fra_generic.h>
18 #include <frsh_forb.h>
19 #include "frsh_resources.h"
20 #ifdef CONFIG_ACPI_CPU
21 #  include <fra_acpi_cpu.h>
22 #endif
23 #ifdef CONFIG_ACPI_LCD
24 #  include <fra_acpi_lcd.h>
25 #endif
26 #include <frsh.h>
27
28 static inline int __is_a_valid_power(level)
29 {
30         if (level >=0 && level < 3 )
31                 return 1;
32
33         return 0;
34 }
35
36 int frsh_contract_set_min_expiration(frsh_contract_t *contract,
37                                      frsh_rel_time_t min_expiration)
38 {
39         fres_block_power_management *p;
40         int ret;
41
42         if (!contract || !*contract)
43                 return FRSH_ERR_BAD_ARGUMENT;
44
45         p = fres_contract_get_power_management(*contract);
46         if (!p) {
47                 p = malloc(sizeof(*p));
48                 if (!p) return ENOMEM;
49         }
50         p->min_expiration = min_expiration;
51
52         fres_contract_del_power_management(*contract);
53         ret = fres_contract_add_power_management(*contract, p);
54         if (ret) {
55                 free(p);
56                 return errno;
57         }
58
59         return FRSH_NO_ERROR;
60 }
61
62 int frsh_contract_set_min_budget_pow
63   (frsh_contract_t *contract,
64    frsh_power_level_t power_level,
65    const frsh_rel_time_t *pow_min_budget)
66 {
67         fres_block_power_management *b;
68         int ret;
69
70         if (!contract || !*contract ||
71             !pow_min_budget)
72                 return FRSH_ERR_BAD_ARGUMENT;
73
74         b = fres_contract_get_power_management(*contract);
75         if (!b) {
76                 b = malloc(sizeof(*b));
77                 if (!b) return ENOMEM;
78         }
79         b->min_budget[power_level] = *pow_min_budget;
80
81         fres_contract_del_power_management(*contract);
82         ret = fres_contract_add_power_management(*contract, b);
83         if (ret) {
84                 free(b);
85                 return errno;
86         }
87
88         return FRSH_NO_ERROR;
89 }
90
91 int frsh_contract_get_min_budget_pow
92   (const frsh_contract_t *contract,
93    frsh_power_level_t power_level,
94    frsh_rel_time_t *pow_min_budget)
95 {
96         fres_block_power_management *b;
97
98         if (!contract || !*contract ||
99             !__is_a_valid_power(power_level))
100                 return FRSH_ERR_BAD_ARGUMENT;
101
102         b = fres_contract_get_power_management(*contract);
103         if (!b)
104                 return FRSH_ERR_BAD_ARGUMENT;
105
106         *pow_min_budget = b->min_budget[power_level];
107
108         return FRSH_NO_ERROR;
109 }
110
111 int frsh_contract_set_max_budget_pow
112   (frsh_contract_t *contract,
113    frsh_power_level_t power_level,
114    const frsh_rel_time_t *pow_max_budget)
115 {
116         fres_block_power_management *b;
117         int ret;
118
119         if (!contract || !*contract ||
120             !pow_max_budget || !__is_a_valid_power(power_level))
121                 return FRSH_ERR_BAD_ARGUMENT;
122
123         b = fres_contract_get_power_management(*contract);
124         if (!b) {
125                 b = malloc(sizeof(*b));
126                 if (!b) return ENOMEM;
127         }
128         b->max_budget[power_level] = *pow_max_budget;
129
130         fres_contract_del_power_management(*contract);
131         ret = fres_contract_add_power_management(*contract, b);
132         if (ret) {
133                 free(b);
134                 return errno;
135         }
136
137         return FRSH_NO_ERROR;
138 }
139
140 int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
141                                      frsh_power_level_t power_level,
142                                      frsh_rel_time_t *pow_max_budget)
143 {
144         fres_block_power_management *b;
145
146         if (!contract || !*contract ||
147             !__is_a_valid_power(power_level)) {
148                 return FRSH_ERR_BAD_ARGUMENT;
149         }
150
151         b = fres_contract_get_power_management(*contract);
152         if (!b)
153                 return FRSH_ERR_BAD_ARGUMENT;
154
155         *pow_max_budget = b->max_budget[power_level];
156
157         return FRSH_NO_ERROR;
158 }
159
160 int frsh_contract_set_utilization_pow
161   (frsh_contract_t *contract,
162    frsh_power_level_t power_level,
163    const frsh_rel_time_t *budget,
164    const frsh_rel_time_t *period,
165    const frsh_rel_time_t *deadline)
166 {
167         return FRSH_ERR_NOT_IMPLEMENTED;
168 }
169
170 int frsh_contract_get_utilization_pow
171   (const frsh_contract_t *contract,
172    frsh_power_level_t power_level,
173    frsh_rel_time_t *budget,
174    frsh_rel_time_t *period,
175    frsh_rel_time_t *deadline)
176 {
177         return FRSH_ERR_NOT_IMPLEMENTED;;
178 }
179
180 /* FIXME: What happens when one application set one power-level and
181  * second application different level. I think this function should
182  * not be part of API. It should be used internally (e.g. by contract
183  * broker) to achieve the requirements specified by
184  * frsh_contract_set_min_expiration() and similar functions.
185  *
186  * This implementation also skips FCB when doing changes to resources,
187  * which is certainly not good, because resource manager does not know
188  * about the change.
189  */
190 int frsh_resource_set_power_level
191   (frsh_resource_type_t resource_type,
192    frsh_resource_id_t resource_id,
193    frsh_power_level_t power_level)
194 {
195
196         switch(resource_type)
197         {
198 #ifdef CONFIG_ACPI_CPU
199                 case FRSH_RT_PROCESSOR:
200                 {
201                         int ret;
202                         ret = fra_CPU_frequency_init(resource_id);
203                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
204
205                         ret = fra_CPU_set_frequency(resource_id, power_level);
206                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
207
208                         /**
209                          * @TODO:
210                          * if (i budget sono effettivamente diversi)
211                          *      rinegozia i contratti coi nuovi valori
212                          **/
213                         break;
214                 }
215 #endif
216 #ifdef CONFIG_ACPI_LCD
217                 case FRSH_RT_LCD:
218                 {
219                         int ret;
220                         ret = fra_LCD_brightness_init(resource_id);
221                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
222
223                         ret = fra_LCD_set_brightness(resource_id, power_level);
224                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
225                         break;
226                 }
227 #endif
228                 default:
229                         return FRSH_ERR_NOT_IMPLEMENTED;
230         }
231
232         return FRSH_NO_ERROR;
233 }
234
235 int frsh_resource_get_power_level
236   (frsh_resource_type_t resource_type,
237    frsh_resource_id_t resource_id,
238    frsh_power_level_t *power_level)
239 {
240         switch(resource_type)
241         {
242 #ifdef CONFIG_ACPI_CPU
243                 case FRSH_RT_PROCESSOR:
244                 {
245                         int ret;
246                         ret = fra_CPU_get_level(resource_id,
247                                                 (int*) power_level);
248                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
249
250                         break;
251                 }
252 #endif
253 #ifdef CONFIG_ACPI_LCD
254                 case FRSH_RT_LCD:
255                 {
256                         int ret;
257                         ret = fra_LCD_get_level(resource_id,
258                                                 (int*) power_level);
259                         if (ret) return FRSH_ERR_INTERNAL_ERROR;
260
261                         break;
262                 }
263 #endif
264                 default:
265                         return FRSH_ERR_NOT_IMPLEMENTED;
266         }
267
268         return FRSH_NO_ERROR;
269 }
270
271 int frsh_resource_get_num_power_levels
272   (frsh_resource_type_t resource_type,
273    frsh_resource_id_t resource_id,
274    frsh_power_level_t *num_power_levels)
275 {
276         /**
277          * @FIXME:
278          *   This looks tremendous... But the number '3' is hardcoded
279          *   whereever in the headers as the number of power level, so...
280          */
281         *num_power_levels = 3;
282
283         return FRSH_NO_ERROR;
284 }
285
286 int frsh_battery_get_expiration(frsh_abs_time_t *expiration)
287 {
288 #ifdef CONFIG_ACPI_CPU
289         frsh_rel_time_t interval;
290         int ret;
291
292         ret = fra_CPU_battery_expiration(&interval);
293         if (ret) return FRSH_ERR_INTERNAL_ERROR;
294
295         fosa_clock_get_time(FOSA_CLOCK_REALTIME, expiration);
296         *expiration = fosa_abs_time_incr(*expiration, interval);
297
298         return FRSH_NO_ERROR;
299 #else
300         return FRSH_ERR_NOT_IMPLEMENTED;        
301 #endif
302 }
303