pass-hal: standard: Add implementation for get_available_min/max_freq() 44/143144/7
authorDongwoo Lee <dwoo08.lee@samsung.com>
Mon, 7 Aug 2017 06:55:32 +0000 (15:55 +0900)
committerDongwoo Lee <dwoo08.lee@samsung.com>
Tue, 15 Aug 2017 23:52:48 +0000 (23:52 +0000)
The new functions for getting available minimum/maximum frequency
is added to dvfs callback. For cpu it can be done by accessing cpuinfo
node, but devfreq has no sysfs node which has available max, so the
value is retrieved from the available frequency lists.

Change-Id: I4b09149d3d434837462e412412eb022489ab96b3
Signed-off-by: Dongwoo Lee <dwoo08.lee@samsung.com>
src/bus/bus.c
src/cpu/cpu.c

index 5dff2f3..cd066f0 100644 (file)
@@ -33,6 +33,7 @@
 #define DEVFREQ_BUS_CURR_FREQ_PATH_SUFFIX      "/cur_freq"
 #define DEVFREQ_BUS_MIN_FREQ_PATH_SUFFIX       "/min_freq"
 #define DEVFREQ_BUS_MAX_FREQ_PATH_SUFFIX       "/max_freq"
+#define DEVFREQ_BUS_AVAILABLE_FREQ_PATH_SUFFIX "/available_frequencies"
 
 static int standard_dvfs_get_curr_governor(char *res_name, char *governor)
 {
@@ -173,6 +174,64 @@ static int standard_dvfs_set_max_freq(char *res_name, int freq)
        return 0;
 }
 
+static int standard_dvfs_get_available_min_freq(char *res_name)
+{
+       char path[PATH_MAX];
+       char buf[MAX_BUF_SIZE];
+       char *p;
+       int ret;
+
+       if (!res_name)
+               return -EINVAL;
+
+       snprintf(path, PATH_MAX, "%s%s%s",
+               DEVFREQ_BUS_PATH_PREFIX,
+               res_name,
+               DEVFREQ_BUS_AVAILABLE_FREQ_PATH_SUFFIX);
+
+       ret = sysfs_read_str(path, buf, MAX_BUF_SIZE);
+       if (ret < 0)
+               return ret;
+
+       p = strchr(buf, ' ');
+       if (p)
+               *p = '\0';
+
+       ret = strtoul(buf, NULL, 10);
+       if (!ret)
+               return -EINVAL;
+
+       return ret;
+}
+
+static int standard_dvfs_get_available_max_freq(char *res_name)
+{
+       char path[PATH_MAX];
+       char buf[MAX_BUF_SIZE];
+       char *p;
+       int ret;
+
+       if (!res_name)
+               return -EINVAL;
+
+       snprintf(path, PATH_MAX, "%s%s%s",
+               DEVFREQ_BUS_PATH_PREFIX,
+               res_name,
+               DEVFREQ_BUS_AVAILABLE_FREQ_PATH_SUFFIX);
+
+       ret = sysfs_read_str(path, buf, MAX_BUF_SIZE);
+       if (ret < 0)
+               return ret;
+
+       p = strrchr(buf, ' ');
+       p = p ? p + 1 : buf;
+
+       ret = strtoul(p, NULL, 10);
+       if (!ret)
+               return -EINVAL;
+
+       return ret;
+}
 
 static struct pass_resource_dvfs_ops standard_bus_dvfs_ops =  {
        .get_curr_governor = standard_dvfs_get_curr_governor,
@@ -182,6 +241,8 @@ static struct pass_resource_dvfs_ops standard_bus_dvfs_ops =  {
        .set_min_freq = standard_dvfs_set_min_freq,
        .get_max_freq = standard_dvfs_get_max_freq,
        .set_max_freq = standard_dvfs_set_max_freq,
+       .get_available_min_freq = standard_dvfs_get_available_min_freq,
+       .get_available_max_freq = standard_dvfs_get_available_max_freq,
 };
 
 static int standard_bus_open(char *res_name, struct pass_resource_info *info,
index a38277a..7fb3c2c 100644 (file)
@@ -37,6 +37,8 @@
  * and scaling_cur_freq is the CPU frequency set by the CPUFREQ policy.
  */
 #define CPUFREQ_CURR_FREQ_PATH_SUFFIX          "/cpufreq/cpuinfo_cur_freq"
+#define CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_min_freq"
+#define CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX "/cpufreq/cpuinfo_max_freq"
 #define CPUFREQ_MIN_FREQ_PATH_SUFFIX           "/cpufreq/scaling_min_freq"
 #define CPUFREQ_MAX_FREQ_PATH_SUFFIX           "/cpufreq/scaling_max_freq"
 #define CPUFREQ_UP_THRESHOLD_PATH_SUFFIX       "/cpufreq/ondemand/up_threshold"
@@ -189,6 +191,47 @@ static int standard_dvfs_set_max_freq(char *res_name, int freq)
        return 0;
 }
 
+static int standard_dvfs_get_available_min_freq(char *res_name)
+{
+       char path[PATH_MAX];
+       int val, ret;
+
+       if (!res_name)
+               return -EINVAL;
+
+       snprintf(path, PATH_MAX, "%s%s%s",
+               CPUFREQ_PATH_PREFIX,
+               res_name,
+               CPUFREQ_AVAILABLE_MIN_FREQ_PATH_SUFFIX);
+
+       ret = sysfs_read_int(path, &val);
+       if (ret < 0)
+               return ret;
+
+       return val;
+}
+
+
+static int standard_dvfs_get_available_max_freq(char *res_name)
+{
+       char path[PATH_MAX];
+       int val, ret;
+
+       if (!res_name)
+               return -EINVAL;
+
+       snprintf(path, PATH_MAX, "%s%s%s",
+               CPUFREQ_PATH_PREFIX,
+               res_name,
+               CPUFREQ_AVAILABLE_MAX_FREQ_PATH_SUFFIX);
+
+       ret = sysfs_read_int(path, &val);
+       if (ret < 0)
+               return ret;
+
+       return val;
+}
+
 static int standard_dvfs_get_up_threshold(char *res_name)
 {
        char path[PATH_MAX];
@@ -237,6 +280,8 @@ static struct pass_resource_dvfs_ops standard_cpu_dvfs_ops =  {
        .set_min_freq = standard_dvfs_set_min_freq,
        .get_max_freq = standard_dvfs_get_max_freq,
        .set_max_freq = standard_dvfs_set_max_freq,
+       .get_available_min_freq = standard_dvfs_get_available_min_freq,
+       .get_available_max_freq = standard_dvfs_get_available_max_freq,
        .get_up_threshold = standard_dvfs_get_up_threshold,
        .set_up_threshold = standard_dvfs_set_up_threshold,
 };