* pass_governor_change_level_scope - Change the scope of pass level
*
* @policy: the instance of struct pass_policy
+ * @new_level: the desirous pass level
* @min_level: the minimum pass level
* @max_level: the maximum pass level
*/
int pass_governor_change_level_scope(struct pass_policy *policy,
- int min_level, int max_level)
+ int new_level, int min_level, int max_level)
{
if (!policy)
return -EINVAL;
policy->min_level = min_level;
policy->max_level = max_level;
- pass_governor_change_level(policy, policy->curr_level);
+ pass_governor_change_level(policy, new_level);
return 0;
}
* pass_notifier_pmqos - Callback function of DEVICE_NOTIFIER_PMQOS notifier
* @data: the scenario name
*/
+#define MAX(a,b) (a > b ? a : b)
int pass_notifier_pmqos_func(struct pass_policy *policy, void *data)
{
struct pass_resource *pass_res = to_pass_resource(policy);
struct pass_scenario *scn = NULL;
enum pass_state locked = PASS_UNUSED;
char name[PASS_NAME_LEN] = {""};
+ unsigned int new_level = 0;
unsigned int min_level = 0;
unsigned int max_level = 0;
int count = 0;
name, locked ? "Locked" : "Unlocked");
return 0;
}
- scenario->list[index].locked = locked;
-
- /* Change scaling scope according to scenario's level */
- for (i = 0; i < scenario->num_scenarios; i++) {
- struct pass_scenario *scn = &scenario->list[i];
-
- if (is_scenario_locked(scn)) {
- if (scn->min_level > min_level)
- min_level = scn->min_level;
- if (scn->max_level > max_level)
- max_level = scn->max_level;
- count++;
+ scn->locked = locked;
+
+ if (scn->locked) {
+ if (scenario->num_locked_scenarios == 0)
+ new_level = scenario->init_level = policy->curr_level;
+ else
+ new_level = scenario->curr_level;
+ min_level = MAX(scn->min_level, scenario->min_level);
+ max_level = MAX(scn->max_level, scenario->max_level);
+
+ if (new_level < min_level)
+ new_level = min_level;
+ else if (new_level > max_level)
+ new_level = scn->max_level;
+
+ scenario->curr_level = new_level;
+ scenario->min_level = min_level;
+ scenario->max_level = max_level;
+
+ scenario->num_locked_scenarios++;
+ } else {
+ scenario->num_locked_scenarios--;
+
+ if (scenario->num_locked_scenarios == 0) {
+ new_level = scenario->init_level;
+ min_level = policy->default_min_level;
+ max_level = policy->default_max_level;
+
+ scenario->curr_level = 0;
+ scenario->min_level = 0;
+ scenario->max_level = 0;
+ } else {
+ new_level = scenario->curr_level;
+ min_level = scenario->min_level;
+ max_level = scenario->max_level;
}
}
- /*
- * Restore default min/max level if all scenarios hasn't locked state.
- */
- if (!is_scenario_locked(scn) && !count) {
- min_level = policy->default_min_level;
- max_level = policy->default_max_level;
- }
-
- pass_governor_change_level_scope(policy, min_level, max_level);
+ pass_governor_change_level_scope(policy, new_level, min_level, max_level);
- if (locked) {
+ if (scn->locked) {
_I("Lock '%s' scenario for '%s' resource\n",
name, cdata->res_name);