summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorAnimesh Kishore <animeshk@codeaurora.org>2018-02-23 18:04:28 +0530
committerAnimesh Kishore <animeshk@codeaurora.org>2018-02-28 12:12:16 +0530
commit4c2dad03b75dcbba3b5182a6b94c6c65f23a54ea (patch)
tree843a32c408db50df7a5cea67aac94016fc567161 /drivers/video/fbdev
parent867bd83b1faa29778f3dac6c97f2e772a6a69240 (diff)
msm: mdss: Fix scalar LUT handling
Add lock to serialize access between userspace and kernel. Fix error handling for LUT allocation. Change-Id: Ie86a8eb3e2a11852ae16d87ebc851afb6566732f Signed-off-by: Animesh Kishore <animeshk@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/mdss.h9
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c4
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c40
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_pp.c9
4 files changed, 45 insertions, 17 deletions
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 5548f0f09f8a..1ccb27113c11 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -255,6 +255,13 @@ struct mdss_scaler_block {
u32 *dest_scaler_off;
u32 *dest_scaler_lut_off;
struct mdss_mdp_qseed3_lut_tbl lut_tbl;
+
+ /*
+ * Lock is mainly to serialize access to LUT.
+ * LUT values come asynchronously from userspace
+ * via ioctl.
+ */
+ struct mutex scaler_lock;
};
struct mdss_data_type;
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index 410d36a3ac31..a77e5c4435bb 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -1,7 +1,7 @@
/*
* MDSS MDP Interface (used by framebuffer core)
*
- * Copyright (c) 2007-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2007-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2007 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
@@ -2436,6 +2436,8 @@ static u32 mdss_mdp_scaler_init(struct mdss_data_type *mdata,
ret = mdss_mdp_ds_addr_setup(mdata);
}
+ mutex_init(&mdata->scaler_off->scaler_lock);
+
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
index 11c159630747..791c73baa9e7 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -6631,14 +6631,18 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
if (!mdata->scaler_off)
return -EFAULT;
+ mutex_lock(&mdata->scaler_off->scaler_lock);
+
qseed3_lut_tbl = &mdata->scaler_off->lut_tbl;
if ((lut_tbl->dir_lut_size !=
DIR_LUT_IDX * DIR_LUT_COEFFS * sizeof(uint32_t)) ||
(lut_tbl->cir_lut_size !=
CIR_LUT_IDX * CIR_LUT_COEFFS * sizeof(uint32_t)) ||
(lut_tbl->sep_lut_size !=
- SEP_LUT_IDX * SEP_LUT_COEFFS * sizeof(uint32_t)))
- return -EINVAL;
+ SEP_LUT_IDX * SEP_LUT_COEFFS * sizeof(uint32_t))) {
+ mutex_unlock(&mdata->scaler_off->scaler_lock);
+ return -EINVAL;
+ }
if (!qseed3_lut_tbl->dir_lut) {
qseed3_lut_tbl->dir_lut = devm_kzalloc(&mdata->pdev->dev,
@@ -6646,7 +6650,7 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
GFP_KERNEL);
if (!qseed3_lut_tbl->dir_lut) {
ret = -ENOMEM;
- goto fail;
+ goto err;
}
}
@@ -6656,7 +6660,7 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
GFP_KERNEL);
if (!qseed3_lut_tbl->cir_lut) {
ret = -ENOMEM;
- goto fail;
+ goto fail_free_dir_lut;
}
}
@@ -6666,44 +6670,52 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
GFP_KERNEL);
if (!qseed3_lut_tbl->sep_lut) {
ret = -ENOMEM;
- goto fail;
+ goto fail_free_cir_lut;
}
}
/* Invalidate before updating */
qseed3_lut_tbl->valid = false;
-
if (copy_from_user(qseed3_lut_tbl->dir_lut,
(void *)(unsigned long)lut_tbl->dir_lut,
lut_tbl->dir_lut_size)) {
ret = -EINVAL;
- goto err;
+ goto fail_free_sep_lut;
}
if (copy_from_user(qseed3_lut_tbl->cir_lut,
(void *)(unsigned long)lut_tbl->cir_lut,
lut_tbl->cir_lut_size)) {
ret = -EINVAL;
- goto err;
+ goto fail_free_sep_lut;
}
if (copy_from_user(qseed3_lut_tbl->sep_lut,
(void *)(unsigned long)lut_tbl->sep_lut,
lut_tbl->sep_lut_size)) {
ret = -EINVAL;
- goto err;
+ goto fail_free_sep_lut;
}
qseed3_lut_tbl->valid = true;
+ mutex_unlock(&mdata->scaler_off->scaler_lock);
+
return ret;
-fail:
- kfree(qseed3_lut_tbl->dir_lut);
- kfree(qseed3_lut_tbl->cir_lut);
- kfree(qseed3_lut_tbl->sep_lut);
+fail_free_sep_lut:
+ devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->sep_lut);
+fail_free_cir_lut:
+ devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->cir_lut);
+fail_free_dir_lut:
+ devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->dir_lut);
err:
+ qseed3_lut_tbl->dir_lut = NULL;
+ qseed3_lut_tbl->cir_lut = NULL;
+ qseed3_lut_tbl->sep_lut = NULL;
qseed3_lut_tbl->valid = false;
+ mutex_unlock(&mdata->scaler_off->scaler_lock);
+
return ret;
}
diff --git a/drivers/video/fbdev/msm/mdss_mdp_pp.c b/drivers/video/fbdev/msm/mdss_mdp_pp.c
index 9c2b1d42bd35..ee338ba88c4d 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_pp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_pp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1604,11 +1604,16 @@ int mdss_mdp_scaler_lut_cfg(struct mdp_scale_data_v2 *scaler,
};
mdata = mdss_mdp_get_mdata();
+
+ mutex_lock(&mdata->scaler_off->scaler_lock);
+
lut_tbl = &mdata->scaler_off->lut_tbl;
if ((!lut_tbl) || (!lut_tbl->valid)) {
+ mutex_unlock(&mdata->scaler_off->scaler_lock);
pr_err("%s:Invalid QSEED3 LUT TABLE\n", __func__);
return -EINVAL;
}
+
if ((scaler->lut_flag & SCALER_LUT_DIR_WR) ||
(scaler->lut_flag & SCALER_LUT_Y_CIR_WR) ||
(scaler->lut_flag & SCALER_LUT_UV_CIR_WR) ||
@@ -1656,6 +1661,8 @@ int mdss_mdp_scaler_lut_cfg(struct mdp_scale_data_v2 *scaler,
}
}
+ mutex_unlock(&mdata->scaler_off->scaler_lock);
+
return 0;
}