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

Commit bf8a4038 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: hdmi: hdcp2p2: fix hdcp 2.2 compliance issues



Send stream management message to sink after topology update. Poll
for new message or authentication required status after successful
receiver or repeater authentication. Also, DDC hardware polls sink
for a given time. Let the polling complete and do not treat intermediate
DDC errors as failures because DDC transaction can pass in next
iteration. Once polling ends, check for errors and timeouts and reset
polling data. Treat these errors as failure only after polling ends.

Change-Id: I286fb00cf935bff493e108c05df625d5ca3ade26
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 63bc4524
Loading
Loading
Loading
Loading
+48 −7
Original line number Diff line number Diff line
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2016, 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
@@ -354,6 +354,7 @@ struct hdcp_lib_handle {
	enum hdcp_state hdcp_state;
	enum hdcp_lib_wakeup_cmd wakeup_cmd;
	bool repeater_flag;
	bool update_stream;
	bool tethered;
	struct qseecom_handle *qseecom_handle;
	int last_msg_sent;
@@ -703,11 +704,17 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
	struct hdcp_query_stream_type_req *req_buf;
	struct hdcp_query_stream_type_rsp *rsp_buf;

	if (!handle) {
	if (!handle && !handle->qseecom_handle &&
		!handle->qseecom_handle->sbuf) {
		pr_err("invalid handle\n");
		return;
	}

	if (atomic_read(&handle->hdcp_off)) {
		pr_debug("invalid state, hdcp off\n");
		return;
	}

	/* send command to TZ */
	req_buf = (struct hdcp_query_stream_type_req *)handle->
			qseecom_handle->sbuf;
@@ -837,12 +844,12 @@ static int hdcp_lib_check_valid_state(struct hdcp_lib_handle *handle)
		}
	} else {
		if (atomic_read(&handle->hdcp_off)) {
			pr_warn("hdcp2.2 session tearing down\n");
			pr_debug("hdcp2.2 session tearing down\n");
			goto exit;
		}

		if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
			pr_warn("hdcp 2.2 app not loaded\n");
			pr_debug("hdcp 2.2 app not loaded\n");
			goto exit;
		}
	}
@@ -921,7 +928,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
	switch (handle->wakeup_cmd) {
	case HDCP_LIB_WKUP_CMD_START:
		handle->no_stored_km_flag = 0;
		handle->repeater_flag = 0;
		handle->repeater_flag = false;
		handle->update_stream = false;
		handle->last_msg_sent = 0;
		handle->hdcp_timeout = 0;
		handle->timeout_left = 0;
@@ -983,6 +991,10 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)

		if (!hdcp_lib_enable_encryption(handle)) {
			cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS;
			hdcp_lib_wakeup_client(handle, &cdata);

			/* poll for link check */
			cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		} else {
			if (!atomic_read(&handle->hdcp_off))
				HDCP_LIB_EXECUTE(clean);
@@ -990,6 +1002,13 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
		break;
	case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
		pr_debug("Repeater authentication successful\n");

		if (handle->update_stream) {
			HDCP_LIB_EXECUTE(stream);
			handle->update_stream = false;
		} else {
			cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		}
		break;
	default:
		cdata.cmd = HDMI_HDCP_WKUP_CMD_RECV_MESSAGE;
@@ -1060,6 +1079,17 @@ static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
		return;
	}

	if (!handle && !handle->qseecom_handle &&
		!handle->qseecom_handle->sbuf) {
		pr_debug("invalid handle\n");
		return;
	}

	if (atomic_read(&handle->hdcp_off)) {
		pr_debug("invalid state, hdcp off\n");
		return;
	}

	req_buf = (struct hdcp_send_timeout_req *)
		(handle->qseecom_handle->sbuf);
	req_buf->commandid = HDCP_TXMTR_SEND_MESSAGE_TIMEOUT;
@@ -1105,6 +1135,8 @@ static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
			hdcp_lib_send_message(handle);
		}
	}

	return;
error:
	if (!atomic_read(&handle->hdcp_off))
		HDCP_LIB_EXECUTE(clean);
