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

Commit 581cf0e3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: disp: fix the race condition of vsync handler"

parents 8e7457a3 1ebbb0c5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, 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
@@ -600,6 +600,7 @@ struct mdss_mdp_ctl {
	struct mutex flush_lock;
	struct mutex *shared_lock;
	struct mutex rsrc_lock;
	struct mutex vsync_handler_lock;
	spinlock_t spin_lock;

	struct mdss_panel_data *panel_data;
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2019, 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
@@ -2452,6 +2452,7 @@ struct mdss_mdp_ctl *mdss_mdp_ctl_alloc(struct mdss_data_type *mdata,
			mutex_init(&ctl->offlock);
			mutex_init(&ctl->flush_lock);
			mutex_init(&ctl->rsrc_lock);
			mutex_init(&ctl->vsync_handler_lock);
			spin_lock_init(&ctl->spin_lock);
			BLOCKING_INIT_NOTIFIER_HEAD(&ctl->notifier_head);
			pr_debug("alloc ctl_num=%d\n", ctl->num);
+49 −2
Original line number Diff line number Diff line
@@ -1979,6 +1979,49 @@ static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
		return -ENODEV;
	}

	pr_debug("%pS->%s ctl:%d\n",
		__builtin_return_address(0), __func__, ctl->num);

	mutex_lock(&ctl->vsync_handler_lock);

	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), 0x88888);
	sctl = mdss_mdp_get_split_ctl(ctl);
	if (sctl)
		sctx = (struct mdss_mdp_cmd_ctx *) sctl->intf_ctx[MASTER_CTX];

	spin_lock_irqsave(&ctx->clk_lock, flags);
	if (handle->enabled) {
		handle->enabled = false;
		list_del_init(&handle->list);
		disable_vsync_irq = !handle->cmd_post_flush;
	}
	spin_unlock_irqrestore(&ctx->clk_lock, flags);

	if (disable_vsync_irq) {
		/* disable rd_ptr interrupt and clocks */
		mdss_mdp_setup_vsync(ctx, false);
		complete(&ctx->stop_comp);
	}

	mutex_unlock(&ctl->vsync_handler_lock);

	return 0;
}

static int mdss_mdp_cmd_remove_vsync_handler_nolock(struct mdss_mdp_ctl *ctl,
		struct mdss_mdp_vsync_handler *handle)
{
	struct mdss_mdp_ctl *sctl;
	struct mdss_mdp_cmd_ctx *ctx, *sctx = NULL;
	unsigned long flags;
	bool disable_vsync_irq = false;

	ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX];
	if (!ctx) {
		pr_err("%s: invalid ctx\n", __func__);
		return -ENODEV;
	}

	pr_debug("%pS->%s ctl:%d\n",
		__builtin_return_address(0), __func__, ctl->num);

@@ -3216,8 +3259,12 @@ static int mdss_mdp_cmd_stop_sub(struct mdss_mdp_ctl *ctl,
		return -ENODEV;
	}

	list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list)
		mdss_mdp_cmd_remove_vsync_handler(ctl, handle);
	mutex_lock(&ctl->vsync_handler_lock);
	list_for_each_entry_safe(handle, tmp, &ctx->vsync_handlers, list) {
		mdss_mdp_cmd_remove_vsync_handler_nolock(ctl, handle);
	}
	mutex_unlock(&ctl->vsync_handler_lock);

	if (mdss_mdp_is_lineptr_supported(ctl))
		mdss_mdp_cmd_lineptr_ctrl(ctl, false);
	MDSS_XLOG(ctl->num, atomic_read(&ctx->koff_cnt), XLOG_FUNC_ENTRY);