Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2914c152 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Delay firmware unload during session close"

parents 0bc3da06 1f97647f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -335,6 +335,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev,
		init_completion(&core->completions[i]);
	}

	INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
	return rc;
}

+56 −25
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <soc/qcom/subsystem_restart.h>
#include <asm/div64.h>
#include "msm_vidc_common.h"
@@ -2244,6 +2243,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst)
			goto fail_load_fw;
		}
		core->state = VIDC_CORE_LOADED;
		dprintk(VIDC_DBG, "Firmware downloaded\n");
	}
	mutex_unlock(&core->lock);

@@ -2281,7 +2281,6 @@ fail_vote_bus:

static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)
{
	int rc = 0;
	struct msm_vidc_core *core;
	struct hfi_device *hdev;

@@ -2305,35 +2304,22 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst)

	mutex_lock(&core->lock);
	if (list_empty(&core->instances)) {
		if (core->state > VIDC_CORE_INIT) {
			if (core->resources.ocmem_size) {
				if (inst->state != MSM_VIDC_CORE_INVALID)
					msm_comm_unset_ocmem(core);
				call_hfi_op(hdev, free_ocmem,
						hdev->hfi_device_data);
			}
			dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
			rc = call_hfi_op(hdev, core_release,
					hdev->hfi_device_data);
			if (rc) {
				dprintk(VIDC_ERR,
					"Failed to release core, id = %d\n",
					core->id);
				goto exit;
			}
		}
		cancel_delayed_work(&core->fw_unload_work);

		core->state = VIDC_CORE_UNINIT;

		call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
		msm_comm_unvote_buses(core);
		/*
		* Delay unloading of firmware for 10 sec. This is useful
		* in avoiding firmware download delays in cases where we
		* will have a burst of back to back video playback sessions
		* e.g. thumbnail generation.
		*/
		schedule_delayed_work(&core->fw_unload_work,
			msecs_to_jiffies(10000));
	}

core_already_uninited:
	change_inst_state(inst, MSM_VIDC_CORE_UNINIT);
exit:
	mutex_unlock(&core->lock);
	return rc;
	return 0;
}

int msm_comm_force_cleanup(struct msm_vidc_inst *inst)
@@ -4541,3 +4527,48 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst,
	return msm_smem_get_domain_partition(inst->mem_client, flags,
			buffer_type, domain_num, partition_num);
}

void msm_vidc_fw_unload_handler(struct work_struct *work)
{
	struct msm_vidc_core *core = NULL;
	struct hfi_device *hdev = NULL;
	int rc = 0;

	core = container_of(work, struct msm_vidc_core, fw_unload_work.work);
	if (!core || !core->device) {
		dprintk(VIDC_ERR, "%s - invalid work or core handle\n",
				__func__);
		return;
	}

	hdev = core->device;

	mutex_lock(&core->lock);
	if (list_empty(&core->instances) &&
		core->state != VIDC_CORE_UNINIT) {
		if (core->state > VIDC_CORE_INIT) {
			if (core->resources.ocmem_size) {
				if (core->state != VIDC_CORE_INVALID)
					msm_comm_unset_ocmem(core);
				call_hfi_op(hdev, free_ocmem,
						hdev->hfi_device_data);
			}
			dprintk(VIDC_DBG, "Calling vidc_hal_core_release\n");
			rc = call_hfi_op(hdev, core_release,
					hdev->hfi_device_data);
			if (rc) {
				dprintk(VIDC_ERR,
					"Failed to release core, id = %d\n",
					core->id);
				return;
			}
		}

		core->state = VIDC_CORE_UNINIT;

		call_hfi_op(hdev, unload_fw, hdev->hfi_device_data);
		dprintk(VIDC_DBG, "Firmware unloaded\n");
		msm_comm_unvote_buses(core);
	}
	mutex_unlock(&core->lock);
}
+3 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <linux/msm-bus.h>
#include <linux/msm-bus-board.h>
#include <soc/qcom/ocmem.h>
@@ -275,6 +276,7 @@ struct msm_vidc_core {
	u32 enc_codec_supported;
	u32 dec_codec_supported;
	struct msm_vidc_idle_stats idle_stats;
	struct delayed_work fw_unload_work;
};

struct msm_vidc_inst {
@@ -391,4 +393,5 @@ struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
				enum hal_buffer buffer_type);
int msm_smem_get_domain_partition(void *clt, u32 flags, enum hal_buffer
		buffer_type, int *domain_num, int *partition_num);
void msm_vidc_fw_unload_handler(struct work_struct *work);
#endif