diff --git a/msm/vidc/msm_v4l2_vidc.c b/msm/vidc/msm_v4l2_vidc.c index 873b1a2053da..7d492887154e 100644 --- a/msm/vidc/msm_v4l2_vidc.c +++ b/msm/vidc/msm_v4l2_vidc.c @@ -677,6 +677,7 @@ static int msm_vidc_pm_suspend(struct device *dev) int rc = 0; struct msm_vidc_core *core; + d_vpr_h("%s\n", __func__); /* * Bail out if * - driver possibly not probed yet @@ -698,14 +699,33 @@ static int msm_vidc_pm_suspend(struct device *dev) rc = 0; else if (rc) d_vpr_e("Failed to suspend: %d\n", rc); - + else + core->pm_suspended = true; return rc; } static int msm_vidc_pm_resume(struct device *dev) { + struct msm_vidc_core *core; + d_vpr_h("%s\n", __func__); + /* + * Bail out if + * - driver possibly not probed yet + * - not the main device. We don't support power management on + * subdevices (e.g. context banks) + */ + if (!dev || !dev->driver || + !of_device_is_compatible(dev->of_node, "qcom,msm-vidc")) + return 0; + + core = dev_get_drvdata(dev); + if (!core) { + d_vpr_e("%s: invalid core\n", __func__); + return -EINVAL; + } + core->pm_suspended = false; return 0; } diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index 32cd6f6a1f04..5c8bee69eee7 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -3054,6 +3054,7 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) core->state = VIDC_CORE_INIT; core->smmu_fault_handled = false; core->trigger_ssr = false; + core->pm_suspended = false; core->resources.max_secure_inst_count = core->resources.max_secure_inst_count ? core->resources.max_secure_inst_count : @@ -4540,10 +4541,11 @@ void msm_vidc_batch_handler(struct work_struct *work) { int rc = 0; struct msm_vidc_inst *inst; + struct msm_vidc_core *core; inst = container_of(work, struct msm_vidc_inst, batch_work.work); inst = get_inst(get_vidc_core(MSM_VIDC_CORE_VENUS), inst); - if (!inst) { + if (!inst || !inst->core) { d_vpr_e("%s: invalid params\n", __func__); return; } @@ -4553,9 +4555,14 @@ void msm_vidc_batch_handler(struct work_struct *work) goto exit; } + core = inst->core; + if (core->pm_suspended) { + s_vpr_h(inst->sid, "%s: device in pm suspend state\n", __func__); + goto exit; + } + s_vpr_h(inst->sid, "%s: queue pending batch buffers\n", __func__); - rc = msm_comm_qbufs_batch(inst, NULL); if (rc) { s_vpr_e(inst->sid, "%s: batch qbufs failed\n", __func__); diff --git a/msm/vidc/msm_vidc_internal.h b/msm/vidc/msm_vidc_internal.h index 62e8c0b6a110..0f1614a613d3 100644 --- a/msm/vidc/msm_vidc_internal.h +++ b/msm/vidc/msm_vidc_internal.h @@ -508,6 +508,7 @@ struct msm_vidc_core { unsigned long min_freq; unsigned long curr_freq; struct msm_vidc_core_ops *core_ops; + bool pm_suspended; }; struct msm_vidc_inst;