summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjay Singh Parmar <aparmar@codeaurora.org>2016-10-20 17:13:19 -0700
committerAjay Singh Parmar <aparmar@codeaurora.org>2016-10-27 15:16:42 -0700
commit01cb3026c647fecaf22449ed25548c590cd5c1c8 (patch)
tree751daa48d3363c5d3851a73ba60ffdf6b6f86146
parent821b280d6a83e16825039c097829f663b2d7f577 (diff)
msm: mdss: hdcp2p2: fix deadlock during re-authentication
Fix the dead lock happening during re-authentication where threads were waiting for each other during clearing the last session and starting a new one. Change-Id: Ife18adde8349acb92b22e228d0bbc18edbf2c90e Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
-rw-r--r--drivers/misc/hdcp.c89
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.c63
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c114
-rw-r--r--drivers/video/fbdev/msm/mdss_hdcp.h1
-rw-r--r--include/linux/hdcp_qseecom.h3
6 files changed, 141 insertions, 131 deletions
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 76add503b6b8..8b7c16e9175d 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -616,32 +616,53 @@ static int hdcp_lib_get_next_message(struct hdcp_lib_handle *handle,
}
}
-static inline void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
- struct hdmi_hdcp_wakeup_data *data)
+static void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
+ struct hdmi_hdcp_wakeup_data *data)
{
- int rc = 0;
+ int rc = 0, i;
- if (handle && handle->client_ops && handle->client_ops->wakeup &&
- data && (data->cmd != HDMI_HDCP_WKUP_CMD_INVALID)) {
- data->abort_mask = REAUTH_REQ | LINK_INTEGRITY_FAILURE;
+ if (!handle || !handle->client_ops || !handle->client_ops->wakeup ||
+ !data || (data->cmd == HDMI_HDCP_WKUP_CMD_INVALID))
+ return;
- if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE ||
- data->cmd == HDMI_HDCP_WKUP_CMD_RECV_MESSAGE ||
- data->cmd == HDMI_HDCP_WKUP_CMD_LINK_POLL) {
- handle->last_msg =
- hdcp_lib_get_next_message(handle, data);
+ data->abort_mask = REAUTH_REQ | LINK_INTEGRITY_FAILURE;
- if (handle->last_msg > INVALID_MESSAGE_ID &&
- handle->last_msg < HDCP2P2_MAX_MESSAGES)
- data->message_data =
- &hdcp_msg_lookup[handle->last_msg];
- }
+ if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE ||
+ data->cmd == HDMI_HDCP_WKUP_CMD_RECV_MESSAGE ||
+ data->cmd == HDMI_HDCP_WKUP_CMD_LINK_POLL) {
+ handle->last_msg = hdcp_lib_get_next_message(handle, data);
- rc = handle->client_ops->wakeup(data);
- if (rc)
- pr_err("error sending %s to client\n",
- hdmi_hdcp_cmd_to_str(data->cmd));
+ pr_debug("lib->client: %s (%s)\n",
+ hdmi_hdcp_cmd_to_str(data->cmd),
+ hdcp_lib_message_name(handle->last_msg));
+
+ if (handle->last_msg > INVALID_MESSAGE_ID &&
+ handle->last_msg < HDCP2P2_MAX_MESSAGES) {
+ u32 msg_num, rx_status;
+ const struct hdcp_msg_part *msg;
+
+ data->message_data = &hdcp_msg_lookup[handle->last_msg];
+
+ msg_num = data->message_data->num_messages;
+ msg = data->message_data->messages;
+ rx_status = data->message_data->rx_status;
+
+ pr_debug("rxstatus 0x%x\n", rx_status);
+ pr_debug("%6s | %4s\n", "offset", "len");
+
+ for (i = 0; i < msg_num; i++)
+ pr_debug("%6x | %4d\n",
+ msg[i].offset, msg[i].length);
+ }
+ } else {
+ pr_debug("lib->client: %s\n",
+ hdmi_hdcp_cmd_to_str(data->cmd));
}
+
+ rc = handle->client_ops->wakeup(data);
+ if (rc)
+ pr_err("error sending %s to client\n",
+ hdmi_hdcp_cmd_to_str(data->cmd));
}
static inline void hdcp_lib_send_message(struct hdcp_lib_handle *handle)
@@ -1486,6 +1507,7 @@ static int hdcp_lib_check_valid_state(struct hdcp_lib_handle *handle)
if (handle->wakeup_cmd == HDCP_LIB_WKUP_CMD_START) {
if (!list_empty(&handle->worker.work_list)) {
+ pr_debug("error: queue not empty\n");
rc = -EBUSY;
goto exit;
}
@@ -1543,9 +1565,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
handle->wakeup_cmd = data->cmd;
handle->timeout_left = data->timeout;
- pr_debug("%s, timeout left: %dms, tethered %d\n",
- hdcp_lib_cmd_to_str(handle->wakeup_cmd),
- handle->timeout_left, handle->tethered);
+ pr_debug("client->lib: %s\n",
+ hdcp_lib_cmd_to_str(handle->wakeup_cmd));
rc = hdcp_lib_check_valid_state(handle);
if (rc)
@@ -1599,6 +1620,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
break;
case HDCP_LIB_WKUP_CMD_MSG_SEND_FAILED:
case HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED:
+ case HDCP_LIB_WKUP_CMD_LINK_FAILED:
+ handle->hdcp_state |= HDCP_STATE_ERROR;
HDCP_LIB_EXECUTE(clean);
break;
case HDCP_LIB_WKUP_CMD_MSG_RECV_SUCCESS:
@@ -1825,7 +1848,7 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
if (!handle) {
pr_err("invalid input\n");
return;
- };
+ }
hdcp_lib_txmtr_deinit(handle);
if (!handle->legacy_app)
@@ -1859,6 +1882,7 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
struct hdcp_rcvd_msg_rsp *rsp_buf;
uint32_t msglen;
char *msg = NULL;
+ char msg_name[50];
uint32_t message_id_bytes = 0;
if (!handle || !handle->qseecom_handle ||
@@ -1907,8 +1931,11 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
mutex_unlock(&handle->msg_lock);
- pr_debug("msg received: %s from sink\n",
- hdcp_lib_message_name((int)msg[0]));
+ snprintf(msg_name, sizeof(msg_name), "%s: ",
+ hdcp_lib_message_name((int)msg[0]));
+
+ print_hex_dump(KERN_DEBUG, msg_name,
+ DUMP_PREFIX_NONE, 16, 1, msg, msglen, false);
/* send the message to QSEECOM */
req_buf = (struct hdcp_rcvd_msg_req *)(handle->qseecom_handle->sbuf);
@@ -2026,6 +2053,16 @@ static void hdcp_lib_topology_work(struct kthread_work *work)
return;
}
+ if (atomic_read(&handle->hdcp_off)) {
+ pr_debug("invalid state: hdcp off\n");
+ return;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_ERROR) {
+ pr_debug("invalid state: hdcp error\n");
+ return;
+ }
+
reinit_completion(&handle->topo_wait);
timeout = wait_for_completion_timeout(&handle->topo_wait, HZ * 3);
if (!timeout) {
diff --git a/drivers/video/fbdev/msm/mdss_dp.c b/drivers/video/fbdev/msm/mdss_dp.c
index dea326a2fc76..dbaf3247e8bb 100644
--- a/drivers/video/fbdev/msm/mdss_dp.c
+++ b/drivers/video/fbdev/msm/mdss_dp.c
@@ -1620,22 +1620,18 @@ end:
return rc;
}
-static void mdss_dp_hdcp_cb(void *ptr, enum hdcp_states status)
+static void mdss_dp_hdcp_cb_work(struct work_struct *work)
{
- struct mdss_dp_drv_pdata *dp = ptr;
+ struct mdss_dp_drv_pdata *dp;
+ struct delayed_work *dw = to_delayed_work(work);
struct hdcp_ops *ops;
int rc = 0;
- if (!dp) {
- pr_debug("invalid input\n");
- return;
- }
+ dp = container_of(dw, struct mdss_dp_drv_pdata, hdcp_cb_work);
ops = dp->hdcp.ops;
- mutex_lock(&dp->train_mutex);
-
- switch (status) {
+ switch (dp->hdcp_status) {
case HDCP_STATE_AUTHENTICATED:
pr_debug("hdcp authenticated\n");
dp->hdcp.auth_state = true;
@@ -1658,8 +1654,20 @@ static void mdss_dp_hdcp_cb(void *ptr, enum hdcp_states status)
default:
break;
}
+}
- mutex_unlock(&dp->train_mutex);
+static void mdss_dp_hdcp_cb(void *ptr, enum hdcp_states status)
+{
+ struct mdss_dp_drv_pdata *dp = ptr;
+
+ if (!dp) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ dp->hdcp_status = status;
+
+ queue_delayed_work(dp->workq, &dp->hdcp_cb_work, HZ/4);
}
static int mdss_dp_hdcp_init(struct mdss_panel_data *pdata)
@@ -1888,6 +1896,13 @@ static void mdss_dp_update_hdcp_info(struct mdss_dp_drv_pdata *dp)
dp->hdcp.ops = ops;
}
+static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
+{
+ return dp_drv->hdcp.feature_enabled &&
+ (dp_drv->hdcp.hdcp1_present || dp_drv->hdcp.hdcp2_present) &&
+ dp_drv->hdcp.ops;
+}
+
static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
int event, void *arg)
{
@@ -1919,8 +1934,10 @@ static int mdss_dp_event_handler(struct mdss_panel_data *pdata,
rc = mdss_dp_off(pdata);
break;
case MDSS_EVENT_BLANK:
- if (dp->hdcp.ops && dp->hdcp.ops->off)
+ if (dp_is_hdcp_enabled(dp) && dp->hdcp.ops->off) {
+ flush_delayed_work(&dp->hdcp_cb_work);
dp->hdcp.ops->off(dp->hdcp.data);
+ }
mdss_dp_mainlink_push_idle(pdata);
break;
@@ -2197,6 +2214,11 @@ irqreturn_t dp_isr(int irq, void *ptr)
dp_aux_native_handler(dp, isr1);
}
+ if (dp->hdcp.ops && dp->hdcp.ops->isr) {
+ if (dp->hdcp.ops->isr(dp->hdcp.data))
+ pr_err("dp_hdcp_isr failed\n");
+ }
+
return IRQ_HANDLED;
}
@@ -2211,6 +2233,7 @@ static int mdss_dp_event_setup(struct mdss_dp_drv_pdata *dp)
}
INIT_WORK(&dp->work, mdss_dp_event_work);
+ INIT_DELAYED_WORK(&dp->hdcp_cb_work, mdss_dp_hdcp_cb_work);
return 0;
}
@@ -2434,8 +2457,6 @@ static void mdss_dp_process_hpd_irq_high(struct mdss_dp_drv_pdata *dp)
{
int ret = 0;
- pr_debug("enter: HPD IRQ High\n");
-
dp->hpd_irq_on = true;
mdss_dp_aux_parse_sink_status_field(dp);
@@ -2523,6 +2544,12 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
dp_drv->alt_mode.dp_status.hpd_irq;
if (dp_drv->alt_mode.dp_status.hpd_irq) {
+ pr_debug("Attention: hpd_irq high\n");
+
+ if (dp_drv->power_on && dp_drv->hdcp.ops &&
+ dp_drv->hdcp.ops->cp_irq)
+ dp_drv->hdcp.ops->cp_irq(dp_drv->hdcp.data);
+
mdss_dp_process_hpd_irq_high(dp_drv);
break;
}
@@ -2552,9 +2579,6 @@ static void usbpd_response_callback(struct usbpd_svid_handler *hdlr, u8 cmd,
else
dp_send_events(dp_drv, EV_USBPD_DP_CONFIGURE);
- if (dp_drv->alt_mode.dp_status.hpd_irq && dp_drv->power_on &&
- dp_drv->hdcp.ops && dp_drv->hdcp.ops->isr)
- dp_drv->hdcp.ops->isr(dp_drv->hdcp.data);
break;
case DP_VDM_STATUS:
dp_drv->alt_mode.dp_status.response = *vdos;
@@ -2770,13 +2794,6 @@ void *mdss_dp_get_hdcp_data(struct device *dev)
return dp_drv->hdcp.data;
}
-static inline bool dp_is_hdcp_enabled(struct mdss_dp_drv_pdata *dp_drv)
-{
- return dp_drv->hdcp.feature_enabled &&
- (dp_drv->hdcp.hdcp1_present || dp_drv->hdcp.hdcp2_present) &&
- dp_drv->hdcp.ops;
-}
-
static inline bool dp_is_stream_shareable(struct mdss_dp_drv_pdata *dp_drv)
{
bool ret = 0;
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index 0d4e8da90da5..cfacbfa1d413 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -484,6 +484,7 @@ struct mdss_dp_drv_pdata {
/* event */
struct workqueue_struct *workq;
struct work_struct work;
+ struct delayed_work hdcp_cb_work;
u32 current_event;
spinlock_t event_lock;
spinlock_t lock;
@@ -494,6 +495,7 @@ struct mdss_dp_drv_pdata {
u32 vic;
u32 new_vic;
int fb_node;
+ int hdcp_status;
struct dpcd_test_request test_data;
struct dpcd_sink_count sink_count;
diff --git a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
index 3891806b09bb..a5146437978b 100644
--- a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
+++ b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c
@@ -53,7 +53,6 @@ struct dp_hdcp2p2_ctrl {
struct kthread_work send_msg;
struct kthread_work recv_msg;
struct kthread_work link;
- struct kthread_work poll;
char *msg_buf;
uint32_t send_msg_len; /* length of all parameters in msg */
uint32_t timeout;
@@ -67,26 +66,6 @@ struct dp_hdcp2p2_ctrl {
bool polling;
};
-static inline char *dp_hdcp_cmd_to_str(uint32_t cmd)
-{
- switch (cmd) {
- case HDMI_HDCP_WKUP_CMD_SEND_MESSAGE:
- return "HDMI_HDCP_WKUP_CMD_SEND_MESSAGE";
- case HDMI_HDCP_WKUP_CMD_RECV_MESSAGE:
- return "HDMI_HDCP_WKUP_CMD_RECV_MESSAGE";
- case HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS:
- return "HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS";
- case HDMI_HDCP_WKUP_CMD_STATUS_FAILED:
- return "DP_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:
- return "???";
- }
-}
-
static inline bool dp_hdcp2p2_is_valid_state(struct dp_hdcp2p2_ctrl *ctrl)
{
if (ctrl->wakeup_cmd == HDMI_HDCP_WKUP_CMD_AUTHENTICATE)
@@ -193,7 +172,7 @@ static int dp_hdcp2p2_wakeup(struct hdmi_hdcp_wakeup_data *data)
queue_kthread_work(&ctrl->worker, &ctrl->status);
break;
case HDMI_HDCP_WKUP_CMD_LINK_POLL:
- queue_kthread_work(&ctrl->worker, &ctrl->poll);
+ ctrl->polling = true;
break;
case HDMI_HDCP_WKUP_CMD_AUTHENTICATE:
queue_kthread_work(&ctrl->worker, &ctrl->auth);
@@ -203,10 +182,11 @@ static int dp_hdcp2p2_wakeup(struct hdmi_hdcp_wakeup_data *data)
}
exit:
mutex_unlock(&ctrl->wakeup_mutex);
+
return 0;
}
-static inline int dp_hdcp2p2_wakeup_lib(struct dp_hdcp2p2_ctrl *ctrl,
+static inline void dp_hdcp2p2_wakeup_lib(struct dp_hdcp2p2_ctrl *ctrl,
struct hdcp_lib_wakeup_data *data)
{
int rc = 0;
@@ -218,8 +198,6 @@ static inline int dp_hdcp2p2_wakeup_lib(struct dp_hdcp2p2_ctrl *ctrl,
pr_err("error sending %s to lib\n",
hdcp_lib_cmd_to_str(data->cmd));
}
-
- return rc;
}
static void dp_hdcp2p2_reset(struct dp_hdcp2p2_ctrl *ctrl)
@@ -339,8 +317,6 @@ static void dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl)
return;
}
- atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
-
/* notify DP about HDCP failure */
ctrl->init_data.notify_status(ctrl->init_data.cb_data,
HDCP_STATE_AUTH_FAIL);
@@ -349,8 +325,7 @@ static void dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl)
static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl,
u8 *buf, int size, int offset, u32 timeout)
{
- int rc, max_size = 16, read_size, len = size;
- u8 *buf_start = buf;
+ int rc, max_size = 16, read_size;
if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
pr_err("hdcp is off\n");
@@ -378,8 +353,6 @@ static int dp_hdcp2p2_aux_read_message(struct dp_hdcp2p2_ctrl *ctrl,
size -= read_size;
} while (size > 0);
- print_hex_dump(KERN_DEBUG, "hdcp2p2: ", DUMP_PREFIX_NONE,
- 16, 1, buf_start, len, false);
return rc;
}
@@ -550,7 +523,6 @@ exit:
static void dp_hdcp2p2_recv_msg_work(struct kthread_work *work)
{
- int rc = 0;
struct hdcp_lib_wakeup_data cdata = { HDCP_LIB_WKUP_CMD_INVALID };
struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
struct dp_hdcp2p2_ctrl, recv_msg);
@@ -559,44 +531,24 @@ static void dp_hdcp2p2_recv_msg_work(struct kthread_work *work)
if (atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) {
pr_err("hdcp is off\n");
- goto exit;
+ return;
}
- if (ctrl->sink_rx_status & ctrl->abort_mask) {
- pr_err("reauth or Link fail triggered by sink\n");
-
- ctrl->sink_rx_status = 0;
- rc = -ENOLINK;
- cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
-
- goto exit;
- }
+ if (ctrl->rx_status) {
+ if (!ctrl->cp_irq_done) {
+ pr_debug("waiting for CP_IRQ\n");
+ ctrl->polling = true;
+ return;
+ }
- if (ctrl->rx_status && !ctrl->sink_rx_status) {
- pr_debug("Recv msg for RxStatus, but no CP_IRQ yet\n");
- ctrl->polling = true;
- goto exit;
+ if (ctrl->rx_status & ctrl->sink_rx_status) {
+ ctrl->cp_irq_done = false;
+ ctrl->sink_rx_status = 0;
+ ctrl->rx_status = 0;
+ }
}
dp_hdcp2p2_get_msg_from_sink(ctrl);
-
- return;
-exit:
- if (rc)
- dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
-}
-
-static void dp_hdcp2p2_poll_work(struct kthread_work *work)
-{
- struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
- struct dp_hdcp2p2_ctrl, poll);
-
- if (ctrl->cp_irq_done) {
- ctrl->cp_irq_done = false;
- dp_hdcp2p2_get_msg_from_sink(ctrl);
- } else {
- ctrl->polling = true;
- }
}
static void dp_hdcp2p2_auth_status_work(struct kthread_work *work)
@@ -645,44 +597,45 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work)
if (rc) {
pr_err("failed to read rx status\n");
- cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
+ cdata.cmd = HDCP_LIB_WKUP_CMD_LINK_FAILED;
+ atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
goto exit;
}
if (ctrl->sink_rx_status & ctrl->abort_mask) {
- pr_err("reauth or Link fail triggered by sink\n");
+ if (ctrl->sink_rx_status & BIT(3))
+ pr_err("reauth_req set by sink\n");
+
+ if (ctrl->sink_rx_status & BIT(4))
+ pr_err("link failure reported by sink\n");
ctrl->sink_rx_status = 0;
ctrl->rx_status = 0;
rc = -ENOLINK;
- cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
+
+ cdata.cmd = HDCP_LIB_WKUP_CMD_LINK_FAILED;
+ atomic_set(&ctrl->auth_state, HDCP_STATE_AUTH_FAIL);
goto exit;
}
- /* if polling, get message from sink else let polling start */
if (ctrl->polling && (ctrl->sink_rx_status & ctrl->rx_status)) {
ctrl->sink_rx_status = 0;
ctrl->rx_status = 0;
- rc = dp_hdcp2p2_get_msg_from_sink(ctrl);
+ dp_hdcp2p2_get_msg_from_sink(ctrl);
ctrl->polling = false;
} else {
ctrl->cp_irq_done = true;
}
exit:
- dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
-
- if (rc) {
- dp_hdcp2p2_auth_failed(ctrl);
- return;
- }
+ if (rc)
+ dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
}
static void dp_hdcp2p2_auth_work(struct kthread_work *work)
{
- int rc = 0;
struct hdcp_lib_wakeup_data cdata = {HDCP_LIB_WKUP_CMD_INVALID};
struct dp_hdcp2p2_ctrl *ctrl = container_of(work,
struct dp_hdcp2p2_ctrl, auth);
@@ -694,12 +647,10 @@ static void dp_hdcp2p2_auth_work(struct kthread_work *work)
else
cdata.cmd = HDCP_LIB_WKUP_CMD_STOP;
- rc = dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
- if (rc)
- dp_hdcp2p2_auth_failed(ctrl);
+ dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
}
-static int dp_hdcp2p2_isr(void *input)
+static int dp_hdcp2p2_cp_irq(void *input)
{
struct dp_hdcp2p2_ctrl *ctrl = input;
@@ -748,7 +699,7 @@ void *dp_hdcp2p2_init(struct hdcp_init_data *init_data)
.authenticate = dp_hdcp2p2_authenticate,
.feature_supported = dp_hdcp2p2_feature_supported,
.off = dp_hdcp2p2_off,
- .isr = dp_hdcp2p2_isr
+ .cp_irq = dp_hdcp2p2_cp_irq,
};
static struct hdcp_client_ops client_ops = {
@@ -806,7 +757,6 @@ void *dp_hdcp2p2_init(struct hdcp_init_data *init_data)
init_kthread_work(&ctrl->recv_msg, dp_hdcp2p2_recv_msg_work);
init_kthread_work(&ctrl->status, dp_hdcp2p2_auth_status_work);
init_kthread_work(&ctrl->link, dp_hdcp2p2_link_work);
- init_kthread_work(&ctrl->poll, dp_hdcp2p2_poll_work);
ctrl->thread = kthread_run(kthread_worker_fn,
&ctrl->worker, "dp_hdcp2p2");
diff --git a/drivers/video/fbdev/msm/mdss_hdcp.h b/drivers/video/fbdev/msm/mdss_hdcp.h
index d373d22384e8..6e347a867366 100644
--- a/drivers/video/fbdev/msm/mdss_hdcp.h
+++ b/drivers/video/fbdev/msm/mdss_hdcp.h
@@ -55,6 +55,7 @@ struct hdcp_init_data {
struct hdcp_ops {
int (*isr)(void *ptr);
+ int (*cp_irq)(void *ptr);
int (*reauthenticate)(void *input);
int (*authenticate)(void *hdcp_ctrl);
bool (*feature_supported)(void *input);
diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h
index f66264bc935a..6ad79378737e 100644
--- a/include/linux/hdcp_qseecom.h
+++ b/include/linux/hdcp_qseecom.h
@@ -26,6 +26,7 @@ enum hdcp_lib_wakeup_cmd {
HDCP_LIB_WKUP_CMD_MSG_RECV_FAILED,
HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT,
HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE,
+ HDCP_LIB_WKUP_CMD_LINK_FAILED,
};
enum hdmi_hdcp_wakeup_cmd {
@@ -106,6 +107,8 @@ static inline char *hdcp_lib_cmd_to_str(uint32_t cmd)
return "HDCP_LIB_WKUP_CMD_MSG_RECV_TIMEOUT";
case HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE:
return "HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE";
+ case HDCP_LIB_WKUP_CMD_LINK_FAILED:
+ return "HDCP_LIB_WKUP_CMD_LINK_FAILED";
default:
return "???";
}