From: Peter De Schrijver Date: Fri, 30 Mar 2012 08:42:17 +0000 (+0300) Subject: cpuquiet: governor support X-Git-Tag: firefly_0821_release~4158^2~57 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=58642f2786e4d918ce66a22ac597ef70a050ffd1;p=firefly-linux-kernel-4.4.55.git cpuquiet: governor support Change-Id: I05b9dedc04bb3b2ddba6202a002c1e5514ec4777 Signed-off-by: Peter De Schrijver Reviewed-on: http://git-master/r/105269 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Tested-by: Sai Gurrappadi Reviewed-by: Sai Gurrappadi Reviewed-by: Diwakar Tundlam Rebase-Id: R481f3df7610b737f6c054370efbe3bdb95a5e78d --- 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 +#include +#include + +#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); +}