瀏覽代碼

video: driver: power collapse for last session close

power_collpase thread will initiate suspend sequence
if no there is no transaction for 1.5 sec. So even
after all session closed, power collapse thread will
kick in only after 1.5 sec, which can be avoided.

with this change power_collpase sequence will be
initiated right after last session close.

Change-Id: I4da231fa4a3d65bebbd19725db2f11d1478490dd
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 2 年之前
父節點
當前提交
9c5b7fe1c5
共有 2 個文件被更改,包括 56 次插入7 次删除
  1. 50 5
      driver/vidc/src/msm_vidc_driver.c
  2. 6 2
      driver/vidc/src/venus_hfi.c

+ 50 - 5
driver/vidc/src/msm_vidc_driver.c

@@ -543,6 +543,43 @@ static u32 msm_vidc_get_buffer_stats_flag(struct msm_vidc_inst *inst)
 	return flags;
 	return flags;
 }
 }
 
 
+static int msm_vidc_suspend_locked(struct msm_vidc_core *core)
+{
+	int rc = 0;
+
+	if (!core) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = venus_hfi_suspend(core);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
+static int msm_vidc_try_suspend(struct msm_vidc_inst *inst)
+{
+	struct msm_vidc_core *core;
+	int rc = 0;
+
+	if (!inst || !inst->core) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	core = inst->core;
+
+	core_lock(core, __func__);
+	if (list_empty(&core->instances) && list_empty(&core->dangling_instances)) {
+		i_vpr_h(inst, "%s: closed last open session. suspend video core\n", __func__);
+		msm_vidc_suspend_locked(core);
+	}
+	core_unlock(core, __func__);
+
+	return rc;
+}
+
 int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
 int msm_vidc_add_buffer_stats(struct msm_vidc_inst *inst,
 	struct msm_vidc_buffer *buf)
 	struct msm_vidc_buffer *buf)
 {
 {
@@ -4295,7 +4332,7 @@ static int msm_vidc_remove_dangling_session(struct msm_vidc_inst *inst)
 {
 {
 	struct msm_vidc_inst *i, *temp;
 	struct msm_vidc_inst *i, *temp;
 	struct msm_vidc_core *core;
 	struct msm_vidc_core *core;
-	u32 count = 0;
+	u32 count = 0, dcount = 0;
 
 
 	if (!inst || !inst->core) {
 	if (!inst || !inst->core) {
 		d_vpr_e("%s: invalid params\n", __func__);
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -4312,9 +4349,12 @@ static int msm_vidc_remove_dangling_session(struct msm_vidc_inst *inst)
 			break;
 			break;
 		}
 		}
 	}
 	}
-	list_for_each_entry(i, &core->dangling_instances, list)
+	list_for_each_entry(i, &core->instances, list)
 		count++;
 		count++;
-	i_vpr_h(inst, "%s: remaining dangling sessions %d\n", __func__, count);
+	list_for_each_entry(i, &core->dangling_instances, list)
+		dcount++;
+	i_vpr_h(inst, "%s: remaining sessions. active %d, dangling %d\n",
+		__func__, count, dcount);
 	core_unlock(core, __func__);
 	core_unlock(core, __func__);
 
 
 	return 0;
 	return 0;
@@ -5305,10 +5345,14 @@ int msm_vidc_suspend(struct msm_vidc_core *core)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	rc = venus_hfi_suspend(core);
+	core_lock(core, __func__);
+	d_vpr_h("%s: initiate PM suspend\n", __func__);
+	rc = msm_vidc_suspend_locked(core);
 	if (rc)
 	if (rc)
-		return rc;
+		goto exit;
 
 
+exit:
+	core_unlock(core, __func__);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -5625,6 +5669,7 @@ static void msm_vidc_close_helper(struct kref *kref)
 		destroy_workqueue(inst->workq);
 		destroy_workqueue(inst->workq);
 	msm_vidc_destroy_buffers(inst);
 	msm_vidc_destroy_buffers(inst);
 	msm_vidc_remove_dangling_session(inst);
 	msm_vidc_remove_dangling_session(inst);
+	msm_vidc_try_suspend(inst);
 	mutex_destroy(&inst->client_lock);
 	mutex_destroy(&inst->client_lock);
 	mutex_destroy(&inst->request_lock);
 	mutex_destroy(&inst->request_lock);
 	mutex_destroy(&inst->lock);
 	mutex_destroy(&inst->lock);

+ 6 - 2
driver/vidc/src/venus_hfi.c

@@ -1015,7 +1015,11 @@ int venus_hfi_suspend(struct msm_vidc_core *core)
 		d_vpr_e("%s: invalid params\n", __func__);
 		d_vpr_e("%s: invalid params\n", __func__);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	core_lock(core, __func__);
+
+	rc = __strict_check(core, __func__);
+	if (rc)
+		return rc;
+
 	d_vpr_h("Suspending Venus\n");
 	d_vpr_h("Suspending Venus\n");
 	rc = __power_collapse(core, true);
 	rc = __power_collapse(core, true);
 	if (!rc) {
 	if (!rc) {
@@ -1025,7 +1029,7 @@ int venus_hfi_suspend(struct msm_vidc_core *core)
 		d_vpr_e("%s: Venus is busy\n", __func__);
 		d_vpr_e("%s: Venus is busy\n", __func__);
 		rc = -EBUSY;
 		rc = -EBUSY;
 	}
 	}
-	core_unlock(core, __func__);
+
 	return rc;
 	return rc;
 }
 }