3 * @author Michael Trimarchi <trimarchimichael@yahoo.it>
4 * Dario Faggioli <faggioli@gandalf.sssup.it>
6 * @brief FRSH core thread related functions not implamented in managers..
13 #include <fres_contract.h>
14 #include <fres_contract_idl.h>
15 #include <fres_blocks.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>
23 #ifdef CONFIG_ACPI_BATTERY
24 # include "fra_acpi_battery.h"
26 #ifdef CONFIG_ACPI_LCD
27 # include <fra_acpi_lcd.h>
31 static inline int __is_a_valid_power(int level)
33 if (level >= 0 && level < 3 )
40 fres_block_power_management *__dup_power_management(frsh_contract_t *contract)
42 fres_block_power_management *p, *old_p;
44 old_p = fres_contract_get_power_management(*contract);
45 p = malloc(sizeof(*p));
48 * Needed since frsh_contract_del_xxx frees the
52 memcpy(p, old_p, sizeof(*old_p));
59 int frsh_contract_set_min_expiration(frsh_contract_t *contract,
60 frsh_rel_time_t min_expiration)
62 fres_block_power_management *p;
65 if (!contract || !*contract)
66 return FRSH_ERR_BAD_ARGUMENT;
68 p = __dup_power_management(contract);
72 p->min_expiration = min_expiration;
74 fres_contract_del_power_management(*contract);
75 ret = fres_contract_add_power_management(*contract, p);
84 int frsh_contract_get_min_expiration(const frsh_contract_t *contract,
85 frsh_rel_time_t *min_expiration)
87 fres_block_power_management *p;
89 if (!contract || !*contract)
90 return FRSH_ERR_BAD_ARGUMENT;
92 p = fres_contract_get_power_management(*contract);
94 return FRSH_ERR_BAD_ARGUMENT;
96 *min_expiration = p->min_expiration;
101 int frsh_contract_set_min_budget_pow
102 (frsh_contract_t *contract,
103 frsh_power_level_t power_level,
104 const frsh_rel_time_t *pow_min_budget)
106 fres_block_power_management *b;
109 if (!contract || !*contract ||
111 return FRSH_ERR_BAD_ARGUMENT;
113 b = __dup_power_management(contract);
117 b->min_budget[power_level] = *pow_min_budget;
119 fres_contract_del_power_management(*contract);
120 ret = fres_contract_add_power_management(*contract, b);
126 return FRSH_NO_ERROR;
129 int frsh_contract_get_min_budget_pow
130 (const frsh_contract_t *contract,
131 frsh_power_level_t power_level,
132 frsh_rel_time_t *pow_min_budget)
134 fres_block_power_management *b;
136 if (!contract || !*contract ||
137 !__is_a_valid_power(power_level))
138 return FRSH_ERR_BAD_ARGUMENT;
140 b = fres_contract_get_power_management(*contract);
142 return FRSH_ERR_BAD_ARGUMENT;
144 *pow_min_budget = b->min_budget[power_level];
146 return FRSH_NO_ERROR;
149 int frsh_contract_set_max_budget_pow
150 (frsh_contract_t *contract,
151 frsh_power_level_t power_level,
152 const frsh_rel_time_t *pow_max_budget)
154 fres_block_power_management *b;
157 if (!contract || !*contract ||
158 !pow_max_budget || !__is_a_valid_power(power_level))
159 return FRSH_ERR_BAD_ARGUMENT;
161 b = __dup_power_management(contract);
165 b->max_budget[power_level] = *pow_max_budget;
167 fres_contract_del_power_management(*contract);
168 ret = fres_contract_add_power_management(*contract, b);
174 return FRSH_NO_ERROR;
177 int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
178 frsh_power_level_t power_level,
179 frsh_rel_time_t *pow_max_budget)
181 fres_block_power_management *b;
183 if (!contract || !*contract ||
184 !__is_a_valid_power(power_level)) {
185 return FRSH_ERR_BAD_ARGUMENT;
188 b = fres_contract_get_power_management(*contract);
190 return FRSH_ERR_BAD_ARGUMENT;
192 *pow_max_budget = b->max_budget[power_level];
194 return FRSH_NO_ERROR;
197 int frsh_contract_set_utilization_pow
198 (frsh_contract_t *contract,
199 frsh_power_level_t power_level,
200 const frsh_rel_time_t *budget,
201 const frsh_rel_time_t *period,
202 const frsh_rel_time_t *deadline)
204 return FRSH_ERR_NOT_IMPLEMENTED;
207 int frsh_contract_get_utilization_pow
208 (const frsh_contract_t *contract,
209 frsh_power_level_t power_level,
210 frsh_rel_time_t *budget,
211 frsh_rel_time_t *period,
212 frsh_rel_time_t *deadline)
214 return FRSH_ERR_NOT_IMPLEMENTED;;
217 /* FIXME: What happens when one application set one power-level and
218 * second application different level. I think this function should
219 * not be part of API. It should be used internally (e.g. by contract
220 * broker) to achieve the requirements specified by
221 * frsh_contract_set_min_expiration() and similar functions.
223 * This implementation also skips FCB when doing changes to resources,
224 * which is certainly not good, because resource manager does not know
227 int frsh_resource_set_power_level
228 (frsh_resource_type_t resource_type,
229 frsh_resource_id_t resource_id,
230 frsh_power_level_t power_level)
233 if (!__is_a_valid_power(power_level))
234 return FRSH_ERR_BAD_ARGUMENT;
236 switch(resource_type)
238 #ifdef CONFIG_ACPI_CPU
239 case FRSH_RT_PROCESSOR:
243 ret = fra_CPU_power_init(resource_id);
244 if (ret) return FRSH_ERR_INTERNAL_ERROR;
245 ret = fra_CPU_set_power(resource_id, power_level);
246 if (ret) return FRSH_ERR_INTERNAL_ERROR;
250 * if (i budget sono effettivamente diversi)
251 * rinegozia i contratti coi nuovi valori
256 #ifdef CONFIG_ACPI_LCD
261 ret = fra_LCD_power_init(resource_id);
262 if (ret) return FRSH_ERR_INTERNAL_ERROR;
263 ret = fra_LCD_set_power(resource_id, power_level);
264 if (ret) return FRSH_ERR_INTERNAL_ERROR;
269 return FRSH_ERR_NOT_IMPLEMENTED;
272 return FRSH_NO_ERROR;
275 int frsh_resource_get_power_level
276 (frsh_resource_type_t resource_type,
277 frsh_resource_id_t resource_id,
278 frsh_power_level_t *power_level)
280 switch(resource_type)
282 #ifdef CONFIG_ACPI_CPU
283 case FRSH_RT_PROCESSOR:
287 ret = fra_CPU_power_init(resource_id);
288 if (ret) return FRSH_ERR_INTERNAL_ERROR;
289 ret = fra_CPU_get_power(resource_id,
291 if (ret) return FRSH_ERR_INTERNAL_ERROR;
296 #ifdef CONFIG_ACPI_LCD
301 ret = fra_LCD_power_init(resource_id);
302 if (ret) return FRSH_ERR_INTERNAL_ERROR;
303 ret = fra_LCD_get_power(resource_id,
305 if (ret) return FRSH_ERR_INTERNAL_ERROR;
311 return FRSH_ERR_NOT_IMPLEMENTED;
314 return FRSH_NO_ERROR;
317 int frsh_resource_get_speed
318 (frsh_resource_type_t resource_type,
319 frsh_resource_id_t resource_id,
320 frsh_power_level_t power_level,
323 switch(resource_type)
325 #ifdef CONFIG_ACPI_CPU
326 case FRSH_RT_PROCESSOR:
330 ret = fra_CPU_power_init(resource_id);
331 if (ret) return FRSH_ERR_INTERNAL_ERROR;
332 ret = fra_CPU_get_speed(resource_id,
335 if (ret) return FRSH_ERR_INTERNAL_ERROR;
340 #ifdef CONFIG_ACPI_LCD
345 ret = fra_LCD_power_init(resource_id);
346 if (ret) return FRSH_ERR_INTERNAL_ERROR;
347 ret = fra_LCD_get_speed(resource_id,
350 if (ret) return FRSH_ERR_INTERNAL_ERROR;
356 return FRSH_ERR_NOT_IMPLEMENTED;
359 return FRSH_NO_ERROR;
362 int frsh_resource_get_num_power_levels
363 (frsh_resource_type_t resource_type,
364 frsh_resource_id_t resource_id,
365 int *num_power_levels)
369 *num_power_levels = 1;
371 switch(resource_type)
373 #ifdef CONFIG_ACPI_CPU
374 case FRSH_RT_PROCESSOR:
376 ret = fra_CPU_power_init(resource_id);
381 #ifdef CONFIG_ACPI_LCD
384 ret = fra_LCD_power_init(resource_id);
391 return FRSH_ERR_NOT_IMPLEMENTED;
396 * This looks tremendous... But the number '3' is hardcoded
397 * whereever in the headers as the number of power level, so...
399 *num_power_levels = 3;
402 return FRSH_NO_ERROR;
405 int frsh_battery_get_expiration(frsh_abs_time_t *expiration)
407 #ifdef CONFIG_ACPI_BATTERY
408 frsh_rel_time_t interval;
411 ret = fra_battery_init();
412 if (ret) return FRSH_ERR_INTERNAL_ERROR;
414 ret = fra_battery_expiration(&interval);
415 if (ret == EAGAIN) return ret;
416 if (ret) return FRSH_ERR_INTERNAL_ERROR;
418 fosa_clock_get_time(FOSA_CLOCK_REALTIME, expiration);
419 *expiration = fosa_abs_time_incr(*expiration, interval);
421 return FRSH_NO_ERROR;
423 return FRSH_ERR_NOT_IMPLEMENTED;