diff options
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 29 |
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 | ||
308 | error: | 307 | error: |
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); |
310 | done: | 317 | done: |
311 | nvgpu_mutex_release(&g->poweroff_lock); | 318 | nvgpu_mutex_release(&g->poweroff_lock); |