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

Commit 3befe7cd authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm/sde/rotator: add support to check if done handler is scheduled"

parents 88459eaf d0732454
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-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
@@ -435,6 +435,33 @@ static int sde_rotator_start_streaming(struct vb2_queue *q, unsigned int count)
	return 0;
}

/*
 * Check if done handler is submitted before continuing with
 * the stop streaming request so that mismatch between
 * hardware and software timestamps can be avoided.
 */
static bool sde_rot_check_for_flush_ts(struct sde_rot_mgr *mgr,
	struct sde_rot_file_private *private)
{
	struct sde_rot_entry_container *req, *req_next;
	struct sde_rot_entry *entry;
	ktime_t current_ts;
	int i;

	current_ts = ktime_get();
	list_for_each_entry_safe(req, req_next, &private->req_list, list)
		for (i = 0; i < req->count; i++) {
			entry = req->entries + i;
			if ((entry->item.ts) &&
				ktime_to_ms(ktime_sub(current_ts,
				entry->item.ts[SDE_ROTATOR_TS_FLUSH])) <
				SDE_ROTATOR_STREAM_OFF_TIMEOUT)
				return false;
		}

	return true;
}

/*
 * sde_rotator_stop_streaming - vb2_ops stop_streaming callback.
 * @q: Pointer to vb2 queue struct.
@@ -455,6 +482,8 @@ static void sde_rotator_stop_streaming(struct vb2_queue *q)
			ctx->session_id, q->type,
			!list_empty(&ctx->pending_list));
	ctx->abort_pending = 1;

wait_for_completion:
	mutex_unlock(q->lock);
	ret = wait_event_timeout(ctx->wait_queue,
			list_empty(&ctx->pending_list),
@@ -469,6 +498,13 @@ static void sde_rotator_stop_streaming(struct vb2_queue *q)
				!list_empty(&ctx->pending_list),
				SDE_ROT_EVTLOG_ERROR);
		sde_rot_mgr_lock(rot_dev->mgr);
		ret = sde_rot_check_for_flush_ts(rot_dev->mgr, ctx->private);
		if (!ret) {
			sde_rot_mgr_unlock(rot_dev->mgr);
			SDEDEV_ERR(rot_dev->dev, "wait again for %d ms\n",
				rot_dev->streamoff_timeout);
			goto wait_for_completion;
		}
		sde_rotator_cancel_all_requests(rot_dev->mgr, ctx->private);
		sde_rot_mgr_unlock(rot_dev->mgr);
		list_for_each_safe(curr, next, &ctx->pending_list) {