diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index afc32bb39..6882a009b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -1850,7 +1850,7 @@ struct gk20a { struct nvgpu_cond sw_irq_nonstall_last_handled_cond; nvgpu_atomic_t sw_irq_nonstall_last_handled; - int irqs_enabled; + bool irqs_enabled; u32 irq_stall; /* can be same as irq_nonstall in case of PCI */ u32 irq_nonstall; diff --git a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_init.h b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_init.h index e9b664106..a3b5fcc99 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/nvgpu_init.h +++ b/drivers/gpu/nvgpu/include/nvgpu/nvgpu_init.h @@ -136,6 +136,15 @@ void nvgpu_sw_quiesce(struct gk20a *g); */ void nvgpu_start_gpu_idle(struct gk20a *g); +/** + * @brief Enable interrupt handlers + * + * @param g [in] The GPU + * + * Enable interrupt handlers. + */ +int nvgpu_enable_irqs(struct gk20a *g); + /** * @brief Disable interrupt handlers * diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index 061c7e3d7..dd0b58951 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -487,10 +487,11 @@ int gk20a_pm_finalize_poweron(struct device *dev) trace_gk20a_finalize_poweron_done(dev_name(dev)); #endif - enable_irq(g->irq_stall); - if (g->irq_stall != g->irq_nonstall) - enable_irq(g->irq_nonstall); - g->irqs_enabled = 1; + err = nvgpu_enable_irqs(g); + if (err) { + nvgpu_err(g, "failed to enable irqs %d", err); + goto done; + } gk20a_scale_resume(dev_from_gk20a(g)); @@ -534,13 +535,25 @@ static int gk20a_lockout_registers(struct gk20a *g) return 0; } +int nvgpu_enable_irqs(struct gk20a *g) +{ + if (!g->irqs_enabled) { + enable_irq(g->irq_stall); + if (g->irq_stall != g->irq_nonstall) + enable_irq(g->irq_nonstall); + g->irqs_enabled = true; + } + + return 0; +} + void nvgpu_disable_irqs(struct gk20a *g) { 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; + g->irqs_enabled = false; } } @@ -552,7 +565,7 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) #endif struct gk20a_platform *platform = gk20a_get_platform(dev); bool irqs_enabled; - int ret = 0; + int ret = 0, err = 0; nvgpu_log_fn(g, " "); @@ -589,10 +602,10 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) 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; + err = nvgpu_enable_irqs(g); + if (err) { + nvgpu_err(g, "failed to enable irqs %d", err); + } } gk20a_scale_resume(dev); diff --git a/drivers/gpu/nvgpu/os/posix/nvgpu.c b/drivers/gpu/nvgpu/os/posix/nvgpu.c index 94ebde131..059373b54 100644 --- a/drivers/gpu/nvgpu/os/posix/nvgpu.c +++ b/drivers/gpu/nvgpu/os/posix/nvgpu.c @@ -63,6 +63,11 @@ void nvgpu_start_gpu_idle(struct gk20a *g) nvgpu_set_enabled(g, NVGPU_DRIVER_IS_DYING, true); } +int nvgpu_enable_irqs(struct gk20a *g) +{ + return 0; +} + void nvgpu_disable_irqs(struct gk20a *g) { }