@@ -1157,11 +1189,17 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
	uint32_t msglen;
	char *msg;

	if (!handle) {
	if (!handle && !handle->qseecom_handle &&
		!handle->qseecom_handle->sbuf) {
		pr_err("invalid handle\n");
		return;
	}

	if (atomic_read(&handle->hdcp_off)) {
		pr_debug("invalid state, hdcp off\n");
		return;
	}

	cdata.context = handle->client_ctx;

	mutex_lock(&handle->msg_lock);
@@ -1222,6 +1260,8 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
	if ((msg[0] == REPEATER_AUTH_STREAM_READY_MESSAGE_ID) &&
			(rc == 0) && (rsp_buf->status == 0)) {
		pr_debug("Got Auth_Stream_Ready, nothing sent to rx\n");

		cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		goto exit;
	}

@@ -1252,7 +1292,8 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
		if ((rsp_buf->flag ==
			HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST) &&
						(rsp_buf->timeout > 0))
			handle->repeater_flag = 1;
			handle->repeater_flag = true;
			handle->update_stream = true;
	}

	memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
+56 −36
Original line number Diff line number Diff line
/* Copyright (c) 2015 The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2016, 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
@@ -34,8 +34,6 @@
#define HDCP_SINK_DDC_HDCP2_RXSTATUS 0x70        /* RxStatus, 2 bytes */
#define HDCP_SINK_DDC_HDCP2_READ_MESSAGE 0x80    /* HDCP Tx reads here */

#define HDCP2P2_LINK_CHECK_TIME_MS 900 /* link check within 1 sec */

#define HDCP2P2_DEFAULT_TIMEOUT 500

