--- /dev/null
+/**
+ * @file fres_acpi_cpu.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * Michael Trimarchi <trimarchimichael@yahoo.it>
+ *
+ * @brief Implementation of shared CPU related ACPI functions.
+ *
+ */
+
+#include "fra_acpi_cpu.h"
+
+static global_t acpi_globals;
+
+static int which_batt;
+static battery_t *battery;
+
+static unsigned long freqs[3];
+
+static int battery_initialized = 0;
+static int frequency_initialized = 0;
+
+int fra_CPU_battery_init(int batt)
+{
+ if (battery_initialized == 1)
+ return 0;
+
+ if (init_acpi_batt(&acpi_globals) != SUCCESS ||
+ init_acpi_acadapt(&acpi_globals) != SUCCESS)
+ return EINVAL;
+
+ if (batt >= acpi_globals.batt_count)
+ return EINVAL;
+
+ battery_initialized = 1;
+
+ which_batt = batt;
+ battery = &batteries[which_batt];
+
+ return 0;
+}
+
+int fra_CPU_battery_expiration(fosa_abs_time_t *expiration)
+{
+ int ret;
+ long remng_msec;
+
+ if (!battery_initialized)
+ return EINVAL;
+
+ read_acpi_acstate(&acpi_globals);
+ if (acpi_globals.adapt.ac_state != P_BATT)
+ return EINVAL;
+
+
+ ret = read_acpi_batt(which_batt);
+ if (ret != SUCCESS || battery->present == 0)
+ return EINVAL;
+
+ fosa_clock_get_time(FOSA_CLOCK_REALTIME, expiration);
+ remng_msec = (long) battery->remaining_time * 60000L;
+ *expiration = fosa_abs_time_incr(*expiration,
+ fosa_msec_to_rel_time(remng_msec));
+
+ return 0;
+}
+
+int fra_CPU_frequency_init(int cpu)
+{
+ int ret, found = 0;
+ int i, j, freq_num = 0;
+ struct cpufreq_available_governors *governors, *g;
+ struct cpufreq_available_frequencies *frequencies, *f;
+
+ if (frequency_initialized == 1)
+ return 0;
+
+ ret = cpufreq_cpu_exists(cpu);
+ if (ret)
+ return EINVAL;
+
+ governors = g = cpufreq_get_available_governors(cpu);
+ while (g) {
+ if (strncmp("userspace", g->governor, sizeof(*g->governor)))
+ found = 1;
+ }
+ cpufreq_put_available_governors(governors);
+ if (!found)
+ return EINVAL;
+
+ ret = cpufreq_modify_policy_governor(cpu, "userspace");
+ if (ret)
+ return EPERM;
+
+ frequency_initialized = 1;
+
+ frequencies = f = cpufreq_get_available_frequencies(cpu);
+ while (f)
+ freq_num += 1;
+
+ f = frequencies;
+ i = j = 0;
+ while (f) {
+ if (i == 0 ||
+ i == ((int)ceil((double)freq_num / 2.0f)) ||
+ i == freq_num - 1) {
+ freqs[j] = f->frequency;
+ j++;
+ }
+ i++;
+ }
+ cpufreq_put_available_frequencies(frequencies);
+
+ return 0;
+}
+
+int fra_CPU_get_frequency(int cpu, int level, unsigned long *freq)
+{
+ if (!frequency_initialized)
+ return EINVAL;
+
+ if (level >= 3)
+ return EINVAL;
+
+ *freq = freqs[level];
+
+ return 0;
+}
+
+int fra_CPU_set_frequency(int cpu, int level)
+{
+ if (!frequency_initialized)
+ return EINVAL;
+
+ if (level >= 3)
+ return EINVAL;
+
+ return cpufreq_set_frequency(cpu, freqs[level]);
+}
+
+int fra_CPU_get_level(int cpu, int *level)
+{
+ unsigned long freq;
+ int i;
+
+ if (!frequency_initialized)
+ return EINVAL;
+
+ freq = cpufreq_get(cpu);
+ for (i = 0; i < 3; i++)
+ if (freqs[i] == freq) {
+ *level = i;
+ return 0;
+ }
+
+ return EINVAL;
+}
+