From 0a93373364f8520e552f96b7e8fc22a5917f83ea Mon Sep 17 00:00:00 2001 From: Thomas Fleury Date: Mon, 18 Sep 2017 17:38:06 -0700 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1563896 GVS: Gerrit_Virtual_Submit Reviewed-by: Deepak Nibade Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/module.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/nvgpu/common/linux/module.c') 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) struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); int ret = 0; struct gk20a_platform *platform = gk20a_get_platform(dev); + bool irqs_enabled; gk20a_dbg_fn(""); @@ -276,6 +277,15 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) if (!g->power_on) goto done; + /* disable IRQs and wait for completion */ + irqs_enabled = g->irqs_enabled; + if (irqs_enabled) { + disable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + disable_irq(g->irq_nonstall); + g->irqs_enabled = 0; + } + gk20a_scale_suspend(dev); gk20a_cde_suspend(l); @@ -284,17 +294,6 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) if (ret) goto error; - /* - * After this point, gk20a interrupts should not get - * serviced. - */ - if (g->irqs_enabled) { - disable_irq(g->irq_stall); - if (g->irq_stall != g->irq_nonstall) - disable_irq(g->irq_nonstall); - g->irqs_enabled = 0; - } - /* Decrement platform power refcount */ if (platform->idle) platform->idle(dev); @@ -306,6 +305,14 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) return 0; error: + /* re-enabled IRQs if previously enabled */ + if (irqs_enabled) { + enable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + enable_irq(g->irq_nonstall); + g->irqs_enabled = 1; + } + gk20a_scale_resume(dev); done: nvgpu_mutex_release(&g->poweroff_lock); -- cgit v1.2.2