/*
@@ -74,12 +72,14 @@ struct hdmi_hdcp2p2_ctrl {
	struct kthread_work send_msg;
	struct kthread_work recv_msg;
	struct kthread_work link;
	struct kthread_work poll;
};

static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl);
static void hdmi_hdcp2p2_send_msg(struct hdmi_hdcp2p2_ctrl *ctrl);
static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl);
static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl);
static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl);

static inline bool hdmi_hdcp2p2_is_valid_state(struct hdmi_hdcp2p2_ctrl *ctrl)
{
@@ -144,7 +144,7 @@ static int hdmi_hdcp2p2_wakeup(struct hdmi_hdcp_wakeup_data *data)
	ctrl->wakeup_cmd = data->cmd;

	if (data->timeout)
		ctrl->timeout = data->timeout;
		ctrl->timeout = data->timeout * 2;
	else
		ctrl->timeout = HDCP2P2_DEFAULT_TIMEOUT;

@@ -170,6 +170,9 @@ static int hdmi_hdcp2p2_wakeup(struct hdmi_hdcp_wakeup_data *data)
	case HDMI_HDCP_WKUP_CMD_STATUS_FAILED:
		queue_kthread_work(&ctrl->worker, &ctrl->status);
		break;
	case HDMI_HDCP_WKUP_CMD_LINK_POLL:
		queue_kthread_work(&ctrl->worker, &ctrl->poll);
		break;
	case HDMI_HDCP_WKUP_CMD_AUTHENTICATE:
		queue_kthread_work(&ctrl->worker, &ctrl->auth);
		break;
@@ -186,9 +189,6 @@ static inline int hdmi_hdcp2p2_wakeup_lib(struct hdmi_hdcp2p2_ctrl *ctrl,
{
	int rc = 0;

	if (ctrl)
		ctrl->wakeup_cmd = HDMI_HDCP_WKUP_CMD_INVALID;

	if (ctrl && ctrl->lib && ctrl->lib->wakeup &&
		data && (data->cmd != HDCP_LIB_WKUP_CMD_INVALID)) {
		rc = ctrl->lib->wakeup(data);
@@ -210,16 +210,20 @@ static void hdmi_hdcp2p2_run(struct hdmi_hdcp2p2_ctrl *ctrl)
	while (1) {
		switch (ctrl->wakeup_cmd) {
		case HDMI_HDCP_WKUP_CMD_SEND_MESSAGE:
			ctrl->wakeup_cmd = HDMI_HDCP_WKUP_CMD_INVALID;
			hdmi_hdcp2p2_send_msg(ctrl);
			break;

		case HDMI_HDCP_WKUP_CMD_RECV_MESSAGE:
			ctrl->wakeup_cmd = HDMI_HDCP_WKUP_CMD_INVALID;
			hdmi_hdcp2p2_recv_msg(ctrl);
			break;

		case HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS:
		case HDMI_HDCP_WKUP_CMD_STATUS_FAILED:
			hdmi_hdcp2p2_auth_status(ctrl);
			goto exit;
		case HDMI_HDCP_WKUP_CMD_LINK_POLL:
			hdmi_hdcp2p2_link_check(ctrl);
			goto exit;
		default:
			goto exit;
		}
@@ -726,6 +730,19 @@ static void hdmi_hdcp2p2_send_msg_work(struct kthread_work *work)
	hdmi_hdcp2p2_send_msg(ctrl);
}

static void hdmi_hdcp2p2_link_cb(void *data)
{
	struct hdmi_hdcp2p2_ctrl *ctrl = data;

	if (!ctrl) {
		pr_debug("invalid input\n");
		return;
	}

	if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
		queue_kthread_work(&ctrl->worker, &ctrl->link);
}

static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
{
	int rc, timeout_hsync;
@@ -770,7 +787,7 @@ static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
	pr_debug("timeout for rxstatus %dms, %d hsync\n",
		ctrl->timeout, timeout_hsync);

	ddc_data->intr_mask = RXSTATUS_MESSAGE_SIZE;
	ddc_data->intr_mask = RXSTATUS_MESSAGE_SIZE | RXSTATUS_REAUTH_REQ;
	ddc_data->timeout_ms = ctrl->timeout;
	ddc_data->timeout_hsync = timeout_hsync;
	ddc_data->periodic_timer_hsync = timeout_hsync / 20;
@@ -783,6 +800,14 @@ static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl)
		goto exit;
	}

	if (ddc_data->reauth_req) {
		ddc_data->reauth_req = false;

		pr_debug("reauth triggered by sink\n");
		rc = -EINVAL;
		goto exit;
	}

	ctrl->timeout_left = ddc_data->timeout_left;

	pr_debug("timeout left after rxstatus %dms, msg size %d\n",
@@ -817,7 +842,6 @@ exit:
	else if (rc)
		cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED;


	hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
	kfree(recvd_msg_buf);
}
@@ -830,19 +854,6 @@ static void hdmi_hdcp2p2_recv_msg_work(struct kthread_work *work)
	hdmi_hdcp2p2_recv_msg(ctrl);
}

static void hdmi_hdcp2p2_link_cb(void *data)
{
	struct hdmi_hdcp2p2_ctrl *ctrl = data;

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE)
		queue_kthread_work(&ctrl->worker, &ctrl->link);
}

static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
{
	struct hdmi_tx_ddc_ctrl *ddc_ctrl;
@@ -860,8 +871,7 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
	memset(ddc_data, 0, sizeof(*ddc_data));

	timeout_hsync = hdmi_utils_get_timeout_in_hysnc(
		ctrl->init_data.timing,
		jiffies_to_msecs((HZ / 2) + (HZ / 4)));
		ctrl->init_data.timing, jiffies_to_msecs(HZ / 2));

	if (timeout_hsync <= 0) {
		pr_err("err in timeout hsync calc\n");
@@ -880,6 +890,14 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl)
	return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl);
}

static void hdmi_hdcp2p2_poll_work(struct kthread_work *work)
{
	struct hdmi_hdcp2p2_ctrl *ctrl = container_of(work,
		struct hdmi_hdcp2p2_ctrl, poll);

	hdmi_hdcp2p2_link_check(ctrl);
}

static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl)
{
	if (!ctrl) {
@@ -898,6 +916,9 @@ static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl)
		ctrl->init_data.notify_status(ctrl->init_data.cb_data,
			HDCP_STATE_AUTHENTICATED);

		atomic_set(&ctrl->auth_state, HDCP_STATE_AUTHENTICATED);

		if (ctrl->tethered)
			hdmi_hdcp2p2_link_check(ctrl);
	}
}
@@ -934,16 +955,12 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work)
		goto exit;
	}

	rc = hdmi_hdcp2p2_ddc_check_status(ddc_ctrl);
	if (rc) {
		cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
		goto exit;
	}

	ddc_data = &ddc_ctrl->hdcp2p2_ddc_data;

	if (ddc_data->reauth_req) {
		pr_debug("sync reported loss of synchronization, reauth\n");
		pr_debug("reauth triggered by sink\n");

		ddc_data->reauth_req = false;
		rc = -ENOLINK;
		cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
		goto exit;
@@ -953,6 +970,8 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work)
		pr_debug("topology changed. rxstatus msg size %d\n",
			ddc_data->message_size);

		ddc_data->ready  = false;

		recvd_msg_buf = kzalloc(ddc_data->message_size, GFP_KERNEL);
		if (!recvd_msg_buf) {
			cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
@@ -968,9 +987,9 @@ static void hdmi_hdcp2p2_link_work(struct kthread_work *work)
			cdata.cmd = HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS;
			cdata.recvd_msg_buf = recvd_msg_buf;
			cdata.recvd_msg_len = ddc_data->message_size;

			hdmi_hdcp2p2_link_check(ctrl);
		}

		ddc_data->message_size = 0;
	}
exit:
	hdmi_hdcp2p2_wakeup_lib(ctrl, &cdata);
@@ -1117,6 +1136,7 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data)
	init_kthread_work(&ctrl->recv_msg, hdmi_hdcp2p2_recv_msg_work);
	init_kthread_work(&ctrl->status,   hdmi_hdcp2p2_auth_status_work);
	init_kthread_work(&ctrl->link,     hdmi_hdcp2p2_link_work);
	init_kthread_work(&ctrl->poll,     hdmi_hdcp2p2_poll_work);

	ctrl->thread = kthread_run(kthread_worker_fn,
		&ctrl->worker, "hdmi_hdcp2p2");
+11 −29
Original line number Diff line number Diff line
/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2016, 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
@@ -65,8 +65,6 @@ static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
	u32 ddc_int_ctrl, ddc_status, in_use, timeout;
	u32 sw_done_mask = BIT(2);
	u32 sw_done_ack  = BIT(1);
	u32 hw_done_mask = BIT(6);
	u32 hw_done_ack  = BIT(5);
	u32 in_use_by_sw = BIT(0);
	u32 in_use_by_hw = BIT(1);

@@ -76,7 +74,7 @@ static int hdmi_ddc_clear_irq(struct hdmi_tx_ddc_ctrl *ddc_ctrl,
	}

	/* clear and enable interrutps */
	ddc_int_ctrl = sw_done_mask | sw_done_ack | hw_done_mask | hw_done_ack;
	ddc_int_ctrl = sw_done_mask | sw_done_ack;

	DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_INT_CTRL, ddc_int_ctrl);

