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

Commit 3cf15df9 authored by Vikash Garodia's avatar Vikash Garodia
Browse files

msm: vidc: flush queued work during device suspend



This change flushes any queued work related to power collapse,
once the device is power suspended.
There are applications which do not destroy video instance
on suspending the device. For such applications, if the device
is power suspended, video driver does not prepare venus for
power collapse.
Considerable power saving is observed by power collapsing
venus before the device goes in suspend state.

Change-Id: I11252e45b10d0d3d3eefb38994acd083c847bbb8
Signed-off-by: default avatarVikash Garodia <vgarodia@codeaurora.org>
parent eddaea8d
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -553,6 +553,35 @@ static const struct of_device_id msm_vidc_dt_match[] = {
	{}
};

static int msm_vidc_pm_suspend(struct device *pdev)
{
	struct msm_vidc_core *core;

	if (!pdev) {
		dprintk(VIDC_ERR, "%s invalid device\n", __func__);
		return -EINVAL;
	}

	core = (struct msm_vidc_core *)pdev->platform_data;
	if (!core) {
		dprintk(VIDC_ERR, "%s invalid core\n", __func__);
		return -EINVAL;
	}
	dprintk(VIDC_INFO, "%s\n", __func__);

	return msm_vidc_suspend(core->id);
}

static int msm_vidc_pm_resume(struct device *dev)
{
	dprintk(VIDC_INFO, "%s\n", __func__);
	return 0;
}

static const struct dev_pm_ops msm_vidc_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(msm_vidc_pm_suspend, msm_vidc_pm_resume)
};

MODULE_DEVICE_TABLE(of, msm_vidc_dt_match);

static struct platform_driver msm_vidc_driver = {
@@ -562,6 +591,7 @@ static struct platform_driver msm_vidc_driver = {
		.name = "msm_vidc_v4l2",
		.owner = THIS_MODULE,
		.of_match_table = msm_vidc_dt_match,
		.pm = &msm_vidc_pm_ops,
	},
};

+6 −0
Original line number Diff line number Diff line
@@ -1452,3 +1452,9 @@ int msm_vidc_close(void *instance)
}
EXPORT_SYMBOL(msm_vidc_close);

int msm_vidc_suspend(int core_id)
{
	return msm_comm_suspend(core_id);
}
EXPORT_SYMBOL(msm_vidc_suspend);
+27 −0
Original line number Diff line number Diff line
@@ -2552,6 +2552,33 @@ exit:
	return rc;
}

int msm_comm_suspend(int core_id)
{
	struct hfi_device *hdev;
	struct msm_vidc_core *core;
	int rc = 0;

	core = get_vidc_core(core_id);
	if (!core) {
		dprintk(VIDC_ERR,
			"%s: Failed to find core for core_id = %d\n",
			__func__, core_id);
		return -EINVAL;
	}

	hdev = (struct hfi_device *)core->device;
	if (!hdev) {
		dprintk(VIDC_ERR, "%s Invalid device handle\n", __func__);
		return -EINVAL;
	}

	rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data);
	if (rc)
		dprintk(VIDC_WARN, "Failed to suspend\n");

	return rc;
}

static int get_flipped_state(int present_state,
	int desired_state)
{
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst);
int msm_comm_release_output_buffers(struct msm_vidc_inst *inst);
int msm_comm_force_cleanup(struct msm_vidc_inst *inst);
int msm_comm_suspend(int core_id);
enum hal_extradata_id msm_comm_get_hal_extradata_index(
	enum v4l2_mpeg_vidc_extradata index);
enum hal_buffer_layout_type msm_comm_get_hal_buffer_layout(
+19 −0
Original line number Diff line number Diff line
@@ -1265,6 +1265,24 @@ static unsigned long venus_hfi_get_clock_rate(struct clock_info *clock,
	return ret;
}

static int venus_hfi_suspend(void *dev)
{
	int rc = 0;
	struct venus_hfi_device *device = (struct venus_hfi_device *) dev;

	if (!device) {
		dprintk(VIDC_ERR, "%s invalid device\n", __func__);
		return -EINVAL;
	}
	dprintk(VIDC_INFO, "%s\n", __func__);

	if (device->power_enabled) {
		rc = flush_delayed_work(&venus_hfi_pm_work);
		dprintk(VIDC_INFO, "%s flush delayed work %d\n", __func__, rc);
	}
	return 0;
}

static inline int venus_hfi_clk_enable(struct venus_hfi_device *device)
{
	int rc = 0;
@@ -4211,6 +4229,7 @@ static void venus_init_hfi_callbacks(struct hfi_device *hdev)
	hdev->get_stride_scanline = venus_hfi_get_stride_scanline;
	hdev->get_core_capabilities = venus_hfi_get_core_capabilities;
	hdev->power_enable = venus_hfi_power_enable;
	hdev->suspend = venus_hfi_suspend;
}

int venus_hfi_initialize(struct hfi_device *hdev, u32 device_id,
Loading