summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Boonstoppel <pboonstoppel@nvidia.com>2017-05-18 17:54:43 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-07-05 12:59:05 -0400
commitfd6458bae3729e8611f8e8656bef4554a6a76115 (patch)
tree26d88b8a30c3b0b334feaa1b17f82c770f4e8570
parentc479079b0f0610d520b7d253571876bdaf79d78a (diff)
devfreq: stop podgov polling when disabled through sysfs
The pod governor allows scaling to be enabled/disabled through sysfs. In the current implementation the devfreq_monitor keeps polling periodically even when scaling is disabled. This patch disables the timer when scaling is disabled. NVGPU-20 Change-Id: I6842585afec48dbc9a2fe5aee96867c68612a127 Signed-off-by: Peter Boonstoppel <pboonstoppel@nvidia.com> Reviewed-on: https://git-master/r/1485185 (cherry picked from linux-4.9 commit 96ebb9e97b84092a852274f90e214d3976944b78) Reviewed-on: https://git-master.nvidia.com/r/1770152 Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Timo Alho <talho@nvidia.com> Tested-by: Timo Alho <talho@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/devfreq/governor_pod_scaling.c75
1 files changed, 46 insertions, 29 deletions
diff --git a/drivers/devfreq/governor_pod_scaling.c b/drivers/devfreq/governor_pod_scaling.c
index d7a470957..8f596cb02 100644
--- a/drivers/devfreq/governor_pod_scaling.c
+++ b/drivers/devfreq/governor_pod_scaling.c
@@ -84,6 +84,8 @@ struct podgov_info_rec {
84 struct kobj_attribute enable_3d_scaling_attr; 84 struct kobj_attribute enable_3d_scaling_attr;
85 struct kobj_attribute user_attr; 85 struct kobj_attribute user_attr;
86 struct kobj_attribute freq_request_attr; 86 struct kobj_attribute freq_request_attr;
87
88 struct mutex lock;
87}; 89};
88 90
89/******************************************************************************* 91/*******************************************************************************
@@ -127,42 +129,50 @@ static void scaling_limit(struct devfreq *df, unsigned long *freq)
127static void podgov_enable(struct devfreq *df, int enable) 129static void podgov_enable(struct devfreq *df, int enable)
128{ 130{
129 struct device *dev = df->dev.parent; 131 struct device *dev = df->dev.parent;
130 struct podgov_info_rec *podgov; 132 struct podgov_info_rec *podgov = df->data;
133 bool polling;
131 134
132 /* make sure the device is alive before doing any scaling */ 135 /* make sure the device is alive before doing any scaling */
133 pm_runtime_get_noresume(dev); 136 pm_runtime_get_noresume(dev);
134 137
138 mutex_lock(&podgov->lock);
135 mutex_lock(&df->lock); 139 mutex_lock(&df->lock);
136 140
137 podgov = df->data;
138
139 trace_podgov_enabled(df->dev.parent, enable); 141 trace_podgov_enabled(df->dev.parent, enable);
140 142
141 /* bad configuration. quit. */ 143 /* bad configuration. quit. */
142 if (df->min_freq == df->max_freq) 144 if (df->min_freq == df->max_freq) {
143 goto exit_unlock; 145 mutex_unlock(&df->lock);
146 mutex_unlock(&podgov->lock);
147 pm_runtime_put(dev);
148 return;
149 }
144 150
145 /* store the enable information */ 151 /* store the enable information */
146 podgov->enable = enable; 152 podgov->enable = enable;
147 153
148 /* skip local adjustment if we are enabling or the device is 154 /* skip local adjustment if we are enabling or the device is
149 * suspended */ 155 * suspended */
150 if (enable || !pm_runtime_active(dev)) 156 if (!enable && pm_runtime_active(dev)) {
151 goto exit_unlock; 157 /* full speed */
158 podgov->adjustment_frequency = df->max_freq;
159 podgov->adjustment_type = ADJUSTMENT_LOCAL;
160 update_devfreq(df);
161 }
152 162
153 /* full speed */ 163 polling = podgov->enable && !podgov->p_user;
154 podgov->adjustment_frequency = df->max_freq;
155 podgov->adjustment_type = ADJUSTMENT_LOCAL;
156 update_devfreq(df);
157 164
165 /* Need to unlock to call devfreq_monitor_suspend/resume()
166 * still holding podgov->lock to guarantee atomicity
167 */
158 mutex_unlock(&df->lock); 168 mutex_unlock(&df->lock);
159 169
160 pm_runtime_put(dev); 170 if (polling)
161 171 devfreq_monitor_resume(df);
162 return; 172 else
173 devfreq_monitor_suspend(df);
163 174
164exit_unlock: 175 mutex_unlock(&podgov->lock);
165 mutex_unlock(&df->lock);
166 pm_runtime_put(dev); 176 pm_runtime_put(dev);
167} 177}
168 178
@@ -177,14 +187,15 @@ exit_unlock:
177static void podgov_set_user_ctl(struct devfreq *df, int user) 187static void podgov_set_user_ctl(struct devfreq *df, int user)
178{ 188{
179 struct device *dev = df->dev.parent; 189 struct device *dev = df->dev.parent;
180 struct podgov_info_rec *podgov; 190 struct podgov_info_rec *podgov = df->data;
181 int old_user; 191 int old_user;
192 bool polling;
182 193
183 /* make sure the device is alive before doing any scaling */ 194 /* make sure the device is alive before doing any scaling */
184 pm_runtime_get_noresume(dev); 195 pm_runtime_get_noresume(dev);
185 196
197 mutex_lock(&podgov->lock);
186 mutex_lock(&df->lock); 198 mutex_lock(&df->lock);
187 podgov = df->data;
188 199
189 trace_podgov_set_user_ctl(df->dev.parent, user); 200 trace_podgov_set_user_ctl(df->dev.parent, user);
190 201
@@ -194,22 +205,26 @@ static void podgov_set_user_ctl(struct devfreq *df, int user)
194 205
195 /* skip scaling, if scaling (or the whole device) is turned off 206 /* skip scaling, if scaling (or the whole device) is turned off
196 * - or the scaling already was in user mode */ 207 * - or the scaling already was in user mode */
197 if (!pm_runtime_active(dev) || !podgov->enable || 208 if (pm_runtime_active(dev) && podgov->enable && user && !old_user) {
198 !(user && !old_user)) 209 /* write request */
199 goto exit_unlock; 210 podgov->adjustment_frequency = podgov->p_freq_request;
211 podgov->adjustment_type = ADJUSTMENT_LOCAL;
212 update_devfreq(df);
213 }
200 214
201 /* write request */ 215 polling = podgov->enable && !podgov->p_user;
202 podgov->adjustment_frequency = podgov->p_freq_request;
203 podgov->adjustment_type = ADJUSTMENT_LOCAL;
204 update_devfreq(df);
205 216
217 /* Need to unlock to call devfreq_monitor_suspend/resume()
218 * still holding podgov->lock to guarantee atomicity
219 */
206 mutex_unlock(&df->lock); 220 mutex_unlock(&df->lock);
207 pm_runtime_put(dev);
208 221
209 return; 222 if (polling)
223 devfreq_monitor_resume(df);
224 else
225 devfreq_monitor_suspend(df);
210 226
211exit_unlock: 227 mutex_unlock(&podgov->lock);
212 mutex_unlock(&df->lock);
213 pm_runtime_put(dev); 228 pm_runtime_put(dev);
214} 229}
215 230
@@ -622,6 +637,8 @@ static int nvhost_pod_init(struct devfreq *df)
622 637
623 podgov->power_manager = df; 638 podgov->power_manager = df;
624 639
640 mutex_init(&podgov->lock);
641
625 attr = &podgov->enable_3d_scaling_attr; 642 attr = &podgov->enable_3d_scaling_attr;
626 attr->attr.name = "enable_3d_scaling"; 643 attr->attr.name = "enable_3d_scaling";
627 attr->attr.mode = S_IWUSR | S_IRUGO; 644 attr->attr.mode = S_IWUSR | S_IRUGO;