From 19b7c1036c992e19e6bc350f6b4cb6a795c9e2e9 Mon Sep 17 00:00:00 2001 From: Ajay Singh Parmar Date: Mon, 9 Jan 2017 15:27:51 -0800 Subject: [PATCH] msm: mdss: hdcp2p2: do not process interrupts in failed state Interrupts from sinks (cp_irq) may come asynchronously at different states for HDCP authentications. In case HDCP has failed and an interrupt is received from sink, do not process it to avoid getting unnecessary failures. Change-Id: I00b0d45fdbdc3d43ac49908db66573d6d4b58283 Signed-off-by: Ajay Singh Parmar --- drivers/misc/hdcp.c | 27 ++++++++++++++--------- drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c | 17 +++++++++++++- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c index efb987b4a6b6..038c7a94aca3 100644 --- a/drivers/misc/hdcp.c +++ b/drivers/misc/hdcp.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, 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 @@ -805,8 +805,8 @@ static int hdcp_lib_get_version(struct hdcp_lib_handle *handle) goto exit; } - if (handle->hdcp_state & HDCP_STATE_APP_LOADED) { - pr_err("library already loaded\n"); + if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) { + pr_err("library not loaded\n"); return rc; } @@ -901,8 +901,8 @@ static int hdcp_app_init_legacy(struct hdcp_lib_handle *handle) goto exit; } - if (handle->hdcp_state & HDCP_STATE_APP_LOADED) { - pr_err("library already loaded\n"); + if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) { + pr_err("library not loaded\n"); goto exit; } @@ -949,8 +949,8 @@ static int hdcp_app_init(struct hdcp_lib_handle *handle) goto exit; } - if (handle->hdcp_state & HDCP_STATE_APP_LOADED) { - pr_err("library already loaded\n"); + if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) { + pr_err("library not loaded\n"); goto exit; } @@ -1024,6 +1024,7 @@ static int hdcp_lib_library_load(struct hdcp_lib_handle *handle) goto exit; } + handle->hdcp_state |= HDCP_STATE_APP_LOADED; pr_debug("qseecom_start_app success\n"); rc = hdcp_lib_get_version(handle); @@ -1050,8 +1051,6 @@ static int hdcp_lib_library_load(struct hdcp_lib_handle *handle) pr_err("app init failed\n"); goto exit; } - - handle->hdcp_state |= HDCP_STATE_APP_LOADED; exit: return rc; } @@ -1240,8 +1239,8 @@ static int hdcp_lib_txmtr_init(struct hdcp_lib_handle *handle) goto exit; } - if (handle->hdcp_state & HDCP_STATE_TXMTR_INIT) { - pr_err("txmtr already initialized\n"); + if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) { + pr_err("library not loaded\n"); goto exit; } @@ -1622,6 +1621,12 @@ static int hdcp_lib_check_valid_state(struct hdcp_lib_handle *handle) rc = -EBUSY; goto exit; } + + if (handle->hdcp_state & HDCP_STATE_APP_LOADED) { + pr_debug("library already loaded\n"); + rc = -EBUSY; + goto exit; + } } else { if (atomic_read(&handle->hdcp_off)) { pr_debug("hdcp2.2 session tearing down\n"); diff --git a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c index 73b9ad65482f..3bcacf945761 100644 --- a/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c +++ b/drivers/video/fbdev/msm/mdss_dp_hdcp2p2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 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 @@ -370,6 +370,8 @@ static void dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl) dp_hdcp2p2_set_interrupts(ctrl, false); + 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); @@ -625,6 +627,12 @@ static void dp_hdcp2p2_link_work(struct kthread_work *work) return; } + if (atomic_read(&ctrl->auth_state) == HDCP_STATE_AUTH_FAIL || + atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) { + pr_err("invalid hdcp state\n"); + return; + } + cdata.context = ctrl->lib_ctx; if (ctrl->sink_rx_status & ctrl->abort_mask) { @@ -685,6 +693,13 @@ static int dp_hdcp2p2_cp_irq(void *input) return -EINVAL; } + if (atomic_read(&ctrl->auth_state) == HDCP_STATE_AUTH_FAIL || + atomic_read(&ctrl->auth_state) == HDCP_STATE_INACTIVE) { + pr_err("invalid hdcp state\n"); + rc = -EINVAL; + goto error; + } + ctrl->sink_rx_status = 0; rc = mdss_dp_aux_read_rx_status(ctrl->init_data.cb_data, &ctrl->sink_rx_status);