diff --git a/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c b/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c index d4175c683..5d3599229 100644 --- a/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c +++ b/drivers/gpu/nvgpu/common/gsp/gsp_bootstrap.c @@ -32,21 +32,17 @@ #include #endif -static void gsp_release_firmware(struct gk20a *g, struct nvgpu_gsp *gsp) +void gsp_release_firmware(struct gk20a *g, struct nvgpu_gsp *gsp) { - if (gsp->gsp_ucode.manifest != NULL) { - nvgpu_release_firmware(g, gsp->gsp_ucode.manifest); - } - - if (gsp->gsp_ucode.code != NULL) { - nvgpu_release_firmware(g, gsp->gsp_ucode.code); - } - - if (gsp->gsp_ucode.data != NULL) { - nvgpu_release_firmware(g, gsp->gsp_ucode.data); - } + nvgpu_release_firmware(g, gsp->gsp_ucode.manifest); + gsp->gsp_ucode.manifest = NULL; + nvgpu_release_firmware(g, gsp->gsp_ucode.code); + gsp->gsp_ucode.code = NULL; + nvgpu_release_firmware(g, gsp->gsp_ucode.data); + gsp->gsp_ucode.data = NULL; } + static int gsp_read_firmware(struct gk20a *g, struct nvgpu_gsp *gsp, struct gsp_fw *gsp_ucode) { @@ -56,22 +52,27 @@ static int gsp_read_firmware(struct gk20a *g, struct nvgpu_gsp *gsp, nvgpu_log_fn(g, " "); + if ((gsp_ucode->manifest != NULL) && (gsp_ucode->code != NULL) + && (gsp_ucode->data != NULL)) { + return 0; + } + gsp_ucode->manifest = nvgpu_request_firmware(g, - manifest_name, NVGPU_REQUEST_FIRMWARE_NO_WARN); + manifest_name, 0); if (gsp_ucode->manifest == NULL) { nvgpu_err(g, "%s ucode get failed", manifest_name); goto fw_release; } gsp_ucode->code = nvgpu_request_firmware(g, - code_name, NVGPU_REQUEST_FIRMWARE_NO_WARN); + code_name, 0); if (gsp_ucode->code == NULL) { nvgpu_err(g, "%s ucode get failed", code_name); goto fw_release; } gsp_ucode->data = nvgpu_request_firmware(g, - data_name, NVGPU_REQUEST_FIRMWARE_NO_WARN); + data_name, 0); if (gsp_ucode->data == NULL) { nvgpu_err(g, "%s ucode get failed", data_name); goto fw_release; @@ -237,8 +238,11 @@ int nvgpu_gsp_bootstrap_ns(struct gk20a *g, struct nvgpu_gsp *gsp) err = nvgpu_falcon_wait_for_nvriscv_brom_completion(flcn); if (err != 0) { nvgpu_err(g, "gsp BROM failed"); + goto exit; } + return err; + exit: gsp_release_firmware(g, gsp); return err; diff --git a/drivers/gpu/nvgpu/common/gsp/gsp_init.c b/drivers/gpu/nvgpu/common/gsp/gsp_init.c index 71175922d..a26fa9b84 100644 --- a/drivers/gpu/nvgpu/common/gsp/gsp_init.c +++ b/drivers/gpu/nvgpu/common/gsp/gsp_init.c @@ -62,6 +62,7 @@ void nvgpu_gsp_sw_deinit(struct gk20a *g, struct nvgpu_gsp *gsp) nvgpu_falcon_dbg_buf_destroy(gsp->gsp_flcn); #endif + gsp_release_firmware(g, gsp); nvgpu_kfree(g, gsp); gsp = NULL; } diff --git a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c index a0fcd5075..dcec4ddc9 100644 --- a/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c +++ b/drivers/gpu/nvgpu/common/gsp_scheduler/gsp_scheduler.c @@ -59,6 +59,7 @@ void nvgpu_gsp_sched_suspend(struct gk20a *g, struct nvgpu_gsp_sched *gsp_sched) } gsp_sched->gsp_ready = false; + nvgpu_gsp_queues_free(g, g->gsp_sched->queues); nvgpu_gsp_suspend(g, gsp); } diff --git a/drivers/gpu/nvgpu/include/nvgpu/gsp.h b/drivers/gpu/nvgpu/include/nvgpu/gsp.h index 8dca3406b..d8abea880 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gsp.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gsp.h @@ -57,6 +57,7 @@ struct nvgpu_gsp { int nvgpu_gsp_debug_buf_init(struct gk20a *g, u32 queue_no, u32 buffer_size); void nvgpu_gsp_suspend(struct gk20a *g, struct nvgpu_gsp *gsp); +void gsp_release_firmware(struct gk20a *g, struct nvgpu_gsp *gsp); void nvgpu_gsp_sw_deinit(struct gk20a *g, struct nvgpu_gsp *gsp); void nvgpu_gsp_isr_mutex_acquire(struct gk20a *g, struct nvgpu_gsp *gsp); void nvgpu_gsp_isr_mutex_release(struct gk20a *g, struct nvgpu_gsp *gsp);