lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250930040348.3702923-20-h.dewangan@samsung.com>
Date: Tue, 30 Sep 2025 09:33:38 +0530
From: Himanshu Dewangan <h.dewangan@...sung.com>
To: mchehab@...nel.org, robh@...nel.org, krzk+dt@...nel.org,
	conor+dt@...nel.org, sumit.semwal@...aro.org, christian.koenig@....com,
	alim.akhtar@...sung.com, manjun@...sung.com, nagaraju.s@...sung.com,
	ih0206.lee@...sung.com, jehyung.lee@...sung.com
Cc: linux-arm-kernel@...ts.infradead.org, linux-media@...r.kernel.org,
	devicetree@...r.kernel.org, linux-samsung-soc@...r.kernel.org,
	linux-kernel@...r.kernel.org, dri-devel@...ts.freedesktop.org,
	linaro-mm-sig@...ts.linaro.org, Himanshu Dewangan <h.dewangan@...sung.com>
Subject: [PATCH 19/29] media: mfc: Add QoS, Butler workqueue, and priority‑based scheduling

From: Nagaraju Siddineni <nagaraju.s@...sung.com>

- Integrate QoS handling (core, ops, PM).
- Add Butler workqueue for core tasks (allocation, init, cleanup).
- Implement async QoS control workqueue using atomic counters
  and proper sync.
- Update probe to initialize workqueues, QoS structures,
  and improve logging.
- Modify PM to trigger QoS updates on clock changes and issue
  idle‑clock QoS when bus devfreq is active.
- Refactor scheduler for priority‑aware work handling
  via bit‑mask tracking.
- Extend ops table with extra instance and buffer management.

Signed-off-by: Nagaraju Siddineni <nagaraju.s@...sung.com>
Signed-off-by: Himanshu Dewangan <h.dewangan@...sung.com>
---
 .../platform/samsung/exynos-mfc/mfc_core.c    | 145 +++++++
 .../samsung/exynos-mfc/mfc_core_ops.c         | 370 ++++++++++++++++++
 .../platform/samsung/exynos-mfc/mfc_core_pm.c |  25 ++
 .../samsung/exynos-mfc/mfc_core_sched_prio.c  | 331 ++++++++++++++++
 .../samsung/exynos-mfc/mfc_dec_v4l2.c         |  12 +-
 .../samsung/exynos-mfc/mfc_dec_v4l2.h         |  12 +-
 6 files changed, 881 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c b/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
index 4f5cf459c36f..af6fd088fad3 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core.c
@@ -28,6 +28,7 @@
 
 #include "mfc_core_ops.h"
 #include "mfc_core_isr.h"
+#include "mfc_dec_v4l2.h"
 #include "mfc_debugfs.h"
 
 #include "mfc_core_hwlock.h"
@@ -37,7 +38,9 @@
 
 #include "mfc_core_hw_reg_api.h"
 
+#include "base/mfc_qos.h"
 #include "base/mfc_sched.h"
+#include "base/mfc_queue.h"
 #include "base/mfc_buf.h"
 #include "base/mfc_mem.h"
 
@@ -45,6 +48,45 @@
 
 struct _mfc_trace_logging g_mfc_core_trace_logging[MFC_TRACE_LOG_COUNT_MAX];
 
