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

Commit 450dba6b authored by Clarence Ip's avatar Clarence Ip Committed by Gerrit - the friendly Code Review server
Browse files

msm: sde: abort failed inline requests during cleanup



Cleanup commands for inline rotation may time out in the
event of rotator hardware hangs. This patch attempts to
abort the failed transaction after a cleanup request has
timed out to allow the driver to revert back to a known
good state.

Change-Id: I48812e3d8d9e0b8a458fe8f7d4304aaefb21d3fd
Signed-off-by: default avatarClarence Ip <cip@codeaurora.org>
parent d977a433
Loading
Loading
Loading
Loading
+62 −23
Original line number Diff line number Diff line
@@ -1422,6 +1422,61 @@ int sde_rotator_inline_get_pixfmt_caps(struct platform_device *pdev,
}
EXPORT_SYMBOL(sde_rotator_inline_get_pixfmt_caps);

/*
 * _sde_rotator_inline_cleanup - perform inline related request cleanup
 *	This function assumes rot_dev->mgr lock has been taken when called.
 * @handle: Pointer to rotator context
 * @request: Pointer to rotation request
 * return: 0 if success; -EAGAIN if cleanup should be retried
 */
static int _sde_rotator_inline_cleanup(void *handle,
		struct sde_rotator_request *request)
{
	struct sde_rotator_ctx *ctx;
	struct sde_rotator_device *rot_dev;
	int ret;

	if (!handle || !request) {
		SDEROT_ERR("invalid rotator handle/request\n");
		return -EINVAL;
	}

	ctx = handle;
	rot_dev = ctx->rot_dev;

	if (!rot_dev || !rot_dev->mgr) {
		SDEROT_ERR("invalid rotator device\n");
		return -EINVAL;
	}

	if (request->committed) {
		/* wait until request is finished */
		sde_rot_mgr_unlock(rot_dev->mgr);
		mutex_unlock(&rot_dev->lock);
		ret = wait_event_timeout(ctx->wait_queue,
			sde_rotator_is_request_retired(request),
			msecs_to_jiffies(rot_dev->streamoff_timeout));
		mutex_lock(&rot_dev->lock);
		sde_rot_mgr_lock(rot_dev->mgr);

		if (!ret) {
			SDEROT_ERR("timeout w/o retire s:%d\n",
					ctx->session_id);
			SDEROT_EVTLOG(ctx->session_id, SDE_ROT_EVTLOG_ERROR);
			sde_rotator_abort_inline_request(rot_dev->mgr,
					ctx->private, request->req);
			return -EAGAIN;
		} else if (ret == 1) {
			SDEROT_ERR("timeout w/ retire s:%d\n", ctx->session_id);
			SDEROT_EVTLOG(ctx->session_id, SDE_ROT_EVTLOG_ERROR);
		}
	}

	sde_rotator_req_finish(rot_dev->mgr, ctx->private, request->req);
	sde_rotator_retire_request(request);
	return 0;
}

/*
 * sde_rotator_inline_commit - commit given rotator command
 * @handle: Pointer to rotator context
@@ -1449,7 +1504,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
	ctx = handle;
	rot_dev = ctx->rot_dev;

	if (!rot_dev) {
	if (!rot_dev || !rot_dev->mgr) {
		SDEROT_ERR("invalid rotator device\n");
		return -EINVAL;
	}
@@ -1481,6 +1536,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
		(cmd->video_mode << 5) |
		(cmd_type << 24));

	mutex_lock(&rot_dev->lock);
	sde_rot_mgr_lock(rot_dev->mgr);

	if (cmd_type == SDE_ROTATOR_INLINE_CMD_VALIDATE ||
@@ -1690,30 +1746,11 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
		}

		request = cmd->priv_handle;
		req = request->req;

		if (request->committed) {
			/* wait until request is finished */
			sde_rot_mgr_unlock(rot_dev->mgr);
			ret = wait_event_timeout(ctx->wait_queue,
				sde_rotator_is_request_retired(request),
				msecs_to_jiffies(rot_dev->streamoff_timeout));
			if (!ret) {
				SDEROT_ERR("timeout w/o retire s:%d\n",
						ctx->session_id);
				SDEROT_EVTLOG(ctx->session_id,
						SDE_ROT_EVTLOG_ERROR);
			} else if (ret == 1) {
				SDEROT_ERR("timeout w/ retire s:%d\n",
						ctx->session_id);
				SDEROT_EVTLOG(ctx->session_id,
						SDE_ROT_EVTLOG_ERROR);
			}
			sde_rot_mgr_lock(rot_dev->mgr);
		}
		/* attempt single retry if first cleanup attempt failed */
		if (_sde_rotator_inline_cleanup(handle, request) == -EAGAIN)
			_sde_rotator_inline_cleanup(handle, request);

		sde_rotator_req_finish(rot_dev->mgr, ctx->private, req);
		sde_rotator_retire_request(request);
		cmd->priv_handle = NULL;
	} else if (cmd_type == SDE_ROTATOR_INLINE_CMD_ABORT) {
		if (!cmd->priv_handle) {
@@ -1729,6 +1766,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
	}

	sde_rot_mgr_unlock(rot_dev->mgr);
	mutex_unlock(&rot_dev->lock);
	return 0;

error_handle_request:
@@ -1741,6 +1779,7 @@ int sde_rotator_inline_commit(void *handle, struct sde_rotator_inline_cmd *cmd,
error_invalid_handle:
error_init_request:
	sde_rot_mgr_unlock(rot_dev->mgr);
	mutex_unlock(&rot_dev->lock);
	return ret;
}
EXPORT_SYMBOL(sde_rotator_inline_commit);