diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c index c2bd9d78e..b12917d68 100644 --- a/drivers/gpu/nvgpu/common/linux/driver_common.c +++ b/drivers/gpu/nvgpu/common/linux/driver_common.c @@ -50,6 +50,7 @@ static void nvgpu_init_vars(struct gk20a *g) nvgpu_mutex_init(&platform->railgate_lock); nvgpu_mutex_init(&g->dbg_sessions_lock); nvgpu_mutex_init(&g->client_lock); + nvgpu_mutex_init(&g->poweron_lock); nvgpu_mutex_init(&g->poweroff_lock); g->regs_saved = g->regs; diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index b107a7213..0b5dfec83 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c @@ -88,15 +88,18 @@ int gk20a_busy(struct gk20a *g) goto fail; } } else { + nvgpu_mutex_acquire(&g->poweron_lock); if (!g->power_on) { ret = gk20a_gpu_is_virtual(dev) ? vgpu_pm_finalize_poweron(dev) : gk20a_pm_finalize_poweron(dev); if (ret) { atomic_dec(&g->usage_count); + nvgpu_mutex_release(&g->poweron_lock); goto fail; } } + nvgpu_mutex_release(&g->poweron_lock); } fail: diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 9203882cf..d45477fc1 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1075,6 +1075,7 @@ struct gk20a { #endif unsigned int ch_wdt_timeout_ms; + struct nvgpu_mutex poweron_lock; struct nvgpu_mutex poweroff_lock; /* Channel priorities */ diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index f02acad08..bd52dc0a6 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -243,6 +243,7 @@ static void vgpu_remove_support(struct gk20a *g) static void vgpu_init_vars(struct gk20a *g, struct gk20a_platform *platform) { + nvgpu_mutex_init(&g->poweron_lock); nvgpu_mutex_init(&g->poweroff_lock); g->regs_saved = g->regs; g->bar1_saved = g->bar1;