summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Fleury <tfleury@nvidia.com>2017-09-18 20:38:06 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-29 14:00:51 -0400
commit0a93373364f8520e552f96b7e8fc22a5917f83ea (patch)
treec73fc8f977a07cc7aa2a8d0f07b1039441b21e06
parentca92c1f400f26703643251bc0052d9a23f60bd03 (diff)
gpu: nvgpu: disable IRQs before preparing powering down
Disable IRQs and wait for completion before preparing powering down. This avoids concurrency with threaded interrupts. JIRA EVLR-1852 Change-Id: Iab4cfb0e796b5748430d38daa2a3be8c03b10fff Signed-off-by: Thomas Fleury <tfleury@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1563896 GVS: Gerrit_Virtual_Submit Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c
index e7e79949..68ae1a66 100644
--- a/drivers/gpu/nvgpu/common/linux/module.c
+++ b/drivers/gpu/nvgpu/common/linux/module.c
@@ -268,6 +268,7 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
268 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 268 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
269 int ret = 0; 269 int ret = 0;
270 struct gk20a_platform *platform = gk20a_get_platform(dev); 270 struct gk20a_platform *platform = gk20a_get_platform(dev);
271 bool irqs_enabled;
271 272
272 gk20a_dbg_fn(""); 273 gk20a_dbg_fn("");
273 274
@@ -276,6 +277,15 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
276 if (!g->power_on) 277 if (!g->power_on)
277 goto done; 278 goto done;
278 279
280 /* disable IRQs and wait for completion */
281 irqs_enabled = g->irqs_enabled;
282 if (irqs_enabled) {
283 disable_irq(g->irq_stall);
284 if (g->irq_stall != g->irq_nonstall)
285 disable_irq(g->irq_nonstall);
286 g->irqs_enabled = 0;
287 }
288
279 gk20a_scale_suspend(dev); 289 gk20a_scale_suspend(dev);
280 290
281 gk20a_cde_suspend(l); 291 gk20a_cde_suspend(l);
@@ -284,17 +294,6 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
284 if (ret) 294 if (ret)
285 goto error; 295 goto error;
286 296
287 /*
288 * After this point, gk20a interrupts should not get
289 * serviced.
290 */
291 if (g->irqs_enabled) {
292 disable_irq(g->irq_stall);
293 if (g->irq_stall != g->irq_nonstall)
294 disable_irq(g->irq_nonstall);
295 g->irqs_enabled = 0;
296 }
297
298 /* Decrement platform power refcount */ 297 /* Decrement platform power refcount */
299 if (platform->idle) 298 if (platform->idle)
300 platform->idle(dev); 299 platform->idle(dev);
@@ -306,6 +305,14 @@ static int gk20a_pm_prepare_poweroff(struct device *dev)
306 return 0; 305 return 0;
307 306
308error: 307error:
308 /* re-enabled IRQs if previously enabled */
309 if (irqs_enabled) {
310 enable_irq(g->irq_stall);
311 if (g->irq_stall != g->irq_nonstall)
312 enable_irq(g->irq_nonstall);
313 g->irqs_enabled = 1;
314 }
315
309 gk20a_scale_resume(dev); 316 gk20a_scale_resume(dev);
310done: 317done:
311 nvgpu_mutex_release(&g->poweroff_lock); 318 nvgpu_mutex_release(&g->poweroff_lock);