Loading drivers/devfreq/governor_memlat.c +71 −1 Original line number Diff line number Diff line /* * 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 Loading Loading @@ -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); Loading Loading @@ -212,6 +213,39 @@ static int gov_start(struct devfreq *df) 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; Loading @@ -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++) { Loading Loading @@ -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 Loading
drivers/devfreq/governor_memlat.c +71 −1 Original line number Diff line number Diff line /* * 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 Loading Loading @@ -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); Loading Loading @@ -212,6 +213,39 @@ static int gov_start(struct devfreq *df) 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; Loading @@ -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++) { Loading Loading @@ -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