diff options
author | Animesh Kishore <animeshk@codeaurora.org> | 2018-02-23 18:04:28 +0530 |
---|---|---|
committer | Animesh Kishore <animeshk@codeaurora.org> | 2018-02-28 12:12:16 +0530 |
commit | 4c2dad03b75dcbba3b5182a6b94c6c65f23a54ea (patch) | |
tree | 843a32c408db50df7a5cea67aac94016fc567161 /drivers/video/fbdev | |
parent | 867bd83b1faa29778f3dac6c97f2e772a6a69240 (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.h | 9 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 4 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 40 | ||||
-rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_pp.c | 9 |
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; } |