@@ -871,46 +869,39 @@ void hdmi_ddc_config(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
	DSS_REG_W_ND(ddc_ctrl->io, HDMI_DDC_REF, (1 << 16) | (19 << 0));
} /* hdmi_ddc_config */

int hdmi_hdcp2p2_ddc_check_status(struct hdmi_tx_ddc_ctrl *ctrl)
static void hdmi_hdcp2p2_ddc_clear_status(struct hdmi_tx_ddc_ctrl *ctrl)
{
	int rc = 0;
	u32 reg_val;

	if (!ctrl) {
		pr_err("invalid ddc ctrl\n");
		return -EINVAL;
		return;
	}

	/* check for errors and clear status */
	reg_val = DSS_REG_R(ctrl->io, HDMI_HDCP2P2_DDC_STATUS);

	if (reg_val & BIT(4)) {
		pr_err("ddc aborted\n");
		pr_debug("ddc aborted\n");
		reg_val |= BIT(5);
		rc = -ECONNABORTED;
	}

	if (reg_val & BIT(8)) {
		pr_err("timed out\n");
		pr_debug("timed out\n");
		reg_val |= BIT(9);
		rc = -ETIMEDOUT;
	}

	if (reg_val & BIT(12)) {
		pr_err("NACK0\n");
		pr_debug("NACK0\n");
		reg_val |= BIT(13);
		rc = -EIO;
	}

	if (reg_val & BIT(14)) {
		pr_err("NACK1\n");
		pr_debug("NACK1\n");
		reg_val |= BIT(15);
		rc = -EIO;
	}

	DSS_REG_W(ctrl->io, HDMI_HDCP2P2_DDC_STATUS, reg_val);

	return rc;
}

