]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
ACPI CPU related functions.
authorDario <dario@dario-desktop.(none)>
Wed, 29 Apr 2009 16:35:49 +0000 (18:35 +0200)
committerDario <dario@dario-desktop.(none)>
Wed, 29 Apr 2009 16:35:49 +0000 (18:35 +0200)
This commit adds the basic ACPI functions for get/set
system battery status and CPU frequency.

resources/acpi_cpu/Makefile [new file with mode: 0644]
resources/acpi_cpu/Makefile.omk [new file with mode: 0644]
resources/acpi_cpu/fra_acpi_cpu.c [new file with mode: 0644]
resources/acpi_cpu/fra_acpi_cpu.h [new file with mode: 0644]

diff --git a/resources/acpi_cpu/Makefile b/resources/acpi_cpu/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/resources/acpi_cpu/Makefile.omk b/resources/acpi_cpu/Makefile.omk
new file mode 100644 (file)
index 0000000..2e25bfb
--- /dev/null
@@ -0,0 +1,9 @@
+shared_LIBRARIES = acpi_cpu
+
+acpi_cpu_SOURCES = fra_acpi_cpu.c
+acpi_cpu_LIBS += fosa rt m acpi cpufreq
+
+include_HEADERS = fra_acpi_cpu.h
+
+
+#SUBDIRS=
diff --git a/resources/acpi_cpu/fra_acpi_cpu.c b/resources/acpi_cpu/fra_acpi_cpu.c
new file mode 100644 (file)
index 0000000..b8ff545
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * @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;
+}
+
diff --git a/resources/acpi_cpu/fra_acpi_cpu.h b/resources/acpi_cpu/fra_acpi_cpu.h
new file mode 100644 (file)
index 0000000..cbc3e2f
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef ACPI_CPU
+#define ACPI_CPU
+
+#include <string.h>
+#include <math.h>
+#include <libacpi.h>
+#include <cpufreq.h>
+
+#include <fosa_clocks_and_timers.h>
+#include <fosa.h>
+
+int fra_CPU_battery_init(int batt);
+
+int fra_CPU_battery_expiration(fosa_abs_time_t *expiration);
+
+int fra_CPU_frequency_init(int cpu);
+
+int fra_CPU_get_frequency(int cpu, int level, unsigned long *freq);
+
+int fra_CPU_set_frequency(int cpu, int level);
+
+int fra_CPU_get_level(int cpu, int *level);
+
+#endif