Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f3b73b4 authored by Animesh Kishore's avatar Animesh Kishore Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarAnimesh Kishore <animeshk@codeaurora.org>
parent 102ccfb3
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
/* 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
@@ -232,6 +232,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;
+3 −1
Original line number Diff line number Diff line
/*
 * 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
@@ -2081,6 +2081,8 @@ static u32 mdss_mdp_scaler_init(struct mdss_data_type *mdata,
			return -EINVAL;
	}

	mutex_init(&mdata->scaler_off->scaler_lock);

	return 0;
}

+26 −14
Original line number Diff line number Diff line
/* 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
@@ -6789,14 +6789,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)))
		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,
@@ -6804,7 +6808,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;
		}
	}

@@ -6814,7 +6818,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;
		}
	}

@@ -6824,44 +6828,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;
}

+8 −1
Original line number Diff line number Diff line
/* 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
@@ -1576,11 +1576,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) ||
@@ -1631,6 +1636,8 @@ int mdss_mdp_scaler_lut_cfg(struct mdp_scale_data_v2 *scaler,
		writel_relaxed(BIT(0), MDSS_MDP_REG_SCALER_COEF_LUT_CTRL +
				offset);

	mutex_unlock(&mdata->scaler_off->scaler_lock);

	return 0;
}