diff options
author | Antti P Miettinen <amiettinen@nvidia.com> | 2012-08-20 19:36:38 +0300 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-08-22 12:04:18 -0700 |
commit | 064618cb59271bf674f489219028807ff712b241 (patch) | |
tree | 781eda741710a6a3f6065cb9239b645566b77408 /kernel | |
parent | adf925fb2e1bf0c25e4427884260bf69780ff0bd (diff) |
PM QoS: Add disable parameter
For testing purposes it is useful to be able to disable
PM Qos.
Bug 1020898
Bug 917572
Change-Id: I266f5b5730cfe4705197d8b09db7f9eda6766c7c
Signed-off-by: Antti P Miettinen <amiettinen@nvidia.com>
Reviewed-on: http://git-master/r/124667
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/pm_qos_params.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/kernel/pm_qos_params.c b/kernel/pm_qos_params.c index 82da7ac3b1f3..c52405ce4d78 100644 --- a/kernel/pm_qos_params.c +++ b/kernel/pm_qos_params.c @@ -174,6 +174,8 @@ static const struct file_operations pm_qos_power_fops = { .llseek = noop_llseek, }; +static bool pm_qos_enabled __read_mostly = true; + /* unlocked internal variant */ static inline int pm_qos_get_value(struct pm_qos_object *o) { @@ -226,8 +228,11 @@ static void update_target(struct pm_qos_object *o, struct plist_node *node, } else { plist_add(node, &o->requests); } - curr_value = pm_qos_get_value(o); - pm_qos_set_value(o, curr_value); + if (pm_qos_enabled) { + curr_value = pm_qos_get_value(o); + pm_qos_set_value(o, curr_value); + } else + curr_value = o->default_value; spin_unlock_irqrestore(&pm_qos_lock, flags); if (prev_value != curr_value) @@ -372,6 +377,58 @@ void pm_qos_remove_request(struct pm_qos_request_list *pm_qos_req) } EXPORT_SYMBOL_GPL(pm_qos_remove_request); +static int pm_qos_enabled_set(const char *arg, const struct kernel_param *kp) +{ + unsigned long flags; + bool old; + s32 prev[PM_QOS_NUM_CLASSES], curr[PM_QOS_NUM_CLASSES]; + int ret, i; + + old = pm_qos_enabled; + ret = param_set_bool(arg, kp); + if (ret != 0) { + pr_warn("%s: cannot set PM QoS enable to %s\n", + __FUNCTION__, arg); + return ret; + } + spin_lock_irqsave(&pm_qos_lock, flags); + for (i = 1; i < PM_QOS_NUM_CLASSES; i++) + prev[i] = pm_qos_read_value(pm_qos_array[i]); + if (old && !pm_qos_enabled) { + /* got disabled */ + for (i = 1; i < PM_QOS_NUM_CLASSES; i++) { + curr[i] = pm_qos_array[i]->default_value; + pm_qos_set_value(pm_qos_array[i], curr[i]); + } + } else if (!old && pm_qos_enabled) { + /* got enabled */ + for (i = 1; i < PM_QOS_NUM_CLASSES; i++) { + curr[i] = pm_qos_get_value(pm_qos_array[i]); + pm_qos_set_value(pm_qos_array[i], curr[i]); + } + } + spin_unlock_irqrestore(&pm_qos_lock, flags); + for (i = 1; i < PM_QOS_NUM_CLASSES; i++) + if (prev[i] != curr[i]) + blocking_notifier_call_chain( + pm_qos_array[i]->notifiers, + (unsigned long)curr[i], + NULL); + + return ret; +} + +static int pm_qos_enabled_get(char *buffer, const struct kernel_param *kp) +{ + return param_get_bool(buffer, kp); +} + +static struct kernel_param_ops pm_qos_enabled_ops = { + .set = pm_qos_enabled_set, + .get = pm_qos_enabled_get, +}; +module_param_cb(enable, &pm_qos_enabled_ops, &pm_qos_enabled, 0644); + /** * pm_qos_add_notifier - sets notification entry for changes to target value * @pm_qos_class: identifies which qos target changes should be notified. |