diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 0982ecdf4..1000eba2d 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -669,6 +669,7 @@ static int gk20a_init_support(struct platform_device *dev) mutex_init(&g->dbg_sessions_lock); mutex_init(&g->client_lock); mutex_init(&g->ch_wdt_lock); + mutex_init(&g->poweroff_lock); mutex_init(&g->interleave_lock); g->num_interleaved_channels = 0; @@ -689,17 +690,19 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) gk20a_dbg_fn(""); - gk20a_scale_suspend(pdev); + mutex_lock(&g->poweroff_lock); if (!g->power_on) - return 0; + goto done; + + gk20a_scale_suspend(pdev); /* cancel any pending cde work */ gk20a_cde_suspend(g); ret = gk20a_channel_suspend(g); if (ret) - return ret; + goto done; /* disable elpg before gr or fifo suspend */ ret |= gk20a_pmu_destroy(g); @@ -723,6 +726,9 @@ static int gk20a_pm_prepare_poweroff(struct device *dev) /* Stop CPU from accessing the GPU registers. */ gk20a_lockout_registers(g); +done: + mutex_unlock(&g->poweroff_lock); + return ret; } diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index b02d61118..0207588fd 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -521,6 +521,8 @@ struct gk20a { struct mutex ch_wdt_lock; + struct mutex poweroff_lock; + /* Channel priorities */ u32 timeslice_low_priority_us; u32 timeslice_medium_priority_us;