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

Commit 6a324ce4 authored by Deva Ramasubramanian's avatar Deva Ramasubramanian
Browse files

msm: vidc: Clean up the instance prior to destroying it



_destroy() is only present to reference manage the instance, and not
necessarily to house any logic.  Hence clean up the instance in
_close().

As a side-effect, it also fixes a bug where we send instance-related
commands to firmware after the instance was invalidated.  Hence if
firmware responds back, we ignore the reponses since we think that the
session is no longer valid.

Change-Id: Ia03af3ad9ef9251eddd03bf53ac46ff52bd051de
Signed-off-by: default avatarDeva Ramasubramanian <dramasub@codeaurora.org>
parent 9f5234bb
Loading
Loading
Loading
Loading
+37 −39
Original line number Diff line number Diff line
@@ -1290,20 +1290,53 @@ static void cleanup_instance(struct msm_vidc_inst *inst)

int msm_vidc_destroy(struct msm_vidc_inst *inst)
{
	struct msm_vidc_inst *temp, *inst_dummy;
	struct msm_vidc_core *core;
	int i = 0;

	if (!inst || !inst->core)
		return -EINVAL;

	core = inst->core;

	v4l2_fh_del(&inst->event_handler);

	for (i = 0; i < MAX_PORT_NUM; i++)
		vb2_queue_release(&inst->bufq[i].vb2_bufq);

	mutex_lock(&core->lock);
	/* inst->list lives in core->instances */
	list_del(&inst->list);
	mutex_unlock(&core->lock);

	pr_info(VIDC_DBG_TAG "Closed video instance: %p\n",
			VIDC_MSG_PRIO2STRING(VIDC_INFO), inst);
	kfree(inst);
	return 0;
}

int msm_vidc_close(void *instance)
{
	void close_helper(struct kref *kref)
	{
		struct msm_vidc_inst *inst = container_of(kref,
				struct msm_vidc_inst, kref);

		msm_vidc_destroy(inst);
	}

	struct msm_vidc_inst *inst = instance;
	struct buffer_info *bi, *dummy;
	int rc = 0;
	int i;

	if (!inst || !inst->core)
		return -EINVAL;

	v4l2_fh_del(&inst->event_handler);

	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry_safe(bi, dummy, &inst->registeredbufs.list, list) {
		if (bi->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
			int i = 0;

			list_del(&bi->list);

			for (i = 0; i < min(bi->num_planes, VIDEO_MAX_PLANES);
@@ -1317,26 +1350,14 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
	}
	mutex_unlock(&inst->registeredbufs.lock);

	core = inst->core;

	mutex_lock(&core->lock);
	list_for_each_entry_safe(temp, inst_dummy, &core->instances, list) {
		if (temp == inst)
			list_del(&inst->list);
	}
	mutex_unlock(&core->lock);

	if (inst->session_type == MSM_VIDC_DECODER)
		msm_vdec_ctrl_deinit(inst);
	else if (inst->session_type == MSM_VIDC_ENCODER)
		msm_venc_ctrl_deinit(inst);

	for (i = 0; i < MAX_PORT_NUM; i++)
		vb2_queue_release(&inst->bufq[i].vb2_bufq);

	cleanup_instance(inst);
	if (inst->state != MSM_VIDC_CORE_INVALID &&
		core->state != VIDC_CORE_INVALID)
		inst->core->state != VIDC_CORE_INVALID)
		rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT);
	else
		rc = msm_comm_force_cleanup(inst);
@@ -1345,31 +1366,8 @@ int msm_vidc_destroy(struct msm_vidc_inst *inst)
			"Failed to move video instance to uninit state\n");

	msm_comm_session_clean(inst);

	msm_smem_delete_client(inst->mem_client);

	pr_info(VIDC_DBG_TAG "Closed video instance: %p\n",
			VIDC_MSG_PRIO2STRING(VIDC_INFO), inst);
	kfree(inst);

	return 0;
}

int msm_vidc_close(void *instance)
{
	void close_helper(struct kref *kref)
	{
		struct msm_vidc_inst *inst = container_of(kref,
				struct msm_vidc_inst, kref);

		msm_vidc_destroy(inst);
	}

	struct msm_vidc_inst *inst = instance;

	if (!inst)
		return -EINVAL;

	kref_put(&inst->kref, close_helper);
	return 0;
}