diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c index 983a82f96..8543196bb 100644 --- a/drivers/gpu/nvgpu/clk/clk_arb.c +++ b/drivers/gpu/nvgpu/clk/clk_arb.c @@ -750,12 +750,20 @@ error_check: int nvgpu_clk_arb_init_arbiter(struct gk20a *g) { + int err = 0; + if (!g->ops.clk.support_clk_freq_controller || !g->ops.clk_arb.get_arbiter_clk_domains) { return 0; } - return g->ops.clk_arb.arbiter_clk_init(g); + nvgpu_mutex_acquire(&g->clk_arb_enable_lock); + + err = g->ops.clk_arb.arbiter_clk_init(g); + + nvgpu_mutex_release(&g->clk_arb_enable_lock); + + return err; } void nvgpu_clk_arb_send_thermal_alarm(struct gk20a *g) @@ -783,10 +791,14 @@ void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g) { struct nvgpu_clk_arb *arb = g->clk_arb; + nvgpu_mutex_acquire(&g->clk_arb_enable_lock); + if (arb) { nvgpu_clk_arb_worker_deinit(g); g->ops.clk_arb.clk_arb_cleanup(g->clk_arb); } + + nvgpu_mutex_release(&g->clk_arb_enable_lock); } int nvgpu_clk_arb_init_session(struct gk20a *g, diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index bdf3a168f..f62dfb940 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1588,6 +1588,8 @@ struct gk20a { struct nvgpu_clk_arb *clk_arb; + struct nvgpu_mutex clk_arb_enable_lock; + struct gk20a_ce_app ce_app; bool ltc_intr_en_illegal_compstat; diff --git a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c index 860344d06..001f2bfc0 100644 --- a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c +++ b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c @@ -121,6 +121,10 @@ int gp106_init_clk_arbiter(struct gk20a *g) clk_arb_dbg(g, " "); + if (g->clk_arb != NULL) { + return 0; + } + arb = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_arb)); if (!arb) return -ENOMEM; diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index 16af2cb09..b81cc90c2 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -65,6 +65,7 @@ static void nvgpu_init_vars(struct gk20a *g) nvgpu_mutex_init(&g->poweroff_lock); nvgpu_mutex_init(&g->ctxsw_disable_lock); nvgpu_mutex_init(&g->tpc_pg_lock); + nvgpu_mutex_init(&g->clk_arb_enable_lock); l->regs_saved = l->regs; l->bar1_saved = l->bar1; diff --git a/drivers/gpu/nvgpu/os/linux/module.c b/drivers/gpu/nvgpu/os/linux/module.c index cb5016835..d226ceeb9 100644 --- a/drivers/gpu/nvgpu/os/linux/module.c +++ b/drivers/gpu/nvgpu/os/linux/module.c @@ -1310,6 +1310,8 @@ int nvgpu_remove(struct device *dev, struct class *class) if (platform->remove) platform->remove(dev); + nvgpu_mutex_destroy(&g->clk_arb_enable_lock); + nvgpu_log_fn(g, "removed"); return err;