diff options
author | Peter De Schrijver <pdeschrijver@nvidia.com> | 2012-03-30 11:42:17 +0300 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-06-07 16:47:52 +0530 |
commit | 1d162382c1ddb7eeea026e04e9c2c6eb86664768 (patch) | |
tree | 47354e65372352a3ff778c7cb6c99390da587ea2 /drivers | |
parent | 62d8daf333d121a9ccb41328faadcd4808ce7783 (diff) |
cpuquiet: governor support
Change-Id: I05b9dedc04bb3b2ddba6202a002c1e5514ec4777
Signed-off-by: Peter De Schrijver <pdeschrijver@nvidia.com>
Reviewed-on: http://git-master/r/105269
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Tested-by: Sai Gurrappadi <sgurrappadi@nvidia.com>
Reviewed-by: Sai Gurrappadi <sgurrappadi@nvidia.com>
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cpuquiet/governor.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/drivers/cpuquiet/governor.c b/drivers/cpuquiet/governor.c new file mode 100644 index 000000000000..1446b9ee5066 --- /dev/null +++ b/drivers/cpuquiet/governor.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012 NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include <linux/mutex.h> +#include <linux/module.h> +#include <linux/cpuquiet.h> + +#include "cpuquiet.h" + +LIST_HEAD(cpuquiet_governors); +struct cpuquiet_governor *cpuquiet_curr_governor; + +struct cpuquiet_governor *cpuquiet_get_first_governor(void) +{ + if (!list_empty(&cpuquiet_governors)) + return list_entry(&cpuquiet_governors, struct cpuquiet_governor, + governor_list); + else + return NULL; +} + +struct cpuquiet_governor *cpuquiet_find_governor(const char *str) +{ + struct cpuquiet_governor *gov; + + list_for_each_entry(gov, &cpuquiet_governors, governor_list) + if (!strnicmp(str, gov->name, CPUQUIET_NAME_LEN)) + return gov; + + return NULL; +} + +int cpuquiet_switch_governor(struct cpuquiet_governor *gov) +{ + int err = 0; + + if (cpuquiet_curr_governor) { + if (cpuquiet_curr_governor->stop) + cpuquiet_curr_governor->stop(); + module_put(cpuquiet_curr_governor->owner); + } + + cpuquiet_curr_governor = gov; + + if (gov) { + if (!try_module_get(cpuquiet_curr_governor->owner)) + return -EINVAL; + if (gov->start) + err = gov->start(); + if (!err) + cpuquiet_curr_governor = gov; + } + + return err; +} + +int cpuquiet_register_governor(struct cpuquiet_governor *gov) +{ + int ret = -EEXIST; + + if (!gov) + return -EINVAL; + + mutex_lock(&cpuquiet_lock); + if (cpuquiet_find_governor(gov->name) == NULL) { + ret = 0; + list_add_tail(&gov->governor_list, &cpuquiet_governors); + if (!cpuquiet_curr_governor && cpuquiet_get_driver()) + cpuquiet_switch_governor(gov); + } + mutex_unlock(&cpuquiet_lock); + + return ret; +} + +void cpuquiet_unregister_governor(struct cpuquiet_governor *gov) +{ + if (!gov) + return; + + mutex_lock(&cpuquiet_lock); + if (cpuquiet_curr_governor == gov) + cpuquiet_switch_governor(NULL); + list_del(&gov->governor_list); + mutex_unlock(&cpuquiet_lock); +} |