From 29440602f3fc2b4b7289fce2f539d9d97cb1e04d Mon Sep 17 00:00:00 2001 From: Arto Merilainen Date: Sun, 19 Apr 2015 19:05:05 +0300 Subject: [PATCH] devfreq: Improve wmark_active initialization The wmark_active governor initialization assumes that the device frequency is the lowest possible frequency when the governor is started or resumed. However, this may not be correct if the governor was suspended/stopped before the clock had been slowed down. This patch modifies the governor to read the frequency during governor initialization and resume. Change-Id: I38d3256102b344bc8818c5623a015843678a8ce5 Signed-off-by: Arto Merilainen Reviewed-on: http://git-master/r/733007 Reviewed-on: http://git-master/r/1160009 (cherry picked from linux-4.9 commit 32e2561dffc5d7390fa4fd503651da9013403ecb) Reviewed-on: https://git-master.nvidia.com/r/1770141 Reviewed-by: Mikko Perttunen GVS: Gerrit_Virtual_Submit Reviewed-by: Timo Alho Tested-by: Timo Alho Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/devfreq/governor_wmark_active.c | 31 +++++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/drivers/devfreq/governor_wmark_active.c b/drivers/devfreq/governor_wmark_active.c index c617271f..7dc020dd 100644 --- a/drivers/devfreq/governor_wmark_active.c +++ b/drivers/devfreq/governor_wmark_active.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -233,33 +233,44 @@ static int devfreq_watermark_event_handler(struct devfreq *df, unsigned int event, void *wmark_type) { int ret = 0; - struct wmark_gov_info *wmarkinfo = df->data; switch (event) { case DEVFREQ_GOV_START: - devfreq_watermark_start(df); - wmarkinfo = df->data; - update_watermarks(df, wmarkinfo->freqlist[0]); + { + struct devfreq_dev_status dev_stat; + ret = df->profile->get_dev_status(df->dev.parent, &dev_stat); + if (ret < 0) + break; + + ret = devfreq_watermark_start(df); + if (ret < 0) + break; + + update_watermarks(df, dev_stat.current_frequency); break; + } case DEVFREQ_GOV_STOP: devfreq_watermark_debug_stop(df); break; case DEVFREQ_GOV_SUSPEND: devfreq_monitor_suspend(df); break; - case DEVFREQ_GOV_RESUME: - wmarkinfo = df->data; - update_watermarks(df, wmarkinfo->freqlist[0]); + { + struct devfreq_dev_status dev_stat; + ret = df->profile->get_dev_status(df->dev.parent, &dev_stat); + if (ret < 0) + break; + + update_watermarks(df, dev_stat.current_frequency); devfreq_monitor_resume(df); break; - + } case DEVFREQ_GOV_WMARK: mutex_lock(&df->lock); update_devfreq(df); mutex_unlock(&df->lock); break; - default: break; }