+static void mfc_core_butler_worker(struct work_struct *work)
+{
+	struct mfc_core *core;
+
+	core = container_of(work, struct mfc_core, butler_work);
+
+	mfc_core_try_run(core);
+}
+
+static int __mfc_core_parse_mfc_qos_platdata(struct device_node *np,
+					     char *node_name,
+					     struct mfc_qos *qosdata,
+					     struct mfc_core *core)
+{
+	struct device_node *np_qos;
+
+	np_qos = of_find_node_by_name(NULL, node_name);
+	if (!np_qos) {
+		dev_err(core->device,
+			"%s: could not find mfc_qos_platdata node\n",
+			node_name);
+		return -EINVAL;
+	}
+
+	of_property_read_u32(np_qos, "thrd_mb", &qosdata->threshold_mb);
+	of_property_read_u32(np_qos, "freq_mfc", &qosdata->freq_mfc);
+	of_property_read_u32(np_qos, "freq_int", &qosdata->freq_int);
+	of_property_read_u32(np_qos, "freq_mif", &qosdata->freq_mif);
+	of_property_read_u32(np_qos, "mo_value", &qosdata->mo_value);
+	of_property_read_u32(np_qos, "time_fw", &qosdata->time_fw);
+
+	of_property_read_string(np_qos, "bts_scen", &qosdata->name);
+	if (!qosdata->name) {
+		mfc_pr_err("[QoS] bts_scen is missing in '%s' node", node_name);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 #if (IS_ENABLED(CONFIG_SAMSUNG_IOMMU))
 static int mfc_core_sysmmu_fault_handler(struct iommu_domain *domain,
 					 struct device *dev, unsigned long iova,
@@ -140,6 +182,9 @@ static int mfc_core_sysmmu_fault_handler(struct iommu_domain *domain,
 static int __mfc_core_parse_dt(struct device_node *np, struct mfc_core *core)
 {
 	struct mfc_core_platdata *pdata = core->core_pdata;
+	struct device_node *np_qos;
+	char node_name[50];
+	int i;
 
 	if (!np) {
 		mfc_pr_err("there is no device node\n");
@@ -164,6 +209,61 @@ static int __mfc_core_parse_dt(struct device_node *np, struct mfc_core *core)
 	of_property_read_u32(np, "masterid_mask", &pdata->masterid_mask);
 	of_property_read_u32(np, "tsmux_masterid", &pdata->tsmux_masterid);
 
+	/* QoS */
+	of_property_read_u32(np, "num_default_qos_steps",
+			     &pdata->num_default_qos_steps);
+	of_property_read_u32(np, "max_mb", &pdata->max_mb);
+	of_property_read_u32(np, "max_hw_mb", &pdata->max_hw_mb);
+	of_property_read_u32(np, "mfc_freq_control", &pdata->mfc_freq_control);
+	of_property_read_u32(np, "mo_control", &pdata->mo_control);
+	of_property_read_u32(np, "bw_control", &pdata->bw_control);
+	of_property_read_u32(np, "pm_qos_id", &pdata->pm_qos_id);
+
+	pdata->default_qos_table = devm_kzalloc(core->device,
+						sizeof(struct mfc_qos) *
+						pdata->num_default_qos_steps,
+						GFP_KERNEL);
+	for (i = 0; i < pdata->num_default_qos_steps; i++) {
+		snprintf(node_name, sizeof(node_name), "mfc_d_qos_variant_%d",
+			 i);
+		__mfc_core_parse_mfc_qos_platdata(np, node_name,
+						  &pdata->default_qos_table[i],
+						  core);
+	}
+
+	/* performance boost mode */
+	pdata->qos_boost_table = devm_kzalloc(core->device,
+					      sizeof(struct mfc_qos_boost),
+					      GFP_KERNEL);
+	np_qos = of_find_node_by_name(np, "mfc_perf_boost_table");
+	if (!np_qos) {
+		dev_err(core->device,
+			"[QoS][BOOST] could not find mfc_perf_boost_table node\n");
+		return -EINVAL;
+	}
+	of_property_read_u32(np_qos, "num_cluster",
+			     &pdata->qos_boost_table->num_cluster);
+	of_property_read_u32_array(np_qos, "num_cpu",
+				   &pdata->qos_boost_table->num_cpu[0],
+				   pdata->qos_boost_table->num_cluster);
+	of_property_read_u32(np_qos, "freq_mfc",
+			     &pdata->qos_boost_table->freq_mfc);
+	of_property_read_u32(np_qos, "freq_int",
+			     &pdata->qos_boost_table->freq_int);
+	of_property_read_u32(np_qos, "freq_mif",
+			     &pdata->qos_boost_table->freq_mif);
+	of_property_read_u32_array(np_qos, "freq_cluster",
+				   &pdata->qos_boost_table->freq_cluster[0],
+				   pdata->qos_boost_table->num_cluster);
+
+	of_property_read_string(np_qos, "bts_scen",
+				&pdata->qos_boost_table->name);
+	if (!pdata->qos_boost_table->name) {
+		mfc_pr_err
+		    ("[QoS][BOOST] bts_scen is missing in qos_boost node");
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
@@ -274,6 +374,7 @@ static int mfc_core_probe(struct platform_device *pdev)
 	struct mfc_core *core;
 	struct mfc_dev *dev;
 	int ret = -ENOENT;
+	int i;
 
 	dev_info(&pdev->dev, "%s is called\n", __func__);
 
@@ -325,6 +426,44 @@ static int mfc_core_probe(struct platform_device *pdev)
 
 	spin_lock_init(&core->batch_lock);
 
+	/* core butler worker */
+	core->butler_wq = alloc_workqueue("mfc_core/butler", WQ_UNBOUND
+					  | WQ_MEM_RECLAIM | WQ_HIGHPRI, 1);
+	if (!core->butler_wq) {
+		dev_err(&pdev->dev, "failed to create workqueue for butler\n");
+		goto err_butler_wq;
+	}
+	INIT_WORK(&core->butler_work, mfc_core_butler_worker);
+
+	/* core QoS control worker */
+	core->qos_ctrl_wq = alloc_workqueue("mfc_core/qos_ctrl", WQ_UNBOUND
+					    | WQ_MEM_RECLAIM | WQ_HIGHPRI, 1);
+	if (!core->qos_ctrl_wq) {
+		dev_err(&pdev->dev,
+			"failed to create workqueue for QoS control\n");
+		goto err_qos_ctrl_wq;
+	}
+#ifdef CONFIG_MFC_USE_BUS_DEVFREQ
+	INIT_WORK(&core->qos_ctrl_work, mfc_qos_ctrl_worker);
+#endif
+
+	atomic_set(&core->qos_req_cur, 0);
+	mutex_init(&core->qos_mutex);
+	mutex_init(&core->pm_qos_mutex);
+
+	mfc_core_info("[QoS] control: mfc_freq(%d), mo(%d), bw(%d)\n",
+		      core->core_pdata->mfc_freq_control,
+		      core->core_pdata->mo_control,
+		      core->core_pdata->bw_control);
+	mfc_core_info("[QoS]-------------------Default table\n");
+	for (i = 0; i < core->core_pdata->num_default_qos_steps; i++)
+		mfc_core_info
+		    ("[QoS] table[%d] mfc: %d, int: %d, mif: %d, bts_scen: %s(%d)\n",
+		     i, core->core_pdata->default_qos_table[i].freq_mfc,
+		     core->core_pdata->default_qos_table[i].freq_int,
+		     core->core_pdata->default_qos_table[i].freq_mif,
+		     core->core_pdata->default_qos_table[i].name,
+		     core->core_pdata->default_qos_table[i].bts_scen_idx);
 #if IS_ENABLED(CONFIG_SAMSUNG_IOMMU)
 	ret = samsung_iommu_register_fault_handler(core->device,
 						   mfc_core_sysmmu_fault_handler,
@@ -365,6 +504,10 @@ static int mfc_core_probe(struct platform_device *pdev)
 	samsung_iommu_unregister_fault_handler(&pdev->dev);
  err_sysmmu_fault_handler:
 #endif
+	destroy_workqueue(core->qos_ctrl_wq);
+ err_qos_ctrl_wq:
+	destroy_workqueue(core->butler_wq);
+ err_butler_wq:
 	if (core->has_2sysmmu)
 		iounmap(core->sysmmu1_base);
 	iounmap(core->sysmmu0_base);
@@ -388,6 +531,8 @@ static void mfc_core_remove(struct platform_device *pdev)
 #if IS_ENABLED(CONFIG_SAMSUNG_IOMMU)
 	samsung_iommu_unregister_fault_handler(&pdev->dev);
 #endif
+	flush_workqueue(core->butler_wq);
+	destroy_workqueue(core->butler_wq);
 	mfc_core_destroy_listable_wq_core(core);
 
 	mfc_release_common_context(core);
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_ops.c b/drivers/media/platform/samsung/exynos-mfc/mfc_core_ops.c
index d9200bba1bb5..f8a27548b218 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_ops.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_ops.c
@@ -19,8 +19,10 @@
 #include "mfc_core_hw_reg_api.h"
 
 #include "base/mfc_sched.h"
+#include "base/mfc_qos.h"
 #include "base/mfc_buf.h"
 #include "base/mfc_utils.h"
+#include "base/mfc_queue.h"
 #include "base/mfc_mem.h"
 
 static void __mfc_core_init(struct mfc_core *core, struct mfc_ctx *ctx)
@@ -109,6 +111,8 @@ static int __mfc_core_deinit(struct mfc_core *core, struct mfc_ctx *ctx)
 	if (core->num_inst == 0) {
 		mfc_core_run_deinit_hw(core);
 
+		flush_workqueue(core->butler_wq);
+
 		mfc_debug(2, "power off\n");
 		mfc_core_pm_power_off(core);
 
@@ -121,6 +125,40 @@ static int __mfc_core_deinit(struct mfc_core *core, struct mfc_ctx *ctx)
 		}
 	}
 
+	mfc_qos_off(core, ctx);
+
+	return 0;
+}
+
+static int __mfc_force_close_inst(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
+	enum mfc_inst_state prev_state;
+
+	if (core_ctx->state == MFCINST_FREE)
+		return 0;
+
+	prev_state = core_ctx->state;
+	mfc_change_state(core_ctx, MFCINST_RETURN_INST);
+	mfc_change_op_mode(ctx, MFC_OP_SINGLE);
+	core->sched->set_work(core, core_ctx);
+	mfc_clean_core_ctx_int_flags(core_ctx);
+	if (mfc_core_just_run(core, ctx->num)) {
+		mfc_err("Failed to run MFC\n");
+		mfc_change_state(core_ctx, prev_state);
+		return -EIO;
+	}
+
+	/* Wait until instance is returned or timeout occurred */
+	if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_CLOSE_INSTANCE_RET)) {
+		mfc_err("Waiting for CLOSE_INSTANCE timed out\n");
+		mfc_change_state(core_ctx, prev_state);
+		return -EIO;
+	}
+
+	/* Free resources */
+	mfc_release_instance_context(core_ctx);
+
 	return 0;
 }
 
@@ -153,7 +191,12 @@ static int __mfc_core_instance_init(struct mfc_core *core, struct mfc_ctx *ctx)
 
 	init_waitqueue_head(&core_ctx->cmd_wq);
 	mfc_core_init_listable_wq_ctx(core_ctx);
+	spin_lock_init(&core_ctx->buf_queue_lock);
 	core->sched->clear_work(core, core_ctx);
+	INIT_LIST_HEAD(&core_ctx->qos_list);
+	INIT_LIST_HEAD(&core_ctx->mb_list);
+
+	mfc_create_queue(&core_ctx->src_buf_queue);
 
 	if (core->num_inst == 1) {
 		mfc_debug(2, "it is first instance in to core-%d\n", core->id);
@@ -252,6 +295,14 @@ static int mfc_core_instance_deinit(struct mfc_core *core, struct mfc_ctx *ctx)
 
 	core->sched->clear_work(core, core_ctx);
 
+	/* If a H/W operation is in progress, wait for it complete */
+	if (NEED_TO_WAIT_NAL_ABORT(core_ctx)) {
+		if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_NAL_ABORT_RET)) {
+			mfc_err("Failed to wait nal abort\n");
+			core->sched->yield_work(core, core_ctx);
+		}
+	}
+
 	ret = mfc_core_get_hwlock_ctx(core_ctx);
 	if (ret < 0) {
 		mfc_err("Failed to get hwlock\n");
@@ -265,9 +316,14 @@ static int mfc_core_instance_deinit(struct mfc_core *core, struct mfc_ctx *ctx)
 	if (ret)
 		goto err_release_try;
 
+	mfc_release_codec_buffers(core_ctx);
+	mfc_release_instance_context(core_ctx);
+
 	mfc_core_release_hwlock_ctx(core_ctx);
 	mfc_core_destroy_listable_wq_ctx(core_ctx);
 
+	mfc_delete_queue(&core_ctx->src_buf_queue);
+
 	core->core_ctx[core_ctx->num] = 0;
 	kfree(core_ctx);
 
@@ -275,12 +331,326 @@ static int mfc_core_instance_deinit(struct mfc_core *core, struct mfc_ctx *ctx)
 
 err_release_try:
 	mfc_core_release_hwlock_ctx(core_ctx);
+	core->sched->yield_work(core, core_ctx);
+	return ret;
+}
+
+static int __mfc_core_instance_open_dec(struct mfc_ctx *ctx,
+					struct mfc_core_ctx *core_ctx)
+{
+	struct mfc_core *core = core_ctx->core;
+	int ret = 0;
+
+	/* In case of calling s_fmt twice or more */
+	ret = __mfc_force_close_inst(core, ctx);
+	if (ret) {
+		mfc_err("Failed to close already opening instance\n");
+		mfc_core_release_hwlock_ctx(core_ctx);
+		core->sched->yield_work(core, core_ctx);
+		return -EIO;
+	}
+
+	ret = mfc_alloc_instance_context(core_ctx);
+	if (ret) {
+		mfc_err("Failed to allocate dec instance[%d] buffers\n",
+			ctx->num);
+		mfc_core_release_hwlock_ctx(core_ctx);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static int mfc_core_instance_open(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
+	int ret = 0;
+
+	if (!core_ctx) {
+		mfc_core_err("There is no instance\n");
+		return -EINVAL;
+	}
+
+	ret = mfc_core_get_hwlock_ctx(core_ctx);
+	if (ret < 0) {
+		mfc_err("Failed to get hwlock\n");
+		return ret;
+	}
+
+	if (ctx->type == MFCINST_DECODER) {
+		if (__mfc_core_instance_open_dec(ctx, core_ctx))
+			return -EAGAIN;
+	} else {
+		mfc_err("invalid codec type: %d\n", ctx->type);
+		return -EINVAL;
+	}
+
+	mfc_change_state(core_ctx, MFCINST_INIT);
+	core->sched->set_work(core, core_ctx);
+	ret = mfc_core_just_run(core, ctx->num);
+	if (ret) {
+		mfc_err("Failed to run MFC\n");
+		goto err_open;
+	}
+
+	if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_OPEN_INSTANCE_RET)) {
+		mfc_err("failed to wait OPEN_INSTANCE\n");
+		mfc_change_state(core_ctx, MFCINST_FREE);
+		ret = -EIO;
+		goto err_open;
+	}
+
+	mfc_core_release_hwlock_ctx(core_ctx);
+
+	mfc_debug(2, "Got instance number inst_no: %d\n", core_ctx->inst_no);
+
+	core->sched->enqueue_work(core, core_ctx);
+	if (core->sched->is_work(core))
+		core->sched->queue_work(core);
+
+	return ret;
+
+err_open:
+	mfc_core_release_hwlock_ctx(core_ctx);
+	core->sched->yield_work(core, core_ctx);
+	mfc_release_instance_context(core_ctx);
+
+	return ret;
+}
+
+static void mfc_core_instance_cache_flush(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	if (core->state == MFCCORE_ERROR) {
+		mfc_core_info("[MSR] Couldn't cache flush. It's Error state\n");
+		return;
+	}
+
+	core->curr_core_ctx = ctx->num;
+
+	mfc_core_pm_clock_on(core, 0);
+	mfc_core_run_cache_flush
+		(core,
+		core->last_cmd_has_cache_flush ? MFC_NO_CACHEFLUSH : MFC_CACHEFLUSH,
+		0);
+	mfc_core_pm_clock_off(core, 0);
+}
+
+static int mfc_core_instance_move_to(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	int ret = 0;
+
+	ret = __mfc_core_instance_init(core, ctx);
+	if (ret) {
+		mfc_core_err("Failed to core instance init\n");
+		return ret;
+	}
+
+	if (core->num_inst > 1) {
+		mfc_ctx_debug(2, "to core-%d already working, send cache_flush only\n", core->id);
+		mfc_core_instance_cache_flush(core, ctx);
+	}
+
+	mfc_ctx_info("to core-%d is ready to move\n", core->id);
+
+	return 0;
+}
+
+static int mfc_core_instance_move_from(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
+	int ret = 0;
+	int inst_no;
+
+	mfc_clean_core_ctx_int_flags(core_ctx);
+	core->sched->set_work(core, core_ctx);
+
+	ret = mfc_core_just_run(core, ctx->num);
+	if (ret) {
+		mfc_err("Failed to run MFC\n");
+		return ret;
+	}
+
+	if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_MOVE_INSTANCE_RET)) {
+		mfc_err("time out during move instance\n");
+		core->logging_data->cause |= BIT(MFC_CAUSE_FAIL_MOVE_INST);
+		return -EFAULT;
+	}
+	inst_no = mfc_core_get_inst_no();
+
+	ret = __mfc_core_deinit(core, ctx);
+	if (ret) {
+		mfc_err("Failed to close instance\n");
+		return ret;
+	}
+
+	mfc_info("inst_no.%d will be changed to no.%d\n", core_ctx->inst_no, inst_no);
+	core_ctx->inst_no = inst_no;
+
 	return ret;
 }
 
+static void mfc_core_instance_dpb_flush(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_dec *dec = ctx->dec_priv;
+	struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
+	int index = 0, i, ret;
+	int prev_state;
+
+	if (core->state == MFCCORE_ERROR || core_ctx->state == MFCINST_ERROR)
+		goto cleanup;
+
+	ret = mfc_core_get_hwlock_ctx(core_ctx);
+	if (ret < 0) {
+		mfc_err("Failed to get hwlock\n");
+		MFC_TRACE_CTX_LT("[ERR][Release] failed to get hwlock (shutdown: %d)\n",
+				 core->shutdown);
+		if (core->shutdown)
+			goto cleanup;
+		return;
+	}
+
+	mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
+	mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->err_buf_queue);
+
+	mutex_lock(&dec->dpb_mutex);
+	for (i = 0; i < MFC_MAX_DPBS; i++)
+		dec->dpb[i].queued = 0;
+	mutex_unlock(&dec->dpb_mutex);
+
+	dec->queued_dpb = 0;
+	ctx->is_dpb_realloc = 0;
+	dec->last_dpb_max_index = 0;
+
+	if (!dec->inter_res_change) {
+		dec->dpb_table_used = 0;
+		dec->dynamic_used = 0;
+		if (dec->is_dynamic_dpb) {
+			mfc_cleanup_iovmm(ctx);
+			dec->dynamic_set = 0;
+			core_ctx->dynamic_set = 0;
+		} else {
+			dec->dynamic_set = MFC_ALL_AVAILABLE_DPB;
+		}
+	} else {
+		mfc_cleanup_iovmm_except_used(ctx);
+		mfc_print_dpb_table(ctx);
+	}
+
+	while (index < MFC_MAX_BUFFERS) {
+		index = find_next_bit(ctx->dst_ctrls_avail, MFC_MAX_BUFFERS, index);
+		if (index < MFC_MAX_BUFFERS)
+			call_cop(ctx, reset_buf_ctrls, &ctx->dst_ctrls[index]);
+		index++;
+	}
+
+	mutex_lock(&ctx->drc_wait_mutex);
+	if (ctx->wait_state & WAIT_STOP) {
+		ctx->wait_state &= ~(WAIT_STOP);
+		mfc_debug(2, "clear WAIT_STOP %d\n", ctx->wait_state);
+		MFC_TRACE_CORE_CTX("** DEC clear WAIT_STOP(wait_state %d)\n",
+				   ctx->wait_state);
+
+		if (ctx->ready_to_be_multi_view_enable) {
+			ctx->ready_to_be_multi_view_enable = 0;
+			ctx->multi_view_enable = 1;
+			mfc_debug(3, "[MV-HEVC] enabled\n");
+		}
+	}
+	mutex_unlock(&ctx->drc_wait_mutex);
+
+	if (core_ctx->state == MFCINST_FINISHING)
+		mfc_change_state(core_ctx, MFCINST_RUNNING);
+
+	if (NEED_TO_DPB_FLUSH(core_ctx) && !ctx->dec_priv->inter_res_change) {
+		prev_state = core_ctx->state;
+		mfc_change_state(core_ctx, MFCINST_DPB_FLUSHING);
+		core->sched->set_work(core, core_ctx);
+		mfc_clean_core_ctx_int_flags(core_ctx);
+		mfc_info("try to DPB flush\n");
+		ret = mfc_core_just_run(core, ctx->num);
+		if (ret) {
+			mfc_err("Failed to run MFC\n");
+			mfc_core_release_hwlock_ctx(core_ctx);
+			core->sched->yield_work(core, core_ctx);
+			return;
+		}
+
+		if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_DPB_FLUSH_RET)) {
+			mfc_err("time out during DPB flush\n");
+			core->logging_data->cause |= BIT(MFC_CAUSE_FAIL_DPB_FLUSH);
+		}
+
+		mfc_change_state(core_ctx, prev_state);
+	}
+
+	mfc_debug(2, "decoder destination stop sequence done\n");
+
+	core->sched->clear_work(core, core_ctx);
+	mfc_core_release_hwlock_ctx(core_ctx);
+
+	core->sched->enqueue_work(core, core_ctx);
+	if (core->sched->is_work(core))
+		core->sched->queue_work(core);
+
+	return;
+
+cleanup:
+	mfc_core_info("[MSR] Cleanup dst buffers. It's Error state\n");
+	mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->dst_buf_queue);
+	mfc_cleanup_queue(&ctx->buf_queue_lock, &ctx->err_buf_queue);
+}
+
+static int mfc_core_instance_init_buf(struct mfc_core *core, struct mfc_ctx *ctx)
+{
+	struct mfc_core_ctx *core_ctx = core->core_ctx[ctx->num];
+
+	core->sched->set_work(core, core_ctx);
+	mfc_clean_core_ctx_int_flags(core_ctx);
+	if (mfc_core_just_run(core, ctx->num)) {
+		mfc_err("Failed to run MFC\n");
+		return -EIO;
+	}
+
+	if (mfc_wait_for_done_core_ctx(core_ctx, MFC_REG_R2H_CMD_INIT_BUFFERS_RET)) {
+		mfc_err("[RM] init buffer timeout\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int mfc_core_request_work(struct mfc_core *core,
+				 enum mfc_request_work work,
+				 struct mfc_ctx *ctx)
+{
+	switch (work) {
+	case MFC_WORK_BUTLER:
+		mfc_core_debug(3, "request_work: butler\n");
+		if (core->sched->is_work(core))
+			core->sched->queue_work(core);
+		break;
+	case MFC_WORK_TRY:
+		mfc_core_debug(3, "request_work: try_run\n");
+		mfc_core_try_run(core);
+		break;
+	default:
+		mfc_core_err("not supported request work type: %#x\n", work);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static const struct mfc_core_ops mfc_core_ops = {
 	.instance_init = mfc_core_instance_init,
 	.instance_deinit = mfc_core_instance_deinit,
+	.instance_open = mfc_core_instance_open,
+	.instance_cache_flush = mfc_core_instance_cache_flush,
+	.instance_move_to = mfc_core_instance_move_to,
+	.instance_move_from = mfc_core_instance_move_from,
+	.instance_dpb_flush = mfc_core_instance_dpb_flush,
+	.instance_init_buf = mfc_core_instance_init_buf,
+	.request_work = mfc_core_request_work,
 };
 
 const struct mfc_core_ops *mfc_get_core_ops(void)
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_pm.c b/drivers/media/platform/samsung/exynos-mfc/mfc_core_pm.c
index def7ac2a2007..a70b2b472c06 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_pm.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_pm.c
@@ -16,6 +16,8 @@
 
 #include "mfc_core_hw_reg_api.h"
 
+#include "base/mfc_qos.h"
+
 void mfc_core_pm_init(struct mfc_core *core)
 {
 	spin_lock_init(&core->pm.clklock);
@@ -78,6 +80,9 @@ int mfc_core_pm_clock_on(struct mfc_core *core, bool qos_update)
 	mfc_core_debug(2, "clk_ref = %d\n", state);
 	MFC_TRACE_LOG_CORE("clk_ref = %d", state);
 
+	if (qos_update && state == 1)
+		mfc_qos_update(core, 1);
+
 	return 0;
 }
 
@@ -113,6 +118,9 @@ void mfc_core_pm_clock_off(struct mfc_core *core, bool qos_update)
 
 	mfc_core_debug(2, "clk_ref = %d\n", state);
 	MFC_TRACE_LOG_CORE("clk_ref = %d", state);
+
+	if (qos_update && state == 0)
+		mfc_qos_update(core, 0);
 }
 
 int mfc_core_pm_power_on(struct mfc_core *core)
@@ -126,6 +134,15 @@ int mfc_core_pm_power_on(struct mfc_core *core)
 		goto err_power_on;
 	}
 
+#ifdef CONFIG_MFC_USE_BUS_DEVFREQ
+	if (core->dev->pdata->idle_clk_ctrl) {
+		mfc_core_debug(2, "request mfc idle clk OFF\n");
+		exynos_pm_qos_add_request(&core->qos_req_mfc_noidle,
+					  core->core_pdata->pm_qos_id,
+					  core->dev->pdata->mfc_freqs[0]);
+	}
+#endif
+
 #if (IS_ENABLED(CONFIG_COMMON_CLK_SAMSUNG))
 	core->pm.clock = clk_get(core->device, "aclk_mfc");
 	if (IS_ERR(core->pm.clock)) {
@@ -167,6 +184,14 @@ int mfc_core_pm_power_off(struct mfc_core *core)
 		clk_unprepare(core->pm.clock);
 		clk_put(core->pm.clock);
 	}
+
+#ifdef CONFIG_MFC_USE_BUS_DEVFREQ
+	if (core->dev->pdata->idle_clk_ctrl) {
+		exynos_pm_qos_remove_request(&core->qos_req_mfc_noidle);
+		mfc_core_debug(2, "request mfc idle clk ON\n");
+	}
+#endif
+
 	mfc_core_mfc_always_off(core);
 
 	ret = pm_runtime_put_sync(core->pm.device);
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_core_sched_prio.c b/drivers/media/platform/samsung/exynos-mfc/mfc_core_sched_prio.c
index a2f69a064d3d..34731229338d 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_core_sched_prio.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_core_sched_prio.c
@@ -13,6 +13,7 @@
 #include "mfc_core_sync.h"
 
 #include "base/mfc_sched.h"
+#include "base/mfc_qos.h"
 #include "base/mfc_utils.h"
 
 static inline void __mfc_print_workbits(struct mfc_core *core, int prio, int num)
@@ -36,6 +37,42 @@ static inline void __mfc_clear_all_prio_bits(struct mfc_core *core)
 	spin_unlock_irqrestore(&core->prio_work_lock, flags);
 }
 
+static int __mfc_ctx_ready_set_bit_prio(struct mfc_core_ctx *core_ctx, bool set)
+
+{
+	struct mfc_core *core;
+	struct mfc_ctx *ctx;
+	unsigned long flags;
+	int p, is_ready = 0;
+
+	if (!core_ctx) {
+		mfc_pr_err("no mfc core_ctx device to run\n");
+		return is_ready;
+	}
+
+	core = core_ctx->core;
+	if (!core) {
+		mfc_err("no mfc core device to run\n");
+		return is_ready;
+	}
+
+	ctx = core_ctx->ctx;
+	if (!ctx) {
+		mfc_err("no mfc ctx device to run\n");
+		return is_ready;
+	}
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+
+	p = mfc_get_prio(core, ctx->rt, ctx->prio);
+	is_ready = mfc_ctx_ready_set_bit_raw(core_ctx, &core->prio_work_bits[p], set);
+	__mfc_print_workbits(core, p, core_ctx->num);
+
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+
+	return is_ready;
+}
+
 static void mfc_create_work_prio(struct mfc_core *core)
 {
 	int num_prio = core->dev->pdata->pbs_num_prio;
@@ -61,6 +98,27 @@ static void mfc_clear_all_work_prio(struct mfc_core *core)
 	__mfc_clear_all_prio_bits(core);
 }
 
+static int mfc_is_work_prio(struct mfc_core *core)
+{
+	unsigned long flags;
+	int i, ret = 0;
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+	for (i = 0; i < core->total_num_prio; i++) {
+		if (core->prio_work_bits[i]) {
+			ret = 1;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+	return ret;
+}
+
+static void mfc_queue_work_prio(struct mfc_core *core)
+{
+	queue_work(core->butler_wq, &core->butler_work);
+}
+
 static void mfc_set_work_prio(struct mfc_core *core, struct mfc_core_ctx *core_ctx)
 {
 	struct mfc_ctx *ctx = core_ctx->ctx;
@@ -91,10 +149,283 @@ static void mfc_clear_work_prio(struct mfc_core *core, struct mfc_core_ctx *core
 	spin_unlock_irqrestore(&core->prio_work_lock, flags);
 }
 
+static int mfc_enqueue_work_prio(struct mfc_core *core, struct mfc_core_ctx *core_ctx)
+{
+	return __mfc_ctx_ready_set_bit_prio(core_ctx, true);
+}
+
+static int mfc_dequeue_work_prio(struct mfc_core *core, struct mfc_core_ctx *core_ctx)
+{
+	return __mfc_ctx_ready_set_bit_prio(core_ctx, false);
+}
+
+static void mfc_yield_work_prio(struct mfc_core *core, struct mfc_core_ctx *core_ctx)
+{
+	struct mfc_ctx *ctx = core_ctx->ctx;
+	unsigned long flags;
+	int p;
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+
+	p = mfc_get_prio(core, ctx->rt, ctx->prio);
+	__clear_bit(core_ctx->num, &core->prio_work_bits[p]);
+	__mfc_print_workbits(core, p, core_ctx->num);
+
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+
+	mfc_core_try_run(core);
+}
+
+static unsigned long __mfc_check_lower_prio_inst(struct mfc_core *core, int prio)
+{
+	unsigned long sum = 0;
+	int i;
+
+	for (i = prio + 1; i < core->total_num_prio; i++)
+		sum |= core->prio_work_bits[i];
+
+	return sum;
+}
+
+static void __mfc_update_max_runtime(struct mfc_core *core, unsigned long bits)
+{
+	struct mfc_core_ctx *core_ctx;
+	int max_runtime = 0, runtime;
+	int i, num;
+
+	if (core->dev->debugfs.sched_perf_disable)
+		return;
+
+	for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
+		if (test_bit(i, &bits)) {
+			core_ctx = core->core_ctx[i];
+			if (!core_ctx)
+				continue;
+			/* if runtime is 0, use default 30fps (33msec) */
+			runtime = core_ctx->avg_runtime ? core_ctx->avg_runtime :
+				MFC_DEFAULT_RUNTIME;
+			if (runtime > max_runtime) {
+				max_runtime = runtime;
+				num = i;
+			}
+		}
+	}
+
+	if (max_runtime)
+		mfc_core_debug(2, "[PRIO][c:%d] max runtime is %d usec\n", num, max_runtime);
+
+	core->max_runtime = max_runtime;
+}
+
+static int __mfc_core_get_new_ctx_prio(struct mfc_core *core, int prio, int *highest,
+				       bool predict)
+{
+	struct mfc_core_ctx *core_ctx;
+	unsigned long bits = 0;
+	int new_ctx_index;
+	int i, perf = 0, skip_curr;
+
+	new_ctx_index = (core->last_core_ctx[prio] + 1) % MFC_NUM_CONTEXTS;
+
+	for (i = 0; i < MFC_NUM_CONTEXTS; i++) {
+		if (test_bit(new_ctx_index, &core->prio_work_bits[prio])) {
+			if (*highest < 0)
+				*highest = new_ctx_index;
+
+			/* If predict, do not get curr ctx */
+			skip_curr = 0;
+			if (predict && new_ctx_index == core->curr_core_ctx) {
+				mfc_core_debug(2, "[PRIO][PREDICT](%d) skip curr ctx %d\n",
+					       prio, new_ctx_index);
+				skip_curr = 1;
+			}
+
+			/* If the performance is insufficient, run this */
+			core_ctx = core->core_ctx[new_ctx_index];
+			perf = mfc_rate_check_perf_ctx(core_ctx->ctx, core->max_runtime);
+			if (!perf && !skip_curr) {
+				mfc_core_debug(2, "[PRIO]%s(%d) perf insufficient: %d\n",
+					       (predict ? "[PREDICT]" : ""),
+					       prio, new_ctx_index);
+				return new_ctx_index;
+			}
+
+			/* If the perf of all instances is satisfied, run the highest */
+			bits |= BIT(new_ctx_index);
+			if (((core->prio_work_bits[prio] & ~(bits)) == 0) &&
+			    !__mfc_check_lower_prio_inst(core, prio)) {
+				mfc_core_debug(2, "[PRIO]%s(%d) the highest priority %d\n",
+					       (predict ? "[PREDICT]" : ""),
+					       prio, *highest);
+				return *highest;
+			}
+		}
+		/* If there is no ready context in prio, return */
+		if ((core->prio_work_bits[prio] & ~(bits)) == 0)
+			return -1;
+
+		new_ctx_index = (new_ctx_index + 1) % MFC_NUM_CONTEXTS;
+	}
+
+	return -1;
+}
+
+/* This should be called with prio_work_lock */
+static int __mfc_core_get_new_ctx(struct mfc_core *core, bool predict)
+{
+	int new_ctx_index = 0, highest = -1;
+	int i;
+
+	for (i = 0; i < core->total_num_prio; i++) {
+		if (!core->prio_work_bits[i])
+			continue;
+
+		mfc_core_debug(2, "[PRIO]%s(%d) Previous context: %d (bits %08lx)\n",
+			       (predict ? "[PREDICT]" : ""),
+			       i, core->last_core_ctx[i], core->prio_work_bits[i]);
+
+		new_ctx_index = __mfc_core_get_new_ctx_prio(core, i, &highest, predict);
+		if (new_ctx_index >= 0) {
+			mfc_core_debug(2, "[PRIO]%s(%d) get new_ctx %d\n",
+				       (predict ? "[PREDICT]" : ""), i, new_ctx_index);
+			return new_ctx_index;
+		}
+	}
+
+	return -1;
+}
+
+static int mfc_pick_next_work_prio(struct mfc_core *core)
+{
+	unsigned long flags, work_bits, hweight;
+	int new_ctx_index = -1;
+
+	if (!mfc_is_work_prio(core)) {
+		mfc_core_debug(2, "[PRIO] No ctx to run\n");
+		return -EAGAIN;
+	}
+
+	if (core->preempt_core_ctx > MFC_NO_INSTANCE_SET) {
+		new_ctx_index = core->preempt_core_ctx;
+		mfc_core_debug(2, "[PRIO] preempt_core_ctx %d\n", new_ctx_index);
+		return new_ctx_index;
+	}
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+
+	work_bits = __mfc_check_lower_prio_inst(core, -1);
+	mfc_core_debug(2, "[PRIO] all work_bits %#lx\n", work_bits);
+
+	/* if single instance is ready, run it */
+	hweight = hweight64(work_bits);
+	if (hweight == 1) {
+		new_ctx_index = __ffs(work_bits);
+		mfc_core_debug(2, "[PRIO] new_ctx_idx %d (single)\n", new_ctx_index);
+		spin_unlock_irqrestore(&core->prio_work_lock, flags);
+		return new_ctx_index;
+	}
+
+	__mfc_update_max_runtime(core, work_bits);
+
+	/* if there is predicted next ctx, run it */
+	if (core->next_ctx_idx >= 0 && test_bit(core->next_ctx_idx, &work_bits)) {
+		new_ctx_index = core->next_ctx_idx;
+		mfc_core_debug(2, "[PRIO] new_ctx_idx %d (predict)\n", new_ctx_index);
+		spin_unlock_irqrestore(&core->prio_work_lock, flags);
+		return new_ctx_index;
+	}
+
+	new_ctx_index = __mfc_core_get_new_ctx(core, 0);
+	mfc_core_debug(2, "[PRIO] new_ctx_idx %d\n", new_ctx_index);
+
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+
+	return new_ctx_index;
+}
+
+static int mfc_get_next_work_prio(struct mfc_core *core)
+{
+	unsigned long flags, work_bits, hweight;
+	int new_ctx_index;
+
+	if (core->dev->num_inst)
+		return -1;
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+
+	work_bits = __mfc_check_lower_prio_inst(core, -1);
+	hweight = hweight64(work_bits);
+	/* Nothing to predict because only one instance is ready */
+	if (hweight <= 1) {
+		spin_unlock_irqrestore(&core->prio_work_lock, flags);
+		return -1;
+	}
+
+	new_ctx_index = __mfc_core_get_new_ctx(core, 1);
+	core->next_ctx_idx = new_ctx_index;
+	mfc_core_debug(2, "[PRIO][PREDICT] new_ctx_idx %d\n", new_ctx_index);
+
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+
+	return new_ctx_index;
+}
+
+static int mfc_change_prio_work_prio(struct mfc_core *core, struct mfc_ctx *ctx,
+				     int cur_rt, int cur_prio, int new_rt, int new_prio)
+{
+	unsigned long flags;
+	int cur_p, new_p;
+
+	spin_lock_irqsave(&core->prio_work_lock, flags);
+
+	if (new_prio > core->num_prio)
+		new_prio = core->num_prio;
+
+	/* Check current priority's work_bit */
+	cur_p = mfc_get_prio(core, cur_rt, cur_prio);
+	new_p = mfc_get_prio(core, new_rt, new_prio);
+	if (cur_p == new_p) {
+		ctx->prio = new_prio;
+		ctx->rt = new_rt;
+		spin_unlock_irqrestore(&core->prio_work_lock, flags);
+		return 0;
+	}
+
+	mfc_core_debug(2, "[PRIO] cur_p %d -> new_p %d is changed (%d %d -> %d %d)\n",
+		       cur_p, new_p, cur_rt, cur_prio, new_rt, new_prio);
+
+	if (test_bit(ctx->num, &core->prio_work_bits[cur_p])) {
+		__clear_bit(ctx->num, &core->prio_work_bits[cur_p]);
+		mfc_core_debug(2, "[PRIO][c:%d] prio change from %d (bits %08lx)\n",
+			       ctx->num, cur_p, core->prio_work_bits[cur_p]);
+
+		/* Update current priority's work_bit */
+		__set_bit(ctx->num, &core->prio_work_bits[new_p]);
+		mfc_core_debug(2, "[PRIO][c:%d] prio change to %d (bits %08lx)\n",
+			       ctx->num, new_p, core->prio_work_bits[new_p]);
+	}
+
+	/* These must be updated within the spin_lock for synchronization. */
+	ctx->prio = new_prio;
+	ctx->rt = new_rt;
+
+	spin_unlock_irqrestore(&core->prio_work_lock, flags);
+
+	return 0;
+}
+
 struct mfc_sched_class mfc_sched_prio = {
 	.create_work		= mfc_create_work_prio,
 	.init_work		= mfc_init_work_prio,
 	.clear_all_work		= mfc_clear_all_work_prio,
+	.queue_work		= mfc_queue_work_prio,
+	.is_work		= mfc_is_work_prio,
+	.pick_next_work		= mfc_pick_next_work_prio,
+	.get_next_work		= mfc_get_next_work_prio,
 	.set_work		= mfc_set_work_prio,
 	.clear_work		= mfc_clear_work_prio,
+	.enqueue_work		= mfc_enqueue_work_prio,
+	.dequeue_work		= mfc_dequeue_work_prio,
+	.yield_work		= mfc_yield_work_prio,
+	.change_prio_work	= mfc_change_prio_work_prio,
 };
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.c b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.c
index dd59dc352e34..8eb68294c0b1 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.c
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.c
@@ -1,14 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- * mfc_dec_v4l2.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com/
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * mfc_dec_v4l2.c file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
  */
 
 #include <linux/vmalloc.h>
diff --git a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.h b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.h
index 04652a71cd23..08fe4ed5cf3f 100644
--- a/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.h
+++ b/drivers/media/platform/samsung/exynos-mfc/mfc_dec_v4l2.h
@@ -1,14 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later
  *
- * mfc_dec_v4l2.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2025 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com/
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * mfc_dec_v4l2.h file
+ *
+ * Nagaraju Siddineni, <nagaraju.s@...sung.com>
+ * Himanshu Dewangan, <h.dewangan@...sung.com>
  */
 
 #ifndef __MFC_DEC_V4L2_H
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