pass: Rename governor module to pass-gov and add governor helper functions
authorChanwoo Choi <cw00.choi@samsung.com>
Thu, 2 Feb 2017 01:33:56 +0000 (10:33 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Thu, 2 Feb 2017 23:43:19 +0000 (08:43 +0900)
This patch renames the governor module's filename from pass-core.c
to pass-gov.c beceause pass-core.c includes the governor functions.

And it adds new following governor functions. On previous, other module
,such as pass.c, access the field of struct pass_governor direclty without
any wrapper function.
- int pass_governor_init(struct pass_policy *);
- int pass_governor_exit(struct pass_policy *);
- int pass_governor_update(struct pass_policy *, enum pass_gov_state);

Change-Id: I772edc602325409faf0b747cc741be5d83151c23
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
CMakeLists.txt
src/pass/pass-core.c [deleted file]
src/pass/pass-core.h [deleted file]
src/pass/pass-gov.c [new file with mode: 0644]
src/pass/pass-gov.h
src/pass/pass-pmqos.c
src/pass/pass.c

index 1cb331b19f1850e288eb953e2f5882eeace76ee9..9f1ac387a666806905e8614a3554496485922a3e 100644 (file)
@@ -62,7 +62,7 @@ SET(VERSION 0.1.0)
 
 SET(SRCS
        src/pass/pass.c
-       src/pass/pass-core.c
+       src/pass/pass-gov.c
        src/pass/pass-gov-radiation.c
        src/pass/pass-gov-step.c
        src/pass/pass-parser.c
diff --git a/src/pass/pass-core.c b/src/pass/pass-core.c
deleted file mode 100644 (file)
index f420b3b..0000000
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * PASS (Power Aware System Service)
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "pass.h"
-#include "pass-gov.h"
-#include "pass-pmqos.h"
-#include "pass-hal.h"
-
-#include "core/device-notifier.h"
-#include "core/config-parser.h"
-
-#define PASS_CPU_STATS_MAX_COUNT       20
-
-/*
- * FIXME: Current notifier of PASS didn't pass separate user_data parameter
- * on callback function. So, PASS must need global pass_policy instance. This
- * code must be modified after changing PASS's notifier feature.
- */
-static struct pass_policy *policy_pmqos[PASS_RESOURCE_MAX];
-static int num_policy_pmqos = 0;
-
-/*
- * is_enabled - Check the state of PASS governor
- * @policy: instance of pass_policy structure
- *
- * Return true if the state of PASS is PASS_GOV_START
- * Return false if the state of PASS is PASS_GOV_STOP
- */
-static bool is_enabled(struct pass_policy *policy)
-{
-       if (!policy)
-               return false;
-
-       if (policy->gov_state != PASS_GOV_START)
-               return false;
-
-       return true;
-}
-
-/*
- * pass_notifier_booting_done - Callback function of DEVICE_NOTIFIER_BOOTING_
- *                              DONE notifier
- * @data: NULL, this parameter isn't used
- */
-static int pass_notifier_booting_done(void *data)
-{
-       int i;
-
-       if (num_policy_pmqos == 0)
-               return 0;
-
-       /* Start PASS governor if 'pass_support' in pass.conf is true */
-       for (i = 0; i < num_policy_pmqos; i++) {
-               if (policy_pmqos[i]->state == PASS_ON
-                       && policy_pmqos[i]->governor != NULL) {
-                       policy_pmqos[i]->governor->update(policy_pmqos[i],
-                                                       PASS_GOV_START);
-               }
-       }
-
-       return 0;
-}
-
-static int pass_notifier_pmqos(void *data)
-{
-       int i;
-
-       if (num_policy_pmqos == 0)
-               return 0;
-
-       for (i = 0; i < num_policy_pmqos; i++) {
-               if (policy_pmqos[i]->state == PASS_ON
-                       && policy_pmqos[i]->governor != NULL) {
-                       pass_notifier_pmqos_func(policy_pmqos[i], data);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * pass_notifier_init - Register notifiers and init
- * @policy: the instance of pass_policy structure
- */
-static int pass_notifier_init(struct pass_policy *policy)
-{
-       /* Register DEVICE_NOTIFIER_PMQOS */
-       register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
-
-       /* Register DEVICE_NOTIFIER_BOOTING_DONE */
-       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
-                         pass_notifier_booting_done);
-
-       /*
-        * FIXME: Current notifier of PASS didn't pass separate user_data
-        * parameter on callback function. So, PASS must need global pass_policy
-        * instance. This code must be modified after changing PASS's
-        * notifier feature.
-        */
-       policy_pmqos[num_policy_pmqos++] = policy;
-
-       return 0;
-}
-
-/*
- * pass_notifier_exit - Un-register notifiers and exit
- * @policy: the instance of pass_policy structure
- */
-static int pass_notifier_exit(struct pass_policy *policy)
-{
-       /* Un-register DEVICE_NOTIFIER_PMQOS */
-       unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
-
-       /* Un-Register DEVICE_NOTIFIER_BOOTING_DONE */
-       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
-                           pass_notifier_booting_done);
-
-       return 0;
-}
-
-/*****************************************************************************
- *                            PASS CPU Hotplug                               *
- ****************************************************************************/
-
-/*
- * pass_hotplug_set_online - Change the maximum number of online cpu
- *
- * @policy: the instance of struct pass_policy
- * @max_online: the maximum number of online cpu
- */
-static void pass_hotplug_set_online(struct pass_policy *policy,
-                                       unsigned int online)
-{
-       struct pass_resource *pass_res = to_pass_resource(policy);
-       struct pass_hotplug *hotplug = policy->hotplug;
-       int i;
-
-       if (!hotplug || online == hotplug->online)
-               return;
-
-       if (online > hotplug->max_online)
-               online = hotplug->max_online;
-
-       for (i = 0 ; i < policy->cpufreq.num_nr_cpus; i++) {
-               if (i < online) {
-                       pass_set_online_state(pass_res, hotplug->sequence[i],
-                                               PASS_CPU_UP);
-               } else {
-                       pass_set_online_state(pass_res, hotplug->sequence[i],
-                                               PASS_CPU_DOWN);
-               }
-       }
-
-       /*
-       _I("- CPU %4s '%d->%d'Core\n",
-               (hotplug->online > online ? "DOWN" : "UP"),
-               hotplug->online, online);
-       */
-
-       hotplug->online = online;
-}
-
-/*
- * pass_hotplug_stop - Stop PASS hotplug
- *
- * @policy: the instance of struct pass_policy
- */
-static void pass_hotplug_stop(struct pass_policy *policy)
-{
-       struct pass_table *table = policy->pass_table;
-       int level = policy->max_level;
-
-       if (!policy->hotplug)
-               return;
-
-       policy->hotplug->online = table[level].limit_max_cpu;
-       policy->hotplug->max_online = policy->cpufreq.num_nr_cpus;
-}
-
-static int pass_hotplug_dummy_governor(struct pass_policy *policy)
-{
-       int level = policy->curr_level;
-
-       return policy->pass_table[level].limit_max_cpu;
-}
-
-/*
- * pass_get_governor - Return specific hotplug instance according to type
- *
- * @type: the type of PASS hotplug
- */
-struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
-                                       enum pass_gov_type type)
-{
-       struct pass_hotplug *hotplug;
-
-       switch (type) {
-       case PASS_GOV_STEP:
-       case PASS_GOV_RADIATION:
-               hotplug = calloc(1, sizeof(struct pass_hotplug));
-               if (!hotplug) {
-                       _E("cannot allocate the memory of struct pass_hotplug");
-                       return NULL;
-               }
-               hotplug->governor = pass_hotplug_dummy_governor;
-               return hotplug;
-       default:
-               _E("Unknown hotplug type");
-               break;
-       };
-
-       return NULL;
-}
-
-/*****************************************************************************
- *                              PASS governor                                *
- ****************************************************************************/
-
-/*
- * pass_governor_change_level - Change maximum cpu frequency and number of online cpu
- *
- * @policy: the instance of struct pass_policy
- * @level: the pass level
- */
-static int pass_governor_change_level(struct pass_policy *policy, int new_level)
-{
-       struct pass_resource *pass_res = to_pass_resource(policy);
-       struct pass_conf_data *cdata = &pass_res->cdata;
-       struct pass_table *table = policy->pass_table;
-       struct pass_hotplug *hotplug = policy->hotplug;
-       int curr_level = policy->curr_level;
-       int limit_max_freq;
-       int limit_max_cpu;
-       int online;
-       int ret;
-
-       if (new_level > policy->max_level)
-               new_level = policy->max_level;
-
-       if (new_level < policy->min_level)
-               new_level = policy->min_level;
-
-       if (new_level == curr_level)
-               return 0;
-
-       /*
-        * Get maximum CPU frequency/the maximum number of online CPU
-        * according to PASS level.
-        */
-       limit_max_freq = table[new_level].limit_max_freq;
-       limit_max_cpu = table[new_level].limit_max_cpu;
-
-       policy->prev_level = policy->curr_level;
-       policy->curr_level = new_level;
-
-       /* Turn on/off CPUs according the maximum number of online CPU */
-       if (hotplug) {
-               if (hotplug->max_online != limit_max_cpu)
-                       hotplug->max_online = limit_max_cpu;
-
-               if (hotplug->governor)
-                       online = hotplug->governor(policy);
-               else
-                       online = 1;
-
-               pass_hotplug_set_online(policy, online);
-       }
-
-       /* Set maximum CPU frequency */
-       ret = pass_set_max_freq(pass_res, limit_max_freq);
-       if (ret < 0) {
-               _E("cannot set the maximum frequency of %s", cdata->res_name);
-               return -EINVAL;
-       }
-
-       /*
-       _I("[PASS %s] Level %4s '%d->%d' : '%d'Hz/'%d'Core\n",
-               pass_res->cdata.res_name,
-               (curr_level > new_level ? "DOWN" : "UP"),
-               curr_level, new_level, limit_max_freq, limit_max_cpu);
-       */
-
-       return 0;
-};
-
-/*
- * pass_calculate_busy_cpu - Count a number of busy cpu among NR_CPUS by using
- *                          runnable_avg_sum/runnable_avg_period
- *
- * @policy: the instance of struct pass_policy
- */
-static void pass_calculate_busy_cpu(struct pass_policy *policy)
-{
-       struct pass_cpu_stats *stats = policy->pass_cpu_stats;
-       struct pass_table *table = policy->pass_table;
-       unsigned int level = policy->curr_level;
-       unsigned int cpu_threshold = 0;
-       unsigned int busy_cpu;
-       unsigned int cur_freq;
-       unsigned int load;
-       unsigned int sum_load;
-       unsigned int sum_runnable_load;
-       unsigned int nr_runnings;
-       int limit_max_cpu;
-       int i;
-       int j;
-
-       limit_max_cpu = table[level].limit_max_cpu;
-
-       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
-               cur_freq = stats[i].freq;
-               nr_runnings = stats[i].nr_runnings;
-
-               stats[i].num_busy_cpu = 0;
-               stats[i].avg_load = 0;
-               stats[i].avg_runnable_load = 0;
-               stats[i].avg_thread_load = 0;
-               stats[i].avg_thread_runnable_load = 0;
-
-               busy_cpu = 0;
-               sum_load = 0;
-               sum_runnable_load = 0;
-
-               /* Calculate the number of busy cpu */
-               for (j = 0; j < policy->cpufreq.num_nr_cpus; j++) {
-                       load = stats[i].load[j];
-                       sum_load += stats[i].load[j];
-                       sum_runnable_load += stats[i].runnable_load[j];
-                       if (!load)
-                               continue;
-
-                       cpu_threshold =
-                               (unsigned int)(cur_freq * load)
-                                               / policy->cpufreq.max_freq;
-                       if (load == 100
-                               || cpu_threshold >= policy->pass_cpu_threshold)
-                               busy_cpu++;
-               }
-
-               stats[i].num_busy_cpu = busy_cpu;
-               stats[i].avg_load = sum_load / limit_max_cpu;
-               stats[i].avg_runnable_load = sum_runnable_load / limit_max_cpu;
-               if (nr_runnings) {
-                       stats[i].avg_thread_load
-                               = (sum_load * 100) / nr_runnings;
-                       stats[i].avg_thread_runnable_load
-                               = (sum_runnable_load * 100) / nr_runnings;
-               }
-       }
-}
-
-/*
- * pass_governor_stop - Stop PASS governor through D-Bus
- *
- * @policy: the instance of struct pass_policy
- */
-static void pass_governor_stop(struct pass_policy *policy)
-{
-       struct pass_resource *res = to_pass_resource(policy);
-       struct pass_conf_data *cdata = &res->cdata;
-
-       if (!policy->governor) {
-               _E("cannot stop PASS governor");
-               return;
-       }
-
-       if (policy->gov_state == PASS_GOV_STOP) {
-               _E("PASS governor is already inactive state");
-               return;
-       }
-
-       /* Restore maximum cpu freq/the number of online cpu */
-       pass_governor_change_level(policy, policy->num_levels - 1);
-
-       pass_hotplug_stop(policy);
-
-       if (policy->governor->gov_timer_id) {
-               ecore_timer_del(policy->governor->gov_timer_id);
-               policy->governor->gov_timer_id = NULL;
-       }
-
-       /* Set PASS state as PASS_GOV_STOP */
-       policy->gov_state = PASS_GOV_STOP;
-
-       _I("Stop governor for '%s' resource", cdata->res_name);
-}
-
-/*
- * pass_governor_core_timer - Callback function of core timer for PASS governor
- *
- * @data: the instance of struct pass_policy
- */
-static Eina_Bool pass_governor_core_timer(void *data)
-{
-       struct pass_policy *policy = (struct pass_policy *)data;
-       static int count = 0;
-       int level;
-       int ret;
-
-       if (!policy) {
-               _E("cannot execute PASS core timer");
-               return ECORE_CALLBACK_CANCEL;
-       }
-
-       /*
-        * Collect data related to system state
-        * - current cpu frequency
-        * - the number of nr_running
-        * - cpu load (= runnable_avg_sum * 100 / runnable_avg_period)
-        */
-       ret = pass_get_cpu_stats(policy);
-       if (ret < 0) {
-               if (count++ < PASS_CPU_STATS_MAX_COUNT)
-                       return ECORE_CALLBACK_RENEW;
-
-               count = 0;
-
-               _E("cannot read 'pass_cpu_stats' sysfs entry");
-               pass_governor_stop(policy);
-
-               return ECORE_CALLBACK_CANCEL;
-       }
-
-       /* Calculate the number of busy cpu */
-       pass_calculate_busy_cpu(policy);
-
-       /* Determine the amount of proper resource */
-       if (policy->governor->governor) {
-               level = policy->governor->governor(policy);
-
-               pass_governor_change_level(policy, level);
-       } else {
-               _E("cannot execute governor function");
-               pass_governor_stop(policy);
-               return ECORE_CALLBACK_CANCEL;
-       }
-
-       /*
-        * Change the period of govenor timer according to PASS level
-        */
-       if (policy->pass_table[level].gov_timeout >= PASS_MIN_GOV_TIMEOUT &&
-               (policy->governor->gov_timeout
-                != policy->pass_table[level].gov_timeout)) {
-
-               _I("Change the period of governor timer from %fs to %fs\n",
-                               policy->governor->gov_timeout,
-                               policy->pass_table[level].gov_timeout);
-
-               policy->governor->gov_timeout =
-                       policy->pass_table[level].gov_timeout;
-               ecore_timer_interval_set(policy->governor->gov_timer_id,
-                                       policy->governor->gov_timeout);
-               ecore_timer_reset(policy->governor->gov_timer_id);
-       }
-
-       return ECORE_CALLBACK_RENEW;
-}
-
-/*
- * pass_governor_start - Start PASS governor through D-Bus
- *
- * @policy: the instance of struct pass_policy
- */
-static void pass_governor_start(struct pass_policy *policy)
-{
-       struct pass_resource *res = to_pass_resource(policy);
-       struct pass_conf_data *cdata = &res->cdata;
-
-       if (!policy->governor) {
-               _E("cannot start PASS governor");
-               return;
-       }
-
-       if (is_enabled(policy)) {
-               _E("PASS governor is already active state");
-               return;
-       }
-
-       /* Create the core timer of PASS governor */
-       policy->governor->gov_timer_id = ecore_timer_add(
-                               policy->governor->gov_timeout,
-                               (Ecore_Task_Cb)pass_governor_core_timer,
-                               (void *)policy);
-       if (!policy->governor->gov_timer_id) {
-               _E("cannot add core timer for governor");
-               pass_governor_stop(policy);
-               return;
-       }
-
-       /*
-        * Set default pass level when starting pass
-        * - default pass level according to policy->init_level
-        */
-       policy->curr_level = -1;
-       if (policy->init_level > policy->max_level)
-               policy->init_level = policy->max_level;
-       pass_governor_change_level(policy, policy->init_level);
-
-       /* Set PASS state as PASS_GOV_START */
-       policy->gov_state = PASS_GOV_START;
-
-       _I("Start governor for '%s' resource", cdata->res_name);
-}
-
-/*
- * pass_governor_init - Initialize PASS governor
- *
- * @policy: the instance of struct pass_policy
- */
-static int pass_governor_init(struct pass_policy *policy)
-{
-       struct pass_resource *res = to_pass_resource(policy);
-       struct pass_conf_data *cdata = &res->cdata;
-
-       if(policy->governor->gov_timeout < 0) {
-               _E("invalid timeout value [%d]!",
-                       policy->governor->gov_timeout);
-               pass_governor_stop(policy);
-               return -EINVAL;
-       }
-
-       /* Set default PASS state */
-       policy->gov_state = PASS_GOV_STOP;
-
-       /* Initialize notifier */
-       pass_notifier_init(policy);
-
-       _I("Initialize governor for '%s' resource", cdata->res_name);
-
-       return 0;
-}
-
-/*
- * pass_governor_exit - Exit PASS governor
- */
-static int pass_governor_exit(struct pass_policy *policy)
-{
-       struct pass_resource *res = to_pass_resource(policy);
-       struct pass_conf_data *cdata = &res->cdata;
-       int i;
-
-       /* Exit notifier */
-       pass_notifier_exit(policy);
-
-       /*
-        * Stop core timer and
-        * Restore maximum online cpu/cpu frequency
-        */
-       pass_governor_stop(policy);
-
-       /* Free allocated memory */
-       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
-               free(policy->pass_cpu_stats[i].load);
-               free(policy->pass_cpu_stats[i].nr_running);
-               free(policy->pass_cpu_stats[i].runnable_load);
-       }
-       free(policy->pass_cpu_stats);
-
-       if (policy->hotplug)
-               free(policy->hotplug->sequence);
-
-       if (num_policy_pmqos > 0) {
-               for (i = 0; i < num_policy_pmqos; i++)
-                       policy_pmqos[i] = NULL;
-               num_policy_pmqos = 0;
-       }
-
-       /* Set pass_policy structure as default value */
-       policy->pass_cpu_threshold = 0;
-       policy->up_threshold = 0;
-       policy->down_threshold = 0;
-
-       policy->prev_level = 0;
-       policy->curr_level = 0;
-       policy->min_level = 0;
-       policy->max_level = 0;
-       policy->level_up_threshold = 0;
-
-       policy->pass_table = NULL;
-       policy->num_pass_cpu_stats = 0;
-
-       policy->governor->gov_timeout = 0;
-
-       policy->governor = NULL;
-
-       _I("Exit governor for '%s' resource", cdata->res_name);
-
-       return 0;
-}
-
-/*
- * pass_governor_update - Restart/Pause PASS governor
- *
- * @cond: the instance of struct pass_policy
- */
-static int pass_governor_update(struct pass_policy *policy,
-                       enum pass_gov_state state)
-{
-       if (!policy) {
-               _E("cannot update PASS governor");
-               return -EINVAL;
-       }
-
-       switch (state) {
-       case PASS_GOV_START:
-               pass_governor_start(policy);
-               break;
-       case PASS_GOV_STOP:
-               pass_governor_stop(policy);
-               break;
-       default:
-               _E("Unknown governor state");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * pass_governor_change_level_scope - Change the scope of cpufreq scaling
- *
- * @policy: the instance of struct pass_policy
- * @min_level: the minimum level of cpufreq scaling
- * @max_level: the maximum level of cpufreq scaling
- */
-int pass_governor_change_level_scope(struct pass_policy *policy,
-                                           int min_level, int max_level)
-{
-       if (!policy)
-               return -EINVAL;
-
-       if (min_level > max_level) {
-               _E("min_level(%d) have to be smaller than max_level(%d)\n",
-                                               min_level, max_level);
-               return -EINVAL;
-       }
-
-       if (min_level == policy->min_level
-               && max_level == policy->max_level)
-               return 0;
-
-       /* Change minimum/maximum level of cpufreq scaling */
-       policy->min_level = min_level;
-       policy->max_level = max_level;
-
-       pass_governor_change_level(policy, policy->curr_level);
-
-       return 0;
-}
-
-/*
- * Define PASS governor
- *
- * - Step governor
- * - Radiation governor
- */
-static struct pass_governor pass_gov_step = {
-       .name           = "pass_step",
-       .init           = pass_governor_init,
-       .exit           = pass_governor_exit,
-       .update         = pass_governor_update,
-
-       .governor       = pass_step_governor,
-};
-
-static struct pass_governor pass_gov_radiation = {
-       .name           = "pass_radiation",
-       .init           = pass_governor_init,
-       .exit           = pass_governor_exit,
-       .update         = pass_governor_update,
-
-       .governor       = pass_radiation_governor,
-};
-
-/*
- * pass_get_governor - Return specific governor instance according to type
- *
- * @type: the type of PASS governor
- */
-struct pass_governor* pass_get_governor(struct pass_policy *policy,
-                                               enum pass_gov_type type)
-{
-       switch (type) {
-       case PASS_GOV_STEP:
-               return &pass_gov_step;
-       case PASS_GOV_RADIATION:
-               return &pass_gov_radiation;
-       default:
-               _E("Unknown governor type");
-               break;
-       };
-
-       return NULL;
-}
diff --git a/src/pass/pass-core.h b/src/pass/pass-core.h
deleted file mode 100644 (file)
index bbec558..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * PASS (Power Aware System Service)
- *
- * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __PASS_CORE__
-#define __PASS_CORE__
-
-/*
- * pass_get_governor - Return specific governor instance according to type
- *
- * @policy: the instance of struct pass_policy
- * @type: the type of PASS governor
- */
-struct pass_governor* pass_get_governor(struct pass_policy *policy,
-                                               enum pass_gov_type type);
-
-/*
- * pass_get_hotplug - Return specific hotplug instance according to type
- *
- * @policy: the instance of struct pass_policy
- * @type: the type of PASS governor
- */
-struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
-                                               enum pass_gov_type type);
-
-/*
- * pass_governor_change_level_scope - Change the scope of cpufreq scaling
- *
- * @policy: the instance of struct pass_policy
- * @min_level: the minimum level of cpufreq scaling
- * @max_level: the maximum level of cpufreq scaling
- */
-int pass_governor_change_level_scope(struct pass_policy *policy,
-                                           int min_level, int max_level);
-
-#endif /* __PASS_CORE__ */
diff --git a/src/pass/pass-gov.c b/src/pass/pass-gov.c
new file mode 100644 (file)
index 0000000..904ac72
--- /dev/null
@@ -0,0 +1,742 @@
+/*
+ * PASS (Power Aware System Service) Governor
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "pass.h"
+#include "pass-gov.h"
+#include "pass-pmqos.h"
+#include "pass-hal.h"
+
+#include "core/device-notifier.h"
+#include "core/config-parser.h"
+
+#define PASS_CPU_STATS_MAX_COUNT       20
+
+/*
+ * FIXME: Current notifier of PASS didn't pass separate user_data parameter
+ * on callback function. So, PASS must need global pass_policy instance. This
+ * code must be modified after changing PASS's notifier feature.
+ */
+static struct pass_policy *policy_pmqos[PASS_RESOURCE_MAX];
+static int num_policy_pmqos = 0;
+
+/*
+ * is_enabled - Check the state of PASS governor
+ * @policy: instance of pass_policy structure
+ *
+ * Return true if the state of PASS is PASS_GOV_START
+ * Return false if the state of PASS is PASS_GOV_STOP
+ */
+static bool is_enabled(struct pass_policy *policy)
+{
+       if (!policy)
+               return false;
+
+       if (policy->gov_state != PASS_GOV_START)
+               return false;
+
+       return true;
+}
+
+/*
+ * pass_notifier_booting_done - Callback function of DEVICE_NOTIFIER_BOOTING_
+ *                              DONE notifier
+ * @data: NULL, this parameter isn't used
+ */
+static int pass_notifier_booting_done(void *data)
+{
+       int i;
+
+       if (num_policy_pmqos == 0)
+               return 0;
+
+       /* Start PASS governor if 'pass_support' in pass.conf is true */
+       for (i = 0; i < num_policy_pmqos; i++) {
+               if (policy_pmqos[i]->state == PASS_ON
+                       && policy_pmqos[i]->governor != NULL) {
+                       policy_pmqos[i]->governor->update(policy_pmqos[i],
+                                                       PASS_GOV_START);
+               }
+       }
+
+       return 0;
+}
+
+static int pass_notifier_pmqos(void *data)
+{
+       int i;
+
+       if (num_policy_pmqos == 0)
+               return 0;
+
+       for (i = 0; i < num_policy_pmqos; i++) {
+               if (policy_pmqos[i]->state == PASS_ON
+                       && policy_pmqos[i]->governor != NULL) {
+                       pass_notifier_pmqos_func(policy_pmqos[i], data);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * pass_notifier_init - Register notifiers and init
+ * @policy: the instance of pass_policy structure
+ */
+static int pass_notifier_init(struct pass_policy *policy)
+{
+       /* Register DEVICE_NOTIFIER_PMQOS */
+       register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+
+       /* Register DEVICE_NOTIFIER_BOOTING_DONE */
+       register_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                         pass_notifier_booting_done);
+
+       /*
+        * FIXME: Current notifier of PASS didn't pass separate user_data
+        * parameter on callback function. So, PASS must need global pass_policy
+        * instance. This code must be modified after changing PASS's
+        * notifier feature.
+        */
+       policy_pmqos[num_policy_pmqos++] = policy;
+
+       return 0;
+}
+
+/*
+ * pass_notifier_exit - Un-register notifiers and exit
+ * @policy: the instance of pass_policy structure
+ */
+static int pass_notifier_exit(struct pass_policy *policy)
+{
+       /* Un-register DEVICE_NOTIFIER_PMQOS */
+       unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+
+       /* Un-Register DEVICE_NOTIFIER_BOOTING_DONE */
+       unregister_notifier(DEVICE_NOTIFIER_BOOTING_DONE,
+                           pass_notifier_booting_done);
+
+       return 0;
+}
+
+/*****************************************************************************
+ *                            PASS CPU Hotplug                               *
+ ****************************************************************************/
+
+/*
+ * pass_hotplug_set_online - Change the maximum number of online cpu
+ *
+ * @policy: the instance of struct pass_policy
+ * @max_online: the maximum number of online cpu
+ */
+static void pass_hotplug_set_online(struct pass_policy *policy,
+                                       unsigned int online)
+{
+       struct pass_resource *pass_res = to_pass_resource(policy);
+       struct pass_hotplug *hotplug = policy->hotplug;
+       int i;
+
+       if (!hotplug || online == hotplug->online)
+               return;
+
+       if (online > hotplug->max_online)
+               online = hotplug->max_online;
+
+       for (i = 0 ; i < policy->cpufreq.num_nr_cpus; i++) {
+               if (i < online) {
+                       pass_set_online_state(pass_res, hotplug->sequence[i],
+                                               PASS_CPU_UP);
+               } else {
+                       pass_set_online_state(pass_res, hotplug->sequence[i],
+                                               PASS_CPU_DOWN);
+               }
+       }
+
+       /*
+       _I("- CPU %4s '%d->%d'Core\n",
+               (hotplug->online > online ? "DOWN" : "UP"),
+               hotplug->online, online);
+       */
+
+       hotplug->online = online;
+}
+
+/*
+ * pass_hotplug_stop - Stop PASS hotplug
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_hotplug_stop(struct pass_policy *policy)
+{
+       struct pass_table *table = policy->pass_table;
+       int level = policy->max_level;
+
+       if (!policy->hotplug)
+               return;
+
+       policy->hotplug->online = table[level].limit_max_cpu;
+       policy->hotplug->max_online = policy->cpufreq.num_nr_cpus;
+}
+
+static int pass_hotplug_dummy_governor(struct pass_policy *policy)
+{
+       int level = policy->curr_level;
+
+       return policy->pass_table[level].limit_max_cpu;
+}
+
+/*
+ * pass_get_governor - Return specific hotplug instance according to type
+ *
+ * @type: the type of PASS hotplug
+ */
+struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
+                                       enum pass_gov_type type)
+{
+       struct pass_hotplug *hotplug;
+
+       switch (type) {
+       case PASS_GOV_STEP:
+       case PASS_GOV_RADIATION:
+               hotplug = calloc(1, sizeof(struct pass_hotplug));
+               if (!hotplug) {
+                       _E("cannot allocate the memory of struct pass_hotplug");
+                       return NULL;
+               }
+               hotplug->governor = pass_hotplug_dummy_governor;
+               return hotplug;
+       default:
+               _E("Unknown hotplug type");
+               break;
+       };
+
+       return NULL;
+}
+
+/*****************************************************************************
+ *                              PASS governor                                *
+ ****************************************************************************/
+
+/*
+ * pass_governor_change_level - Change maximum cpu frequency and number of online cpu
+ *
+ * @policy: the instance of struct pass_policy
+ * @level: the pass level
+ */
+static int pass_governor_change_level(struct pass_policy *policy, int new_level)
+{
+       struct pass_resource *pass_res = to_pass_resource(policy);
+       struct pass_conf_data *cdata = &pass_res->cdata;
+       struct pass_table *table = policy->pass_table;
+       struct pass_hotplug *hotplug = policy->hotplug;
+       int curr_level = policy->curr_level;
+       int limit_max_freq;
+       int limit_max_cpu;
+       int online;
+       int ret;
+
+       if (new_level > policy->max_level)
+               new_level = policy->max_level;
+
+       if (new_level < policy->min_level)
+               new_level = policy->min_level;
+
+       if (new_level == curr_level)
+               return 0;
+
+       /*
+        * Get maximum CPU frequency/the maximum number of online CPU
+        * according to PASS level.
+        */
+       limit_max_freq = table[new_level].limit_max_freq;
+       limit_max_cpu = table[new_level].limit_max_cpu;
+
+       policy->prev_level = policy->curr_level;
+       policy->curr_level = new_level;
+
+       /* Turn on/off CPUs according the maximum number of online CPU */
+       if (hotplug) {
+               if (hotplug->max_online != limit_max_cpu)
+                       hotplug->max_online = limit_max_cpu;
+
+               if (hotplug->governor)
+                       online = hotplug->governor(policy);
+               else
+                       online = 1;
+
+               pass_hotplug_set_online(policy, online);
+       }
+
+       /* Set maximum CPU frequency */
+       ret = pass_set_max_freq(pass_res, limit_max_freq);
+       if (ret < 0) {
+               _E("cannot set the maximum frequency of %s", cdata->res_name);
+               return -EINVAL;
+       }
+
+       /*
+       _I("[PASS %s] Level %4s '%d->%d' : '%d'Hz/'%d'Core\n",
+               pass_res->cdata.res_name,
+               (curr_level > new_level ? "DOWN" : "UP"),
+               curr_level, new_level, limit_max_freq, limit_max_cpu);
+       */
+
+       return 0;
+};
+
+/*
+ * pass_calculate_busy_cpu - Count a number of busy cpu among NR_CPUS by using
+ *                          runnable_avg_sum/runnable_avg_period
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void pass_calculate_busy_cpu(struct pass_policy *policy)
+{
+       struct pass_cpu_stats *stats = policy->pass_cpu_stats;
+       struct pass_table *table = policy->pass_table;
+       unsigned int level = policy->curr_level;
+       unsigned int cpu_threshold = 0;
+       unsigned int busy_cpu;
+       unsigned int cur_freq;
+       unsigned int load;
+       unsigned int sum_load;
+       unsigned int sum_runnable_load;
+       unsigned int nr_runnings;
+       int limit_max_cpu;
+       int i;
+       int j;
+
+       limit_max_cpu = table[level].limit_max_cpu;
+
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               cur_freq = stats[i].freq;
+               nr_runnings = stats[i].nr_runnings;
+
+               stats[i].num_busy_cpu = 0;
+               stats[i].avg_load = 0;
+               stats[i].avg_runnable_load = 0;
+               stats[i].avg_thread_load = 0;
+               stats[i].avg_thread_runnable_load = 0;
+
+               busy_cpu = 0;
+               sum_load = 0;
+               sum_runnable_load = 0;
+
+               /* Calculate the number of busy cpu */
+               for (j = 0; j < policy->cpufreq.num_nr_cpus; j++) {
+                       load = stats[i].load[j];
+                       sum_load += stats[i].load[j];
+                       sum_runnable_load += stats[i].runnable_load[j];
+                       if (!load)
+                               continue;
+
+                       cpu_threshold =
+                               (unsigned int)(cur_freq * load)
+                                               / policy->cpufreq.max_freq;
+                       if (load == 100
+                               || cpu_threshold >= policy->pass_cpu_threshold)
+                               busy_cpu++;
+               }
+
+               stats[i].num_busy_cpu = busy_cpu;
+               stats[i].avg_load = sum_load / limit_max_cpu;
+               stats[i].avg_runnable_load = sum_runnable_load / limit_max_cpu;
+               if (nr_runnings) {
+                       stats[i].avg_thread_load
+                               = (sum_load * 100) / nr_runnings;
+                       stats[i].avg_thread_runnable_load
+                               = (sum_runnable_load * 100) / nr_runnings;
+               }
+       }
+}
+
+/*
+ * pass_governor_core_timer - Callback function of core timer for PASS governor
+ *
+ * @data: the instance of struct pass_policy
+ */
+static Eina_Bool pass_governor_core_timer(void *data)
+{
+       struct pass_policy *policy = (struct pass_policy *)data;
+       static int count = 0;
+       int level;
+       int ret;
+
+       if (!policy) {
+               _E("cannot execute PASS core timer");
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /*
+        * Collect data related to system state
+        * - current cpu frequency
+        * - the number of nr_running
+        * - cpu load (= runnable_avg_sum * 100 / runnable_avg_period)
+        */
+       ret = pass_get_cpu_stats(policy);
+       if (ret < 0) {
+               if (count++ < PASS_CPU_STATS_MAX_COUNT)
+                       return ECORE_CALLBACK_RENEW;
+
+               count = 0;
+
+               _E("cannot read 'pass_cpu_stats' sysfs entry");
+               pass_governor_update(policy, PASS_GOV_STOP);
+
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /* Calculate the number of busy cpu */
+       pass_calculate_busy_cpu(policy);
+
+       /* Determine the amount of proper resource */
+       if (policy->governor->governor) {
+               level = policy->governor->governor(policy);
+
+               pass_governor_change_level(policy, level);
+       } else {
+               _E("cannot execute governor function");
+               pass_governor_update(policy, PASS_GOV_STOP);
+               return ECORE_CALLBACK_CANCEL;
+       }
+
+       /*
+        * Change the period of govenor timer according to PASS level
+        */
+       if (policy->pass_table[level].gov_timeout >= PASS_MIN_GOV_TIMEOUT &&
+               (policy->governor->gov_timeout
+                != policy->pass_table[level].gov_timeout)) {
+
+               _I("Change the period of governor timer from %fs to %fs\n",
+                               policy->governor->gov_timeout,
+                               policy->pass_table[level].gov_timeout);
+
+               policy->governor->gov_timeout =
+                       policy->pass_table[level].gov_timeout;
+               ecore_timer_interval_set(policy->governor->gov_timer_id,
+                                       policy->governor->gov_timeout);
+               ecore_timer_reset(policy->governor->gov_timer_id);
+       }
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+/*
+ * __pass_governor_start - Start PASS governor through D-Bus
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void __pass_governor_start(struct pass_policy *policy)
+{
+       struct pass_resource *res = to_pass_resource(policy);
+       struct pass_conf_data *cdata = &res->cdata;
+
+       if (!policy->governor) {
+               _E("cannot start PASS governor");
+               return;
+       }
+
+       if (is_enabled(policy)) {
+               _E("PASS governor is already active state");
+               return;
+       }
+
+       /* Create the core timer of PASS governor */
+       policy->governor->gov_timer_id = ecore_timer_add(
+                               policy->governor->gov_timeout,
+                               (Ecore_Task_Cb)pass_governor_core_timer,
+                               (void *)policy);
+       if (!policy->governor->gov_timer_id) {
+               _E("cannot add core timer for governor");
+               pass_governor_update(policy, PASS_GOV_STOP);
+               return;
+       }
+
+       /*
+        * Set default pass level when starting pass
+        * - default pass level according to policy->init_level
+        */
+       policy->curr_level = -1;
+       if (policy->init_level > policy->max_level)
+               policy->init_level = policy->max_level;
+       pass_governor_change_level(policy, policy->init_level);
+
+       /* Set PASS state as PASS_GOV_START */
+       policy->gov_state = PASS_GOV_START;
+
+       _I("Start governor for '%s' resource", cdata->res_name);
+}
+
+/*
+ * __pass_governor_stop - Stop PASS governor through D-Bus
+ *
+ * @policy: the instance of struct pass_policy
+ */
+static void __pass_governor_stop(struct pass_policy *policy)
+{
+       struct pass_resource *res = to_pass_resource(policy);
+       struct pass_conf_data *cdata = &res->cdata;
+
+       if (!policy->governor) {
+               _E("cannot stop PASS governor");
+               return;
+       }
+
+       if (policy->gov_state == PASS_GOV_STOP) {
+               _E("PASS governor is already inactive state");
+               return;
+       }
+
+       /* Restore maximum cpu freq/the number of online cpu */
+       pass_governor_change_level(policy, policy->num_levels - 1);
+
+       pass_hotplug_stop(policy);
+
+       if (policy->governor->gov_timer_id) {
+               ecore_timer_del(policy->governor->gov_timer_id);
+               policy->governor->gov_timer_id = NULL;
+       }
+
+       /* Set PASS state as PASS_GOV_STOP */
+       policy->gov_state = PASS_GOV_STOP;
+
+       _I("Stop governor for '%s' resource", cdata->res_name);
+}
+
+static int __pass_governor_init(struct pass_policy *policy)
+{
+       struct pass_resource *res = to_pass_resource(policy);
+       struct pass_conf_data *cdata = &res->cdata;
+
+       if(policy->governor->gov_timeout < 0) {
+               _E("invalid timeout value [%d]!",
+                       policy->governor->gov_timeout);
+               pass_governor_update(policy, PASS_GOV_STOP);
+               return -EINVAL;
+       }
+
+       /* Set default PASS state */
+       policy->gov_state = PASS_GOV_STOP;
+
+       /* Initialize notifier */
+       pass_notifier_init(policy);
+
+       _I("Initialize governor for '%s' resource", cdata->res_name);
+
+       return 0;
+}
+
+static int __pass_governor_exit(struct pass_policy *policy)
+{
+       struct pass_resource *res = to_pass_resource(policy);
+       struct pass_conf_data *cdata = &res->cdata;
+       int i;
+
+       /* Exit notifier */
+       pass_notifier_exit(policy);
+
+       /*
+        * Stop core timer and
+        * Restore maximum online cpu/cpu frequency
+        */
+       pass_governor_update(policy, PASS_GOV_STOP);
+
+       /* Free allocated memory */
+       for (i = 0; i < policy->num_pass_cpu_stats; i++) {
+               free(policy->pass_cpu_stats[i].load);
+               free(policy->pass_cpu_stats[i].nr_running);
+               free(policy->pass_cpu_stats[i].runnable_load);
+       }
+       free(policy->pass_cpu_stats);
+
+       if (policy->hotplug)
+               free(policy->hotplug->sequence);
+
+       if (num_policy_pmqos > 0) {
+               for (i = 0; i < num_policy_pmqos; i++)
+                       policy_pmqos[i] = NULL;
+               num_policy_pmqos = 0;
+       }
+
+       /* Set pass_policy structure as default value */
+       policy->pass_cpu_threshold = 0;
+       policy->up_threshold = 0;
+       policy->down_threshold = 0;
+
+       policy->prev_level = 0;
+       policy->curr_level = 0;
+       policy->min_level = 0;
+       policy->max_level = 0;
+       policy->level_up_threshold = 0;
+
+       policy->pass_table = NULL;
+       policy->num_pass_cpu_stats = 0;
+
+       policy->governor->gov_timeout = 0;
+
+       policy->governor = NULL;
+
+       _I("Exit governor for '%s' resource", cdata->res_name);
+
+       return 0;
+}
+
+static int __pass_governor_update(struct pass_policy *policy,
+                       enum pass_gov_state state)
+{
+       if (!policy) {
+               _E("cannot update PASS governor");
+               return -EINVAL;
+       }
+
+       switch (state) {
+       case PASS_GOV_START:
+               __pass_governor_start(policy);
+               break;
+       case PASS_GOV_STOP:
+               __pass_governor_stop(policy);
+               break;
+       default:
+               _E("Unknown governor state");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * pass_governor_change_level_scope - Change the scope of cpufreq scaling
+ *
+ * @policy: the instance of struct pass_policy
+ * @min_level: the minimum level of cpufreq scaling
+ * @max_level: the maximum level of cpufreq scaling
+ */
+int pass_governor_change_level_scope(struct pass_policy *policy,
+                                           int min_level, int max_level)
+{
+       if (!policy)
+               return -EINVAL;
+
+       if (min_level > max_level) {
+               _E("min_level(%d) have to be smaller than max_level(%d)\n",
+                                               min_level, max_level);
+               return -EINVAL;
+       }
+
+       if (min_level == policy->min_level
+               && max_level == policy->max_level)
+               return 0;
+
+       /* Change minimum/maximum level of cpufreq scaling */
+       policy->min_level = min_level;
+       policy->max_level = max_level;
+
+       pass_governor_change_level(policy, policy->curr_level);
+
+       return 0;
+}
+
+/*
+ * Define PASS governor
+ *
+ * - Step governor
+ * - Radiation governor
+ */
+static struct pass_governor pass_gov_step = {
+       .name           = "pass_step",
+       .init           = __pass_governor_init,
+       .exit           = __pass_governor_exit,
+       .update         = __pass_governor_update,
+
+       .governor       = pass_step_governor,
+};
+
+static struct pass_governor pass_gov_radiation = {
+       .name           = "pass_radiation",
+       .init           = __pass_governor_init,
+       .exit           = __pass_governor_exit,
+       .update         = __pass_governor_update,
+
+       .governor       = pass_radiation_governor,
+};
+
+/*
+ * pass_get_governor - Return specific governor instance according to type
+ *
+ * @type: the type of PASS governor
+ */
+struct pass_governor* pass_get_governor(struct pass_policy *policy,
+                                               enum pass_gov_type type)
+{
+       switch (type) {
+       case PASS_GOV_STEP:
+               return &pass_gov_step;
+       case PASS_GOV_RADIATION:
+               return &pass_gov_radiation;
+       default:
+               _E("Unknown governor type");
+               break;
+       };
+
+       return NULL;
+}
+
+/*
+ * __pass_governor_init - Initialize PASS governor
+ *
+ * @policy: the instance of struct pass_policy
+ */
+int pass_governor_init(struct pass_policy *policy)
+{
+       if (!policy || !policy->governor || !policy->governor->init)
+               return -EINVAL;
+
+       return policy->governor->init(policy);
+}
+
+/*
+ * __pass_governor_exit - Exit PASS governor
+ */
+int pass_governor_exit(struct pass_policy *policy)
+{
+       if (!policy || !policy->governor || !policy->governor->exit)
+               return -EINVAL;
+
+       return policy->governor->exit(policy);
+}
+
+/*
+ * __pass_governor_update - Restart/Pause PASS governor
+ *
+ * @policy: the instance of struct pass_policy
+ * @state: the state of governor
+ *     PASS_GOV_START : start governor
+ *     PASS_GOV_STOP: stop governor
+ */
+int pass_governor_update(struct pass_policy *policy,
+                                       enum pass_gov_state state)
+{
+       if (!policy || !policy->governor || !policy->governor->update)
+               return -EINVAL;
+
+       return policy->governor->update(policy, state);
+}
index 1caa07b038cf1df78778e51d566fe0f1b9946178..e80498f18b3da52256757785b145297428110661 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * PASS (Power Aware System Service)
+ * PASS (Power Aware System Service) Governor
  *
  * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
  *
 #ifndef __PASS_GOV__
 #define __PASS_GOV__
 
-/* PASS Step governor function */
-int pass_step_governor(struct pass_policy *policy);
+/* Init, exit and update the governor */
+int pass_governor_init(struct pass_policy *policy);
+int pass_governor_exit(struct pass_policy *policy);
+int pass_governor_update(struct pass_policy *policy, enum pass_gov_state state);
+int pass_governor_change_level_scope(struct pass_policy *policy,
+                                       int min_level, int max_level);
+
+/* Get the governor/hotplug instance according to enum pass_gov_type */
+struct pass_governor* pass_get_governor(struct pass_policy *policy,
+                                       enum pass_gov_type type);
+struct pass_hotplug* pass_get_hotplug(struct pass_policy *policy,
+                                       enum pass_gov_type type);
 
-/* PASS Radiation governor function */
+/* Function for radiation and step governor */
+int pass_step_governor(struct pass_policy *policy);
 int pass_radiation_governor(struct pass_policy *policy);
 
 #endif /* __PASS_GOV__ */
index 9ab0dbb1d6d0d5453a01aac5fb708be1badfd045..31627c5fb83bdc5c504374ade3ca08658b384db6 100644 (file)
@@ -22,7 +22,7 @@
 #include <sys/time.h>
 
 #include "pass.h"
-#include "pass-core.h"
+#include "pass-gov.h"
 #include "pass-hal.h"
 
 #include "core/device-notifier.h"
index ed84d9f8650ee890ce0c43ebdc568523995b788a..0fbabd34d50c239eb034afe83035b55a73f7e3c6 100644 (file)
@@ -23,9 +23,9 @@
 #include <stdlib.h>
 
 #include "pass.h"
-#include "pass-core.h"
 #include "pass-parser.h"
 #include "pass-hal.h"
+#include "pass-gov.h"
 
 #include "core/devices.h"
 #include "core/common.h"
@@ -43,40 +43,47 @@ static struct pass g_pass;
  ******************************************************/
 static DBusMessage* e_dbus_start_cb(E_DBus_Object *obj, DBusMessage* msg)
 {
-       DBusMessage *ret = NULL;
-       int i;
+       DBusMessage *ret_dbus = NULL;
+       int i, ret;
 
        for (i = 0; i < g_pass.num_resources; i++) {
                struct pass_resource *pass_res = &g_pass.res[i];
                struct pass_policy *policy = &pass_res->policy;
 
-               if (policy->governor)
-                       policy->governor->update(policy, PASS_GOV_START);
-               ret = dbus_message_new_method_return(msg);
-               if (!ret)
-                       return ret;
+               ret = pass_governor_update(policy, PASS_GOV_START);
+               if (ret < 0) {
+                       _E("cannot start the governor with dbus");
+                       return ret_dbus;
+               }
+               ret_dbus = dbus_message_new_method_return(msg);
+               if (!ret_dbus)
+                       return ret_dbus;
        }
 
-       return ret;
+       return ret_dbus;
 }
 
 static DBusMessage* e_dbus_stop_cb(E_DBus_Object *obj, DBusMessage* msg)
 {
-       DBusMessage *ret = NULL;
-       int i;
+       DBusMessage *ret_dbus = NULL;
+       int i, ret;
 
        for (i = 0; i < g_pass.num_resources; i++) {
                struct pass_resource *pass_res = &g_pass.res[i];
                struct pass_policy *policy = &pass_res->policy;
 
-               if (policy->governor)
-                       policy->governor->update(policy, PASS_GOV_STOP);
-               ret = dbus_message_new_method_return(msg);
-               if (!ret)
-                       return ret;
+               ret = pass_governor_update(policy, PASS_GOV_STOP);
+               if (ret < 0) {
+                       _E("cannot stop the governor");
+                       return ret_dbus;
+               }
+
+               ret_dbus = dbus_message_new_method_return(msg);
+               if (!ret_dbus)
+                       return ret_dbus;
        }
 
-       return ret;
+       return ret_dbus;
 }
 
 static const struct edbus_method edbus_methods[] = {
@@ -187,14 +194,9 @@ static int pass_resource_init(struct pass_policy *policy)
                        policy->hotplug->sequence[i] = i + pass_res->cdata.cpu;
        }
 
-       if (policy->governor->init) {
-               ret = policy->governor->init(policy);
-               if (ret < 0) {
-                       _E("cannot initialize PASS governor");
-                       return -1;
-               }
-       } else {
-               _E("cannot execute init() of PASS governor");
+       ret = pass_governor_init(policy);
+       if (ret < 0) {
+               _E("cannot initialize PASS governor");
                return -1;
        }
 
@@ -205,21 +207,11 @@ static int pass_resource_exit(struct pass_policy *policy)
 {
        int ret;
 
-       if (!policy->governor) {
-               _E("cannot exit PASS");
-               return -1;
-       }
-
        pass_put_table(policy);
 
-       if (policy->governor->exit) {
-               ret = policy->governor->exit(policy);
-               if (ret < 0) {
-                       _E("cannot exit PASS governor");
-                       return -1;
-               }
-       } else {
-               _E("cannot execute exit() of PASS governor");
+       ret = pass_governor_exit(policy);
+       if (ret < 0) {
+               _E("cannot exit PASS governor");
                return -1;
        }