static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
@@ -987,15 +978,6 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
		data->ready = true;
	}

	/* check and disable not ready interrupt */
	if (intr0 & BIT(15)) {
		/* ack ready/not ready interrupt */
		intr0 |= BIT(17);

		intr0 &= ~BIT(19);
		data->ready = false;
	}

	/* check for reauth req interrupt */
	if (intr0 & BIT(12)) {
		/* ack and disable reauth req interrupt */
@@ -1053,6 +1035,8 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl)
		}
	}

	hdmi_hdcp2p2_ddc_clear_status(ddc_ctrl);

	return rc;
}

@@ -1641,7 +1625,6 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl)

	intr_en_mask = data->intr_mask;
	intr_en_mask |= BIT(HDCP2P2_RXSTATUS_DDC_FAILED_INTR_MASK);
	intr_en_mask |= BIT(HDCP2P2_RXSTATUS_DDC_DONE);

	/* Disable short read for now, sinks don't support it */
	reg_val = DSS_REG_R(ctrl->io, HDMI_HDCP2P2_DDC_CTRL);
@@ -1675,7 +1658,7 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl)
	/* Clear interrupt status bits */
	reg_val |= intr_en_mask >> 1;

	pr_debug("writng HDMI_DDC_INT_CTRL0 0x%x\n", reg_val);
	pr_debug("writing HDMI_DDC_INT_CTRL0 0x%x\n", reg_val);
	DSS_REG_W(ctrl->io, HDMI_DDC_INT_CTRL0, reg_val);

	reg_val = DSS_REG_R(ctrl->io, HDMI_DDC_INT_CTRL5);
@@ -1730,7 +1713,6 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl)
			rc = -ETIMEDOUT;
		}

		rc = hdmi_hdcp2p2_ddc_check_status(ctrl);
		hdmi_hdcp2p2_ddc_disable(ctrl);
	}

+1 −2
Original line number Diff line number Diff line
/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2016, 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
@@ -504,7 +504,6 @@ int hdmi_setup_ddc_timers(struct hdmi_tx_ddc_ctrl *ctrl,
			  u32 type, u32 to_in_num_lines);
void hdmi_scrambler_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl);
void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_hdcp2p2_ddc_check_status(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl);
int hdmi_utils_get_timeout_in_hysnc(struct msm_hdmi_mode_timing_info *timing,
	u32 timeout_ms);
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2016, 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
@@ -32,6 +32,7 @@ enum hdmi_hdcp_wakeup_cmd {
	HDMI_HDCP_WKUP_CMD_RECV_MESSAGE,
	HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS,
	HDMI_HDCP_WKUP_CMD_STATUS_FAILED,
	HDMI_HDCP_WKUP_CMD_LINK_POLL,
	HDMI_HDCP_WKUP_CMD_AUTHENTICATE
};

@@ -62,6 +63,8 @@ static inline char *hdmi_hdcp_cmd_to_str(uint32_t cmd)
		return "HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS";
	case HDMI_HDCP_WKUP_CMD_STATUS_FAILED:
		return "HDMI_HDCP_WKUP_CMD_STATUS_FAIL";
	case HDMI_HDCP_WKUP_CMD_LINK_POLL:
		return "HDMI_HDCP_WKUP_CMD_LINK_POLL";
	case HDMI_HDCP_WKUP_CMD_AUTHENTICATE:
		return "HDMI_HDCP_WKUP_CMD_AUTHENTICATE";
	default: