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

Commit 9d5000f5 authored by Maheshwar Ajja's avatar Maheshwar Ajja
Browse files

msm: vidc: Add schedule work functionality to SSR



User can trigger Sub System Restart (SSR) functionality
using command: "echo 1 > /d/msm_vidc/core0/trigger_ssr".
Kernel will acquire debugfs srcu lock before video driver
ssr function is called. There is deadlock if video driver
acquires core lock inside ssr function as other video threads
trying to acquire debugfs srcu lock after core lock acquired.
To resolve the issue schedule a work inside video driver ssr
function and return without acquiring core lock. The SSR
functionality will be executed whenever ssr work handler
is executed by the kernel.

Change-Id: I18f056156ee55dcb16e769e378434ee1ab6c4f5e
Signed-off-by: default avatarMaheshwar Ajja <majja@codeaurora.org>
parent d2560a26
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -352,6 +352,7 @@ static int msm_vidc_initialize_core(struct platform_device *pdev,
	}

	INIT_DELAYED_WORK(&core->fw_unload_work, msm_vidc_fw_unload_handler);
	INIT_WORK(&core->ssr_work, msm_vidc_ssr_handler);

	mutex_lock(&core->lock);
	core->vote_data = kcalloc(MAX_SUPPORTED_INSTANCES,
+19 −6
Original line number Diff line number Diff line
@@ -5144,17 +5144,32 @@ int msm_vidc_noc_error_info(struct msm_vidc_core *core)
int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
	enum hal_ssr_trigger_type type)
{
	int rc = 0;
	if (!core) {
		dprintk(VIDC_WARN, "%s: Invalid parameters\n", __func__);
		return -EINVAL;
	}
	core->ssr_type = type;
	schedule_work(&core->ssr_work);
	return 0;
}

void msm_vidc_ssr_handler(struct work_struct *work)
{
	int rc;
	struct msm_vidc_core *core;
	struct hfi_device *hdev;

	core = container_of(work, struct msm_vidc_core, ssr_work);
	if (!core || !core->device) {
		dprintk(VIDC_WARN, "Invalid parameters: %pK\n", core);
		return -EINVAL;
		dprintk(VIDC_ERR, "%s: Invalid params\n", __func__);
		return;
	}
	hdev = core->device;

	mutex_lock(&core->lock);
	if (core->state == VIDC_CORE_INIT_DONE) {
		dprintk(VIDC_WARN, "%s: ssr type %d\n", __func__,
			core->ssr_type);
		/*
		 * In current implementation user-initiated SSR triggers
		 * a fatal error from hardware. However, there is no way
@@ -5163,7 +5178,7 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
		 */
		core->trigger_ssr = true;
		rc = call_hfi_op(hdev, core_trigger_ssr,
				hdev->hfi_device_data, type);
				hdev->hfi_device_data, core->ssr_type);
		if (rc) {
			dprintk(VIDC_ERR, "%s: trigger_ssr failed\n",
				__func__);
@@ -5174,8 +5189,6 @@ int msm_vidc_trigger_ssr(struct msm_vidc_core *core,
			__func__, core);
	}
	mutex_unlock(&core->lock);

	return rc;
}

static int msm_vidc_load_supported(struct msm_vidc_inst *inst)
+3 −0
Original line number Diff line number Diff line
@@ -364,6 +364,8 @@ struct msm_vidc_core {
	u32 codec_count;
	struct msm_vidc_capability *capabilities;
	struct delayed_work fw_unload_work;
	struct work_struct ssr_work;
	enum hal_ssr_trigger_type ssr_type;
	bool smmu_fault_handled;
	bool trigger_ssr;
	unsigned long min_freq;
@@ -486,6 +488,7 @@ int msm_smem_unmap_dma_buf(struct msm_vidc_inst *inst, struct msm_smem *smem);
struct dma_buf *msm_smem_get_dma_buf(int fd);
void msm_smem_put_dma_buf(void *dma_buf);
void msm_vidc_fw_unload_handler(struct work_struct *work);
void msm_vidc_ssr_handler(struct work_struct *work);
/*
 * XXX: normally should be in msm_vidc.h, but that's meant for public APIs,
 * whereas this is private