mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
devfreq: memlat: Add suspend/resume for mem_latency
Add suspend/resume support for the mem_latency governor. Uses hwmon driver- defined suspend/resume calls in addition to monitor start/stop calls within the devfreq framework. Change-Id: I900b322a05cd0312f082d70640e21851879cb18c Signed-off-by: Jonathan Avila <avilaj@codeaurora.org>
This commit is contained in:
parent
8c5ca64d7e
commit
5a6ca65348
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2018, The Linux Foundation. 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 version 2 and
|
||||
@ -43,6 +43,7 @@ struct memlat_node {
|
||||
struct memlat_hwmon *hw;
|
||||
struct devfreq_governor *gov;
|
||||
struct attribute_group *attr_grp;
|
||||
unsigned long resume_freq;
|
||||
};
|
||||
|
||||
static LIST_HEAD(memlat_list);
|
||||
@ -212,6 +213,39 @@ err_start:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gov_suspend(struct devfreq *df)
|
||||
{
|
||||
struct memlat_node *node = df->data;
|
||||
unsigned long prev_freq = df->previous_freq;
|
||||
|
||||
node->mon_started = false;
|
||||
devfreq_monitor_suspend(df);
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
update_devfreq(df);
|
||||
mutex_unlock(&df->lock);
|
||||
|
||||
node->resume_freq = max(prev_freq, 1UL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gov_resume(struct devfreq *df)
|
||||
{
|
||||
struct memlat_node *node = df->data;
|
||||
|
||||
mutex_lock(&df->lock);
|
||||
update_devfreq(df);
|
||||
mutex_unlock(&df->lock);
|
||||
|
||||
node->resume_freq = 0;
|
||||
|
||||
devfreq_monitor_resume(df);
|
||||
node->mon_started = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gov_stop(struct devfreq *df)
|
||||
{
|
||||
struct memlat_node *node = df->data;
|
||||
@ -233,6 +267,18 @@ static int devfreq_memlat_get_freq(struct devfreq *df,
|
||||
unsigned long max_freq = 0;
|
||||
unsigned int ratio;
|
||||
|
||||
/*
|
||||
* node->resume_freq is set to 0 at the end of resume (after the update)
|
||||
* and is set to df->prev_freq at the end of suspend (after the update).
|
||||
* This function will be called as part of the update_devfreq call in
|
||||
* both scenarios. As a result, this block will cause a 0 vote during
|
||||
* suspend and a vote for df->prev_freq during resume.
|
||||
*/
|
||||
if (!node->mon_started) {
|
||||
*freq = node->resume_freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
hw->get_cnt(hw);
|
||||
|
||||
for (i = 0; i < hw->num_cores; i++) {
|
||||
@ -331,6 +377,30 @@ static int devfreq_memlat_ev_handler(struct devfreq *df,
|
||||
"Disabled Memory Latency governor\n");
|
||||
break;
|
||||
|
||||
case DEVFREQ_GOV_SUSPEND:
|
||||
ret = gov_suspend(df);
|
||||
if (ret) {
|
||||
dev_err(df->dev.parent,
|
||||
"Unable to suspend memlat governor (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(df->dev.parent, "Suspended memlat governor\n");
|
||||
break;
|
||||
|
||||
case DEVFREQ_GOV_RESUME:
|
||||
ret = gov_resume(df);
|
||||
if (ret) {
|
||||
dev_err(df->dev.parent,
|
||||
"Unable to resume memlat governor (%d)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(df->dev.parent, "Resumed memlat governor\n");
|
||||
break;
|
||||
|
||||
case DEVFREQ_GOV_INTERVAL:
|
||||
sample_ms = *(unsigned int *)data;
|
||||
sample_ms = max(MIN_MS, sample_ms);
|
||||
|
Loading…
x
Reference in New Issue
Block a user