diff options
author | Peter Boonstoppel <pboonstoppel@nvidia.com> | 2017-05-18 17:54:43 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-07-05 12:59:05 -0400 |
commit | fd6458bae3729e8611f8e8656bef4554a6a76115 (patch) | |
tree | 26d88b8a30c3b0b334feaa1b17f82c770f4e8570 | |
parent | c479079b0f0610d520b7d253571876bdaf79d78a (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.c | 75 |
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) | |||
127 | static void podgov_enable(struct devfreq *df, int enable) | 129 | static 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 | ||
164 | exit_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: | |||
177 | static void podgov_set_user_ctl(struct devfreq *df, int user) | 187 | static 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 | ||
211 | exit_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; |