From 5969ffec6686e1730b5353d51acb5b33acb4f9cb Mon Sep 17 00:00:00 2001 From: Ayoung Sim Date: Tue, 20 Nov 2018 15:04:31 +0900 Subject: [PATCH] [RAMEN9610-10029][COMMON] media: mfc: handle MFC QoS atomically MFC QoS should be controled atomically because various thread can request qos_on. Overlapped QoS calls(pm_qos_xxx_request()) cause of countless warning log messages. Change-Id: Ifd74cf009fd263cd6732646ae92d4d46fb1d4ca0 Signed-off-by: Ayoung Sim --- drivers/media/platform/exynos/mfc/mfc.c | 1 + drivers/media/platform/exynos/mfc/mfc_data_struct.h | 1 + drivers/media/platform/exynos/mfc/mfc_qos.c | 11 +++++++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/exynos/mfc/mfc.c b/drivers/media/platform/exynos/mfc/mfc.c index 1ee52a53be3d..e01124b3d0f7 100644 --- a/drivers/media/platform/exynos/mfc/mfc.c +++ b/drivers/media/platform/exynos/mfc/mfc.c @@ -1414,6 +1414,7 @@ static int mfc_probe(struct platform_device *pdev) #ifdef CONFIG_MFC_USE_BUS_DEVFREQ atomic_set(&dev->qos_req_cur, 0); + mutex_init(&dev->qos_mutex); mfc_info_dev("[QoS] control: mfc_freq(%d), mo(%d), bw(%d)\n", dev->pdata->mfc_freq_control, dev->pdata->mo_control, dev->pdata->bw_control); diff --git a/drivers/media/platform/exynos/mfc/mfc_data_struct.h b/drivers/media/platform/exynos/mfc/mfc_data_struct.h index 18141c210401..10abb6589b73 100644 --- a/drivers/media/platform/exynos/mfc/mfc_data_struct.h +++ b/drivers/media/platform/exynos/mfc/mfc_data_struct.h @@ -810,6 +810,7 @@ struct mfc_dev { struct pm_qos_request qos_req_mif; struct pm_qos_request qos_req_cluster[MAX_NUM_CLUSTER]; int qos_has_enc_ctx; + struct mutex qos_mutex; #endif int id; atomic_t clk_ref; diff --git a/drivers/media/platform/exynos/mfc/mfc_qos.c b/drivers/media/platform/exynos/mfc/mfc_qos.c index f19ea64da43a..8b5460a53185 100644 --- a/drivers/media/platform/exynos/mfc/mfc_qos.c +++ b/drivers/media/platform/exynos/mfc/mfc_qos.c @@ -239,10 +239,12 @@ static void __mfc_qos_set(struct mfc_ctx *ctx, int i) } #endif + mutex_lock(&dev->qos_mutex); if (atomic_read(&dev->qos_req_cur) == 0) __mfc_qos_operate(ctx, MFC_QOS_ADD, i); else if (atomic_read(&dev->qos_req_cur) != (i + 1)) __mfc_qos_operate(ctx, MFC_QOS_UPDATE, i); + mutex_unlock(&dev->qos_mutex); } static inline unsigned long __mfc_qos_get_weighted_mb(struct mfc_ctx *ctx, @@ -596,10 +598,12 @@ void mfc_qos_off(struct mfc_ctx *ctx) } if (list_empty(&dev->qos_queue)) { + mutex_lock(&dev->qos_mutex); if (atomic_read(&dev->qos_req_cur) != 0) { mfc_err_ctx("[QoS] MFC request count is wrong!\n"); __mfc_qos_operate(ctx, MFC_QOS_REMOVE, 0); } + mutex_unlock(&dev->qos_mutex); return; } @@ -655,14 +659,17 @@ void mfc_qos_off(struct mfc_ctx *ctx) if (found) list_del(&ctx->qos_list); - if (list_empty(&dev->qos_queue) || total_mb == 0) + if (list_empty(&dev->qos_queue) || total_mb == 0) { + mutex_lock(&dev->qos_mutex); __mfc_qos_operate(ctx, MFC_QOS_REMOVE, 0); - else + mutex_unlock(&dev->qos_mutex); + } else { #ifdef CONFIG_EXYNOS_BTS __mfc_qos_set(ctx, &mfc_bw, i); #else __mfc_qos_set(ctx, i); #endif + } } #endif -- 2.20.1