From 178d4d6f8b7920e8038de802a2c0cfd2a66df39a Mon Sep 17 00:00:00 2001 From: Ajay Singh Parmar Date: Sun, 22 Nov 2015 14:48:22 -0800 Subject: [PATCH] msm: mdss: hdmi: schedule link work from isr Do not schedule link work periodically to check for new message or authentication status. Hardware automatically poll sink for the same. Once new message is available or sink indicates re-authentication required, isr is triggered. Queue link check work from isr to avoid unnecessary software polling. Change-Id: I83c71f5151aa077e863b6578a89f6515f6497159 Signed-off-by: Ajay Singh Parmar --- drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c | 42 ++++++++++----------- drivers/video/fbdev/msm/mdss_hdmi_util.c | 19 +++++++--- drivers/video/fbdev/msm/mdss_hdmi_util.h | 5 ++- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c index 78936832ab30..cde3f42958ef 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_hdcp2p2.c @@ -74,8 +74,6 @@ struct hdmi_hdcp2p2_ctrl { struct kthread_work send_msg; struct kthread_work recv_msg; struct kthread_work link; - - struct delayed_work link_check_work; }; static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl); @@ -777,8 +775,9 @@ static void hdmi_hdcp2p2_recv_msg(struct hdmi_hdcp2p2_ctrl *ctrl) ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync / 20; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; + ddc_data->wait = true; - rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, true); + rc = hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl); if (rc) { pr_err("error reading rxstatus %d\n", rc); goto exit; @@ -831,6 +830,19 @@ 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; @@ -862,8 +874,10 @@ static int hdmi_hdcp2p2_link_check(struct hdmi_hdcp2p2_ctrl *ctrl) ddc_data->timeout_hsync = timeout_hsync; ddc_data->periodic_timer_hsync = timeout_hsync; ddc_data->read_method = HDCP2P2_RXSTATUS_HW_DDC_SW_TRIGGER; + ddc_data->link_cb = hdmi_hdcp2p2_link_cb; + ddc_data->link_data = ctrl; - return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl, false); + return hdmi_hdcp2p2_ddc_read_rxstatus(ddc_ctrl); } static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl) @@ -884,8 +898,7 @@ static void hdmi_hdcp2p2_auth_status(struct hdmi_hdcp2p2_ctrl *ctrl) ctrl->init_data.notify_status(ctrl->init_data.cb_data, HDCP_STATE_AUTHENTICATED); - if (!hdmi_hdcp2p2_link_check(ctrl)) - queue_kthread_work(&ctrl->worker, &ctrl->link); + hdmi_hdcp2p2_link_check(ctrl); } } @@ -897,16 +910,6 @@ static void hdmi_hdcp2p2_auth_status_work(struct kthread_work *work) hdmi_hdcp2p2_auth_status(ctrl); } - -static void hdmi_hdcp2p2_link_schedule_work(struct work_struct *work) -{ - struct hdmi_hdcp2p2_ctrl *ctrl = container_of(to_delayed_work(work), - struct hdmi_hdcp2p2_ctrl, link_check_work); - - if (atomic_read(&ctrl->auth_state) != HDCP_STATE_INACTIVE) - queue_kthread_work(&ctrl->worker, &ctrl->link); -} - static void hdmi_hdcp2p2_link_work(struct kthread_work *work) { int rc = 0; @@ -980,10 +983,6 @@ exit: hdmi_hdcp2p2_auth_failed(ctrl); return; } - - /* recheck within 1sec as per hdcp 2.2 standard */ - schedule_delayed_work(&ctrl->link_check_work, - msecs_to_jiffies(HDCP2P2_LINK_CHECK_TIME_MS)); } static int hdmi_hdcp2p2_auth(struct hdmi_hdcp2p2_ctrl *ctrl) @@ -1122,9 +1121,6 @@ void *hdmi_hdcp2p2_init(struct hdmi_hdcp_init_data *init_data) ctrl->thread = kthread_run(kthread_worker_fn, &ctrl->worker, "hdmi_hdcp2p2"); - INIT_DELAYED_WORK(&ctrl->link_check_work, - hdmi_hdcp2p2_link_schedule_work); - if (IS_ERR(ctrl->thread)) { pr_err("unable to start hdcp2p2 thread\n"); rc = PTR_ERR(ctrl->thread); diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.c b/drivers/video/fbdev/msm/mdss_hdmi_util.c index d957f75e9609..28df6f07231a 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.c @@ -919,6 +919,7 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) struct hdmi_tx_hdcp2p2_ddc_data *data; u32 intr0, intr2, intr5; u32 msg_size; + int rc = 0; if (!ddc_ctrl || !ddc_ctrl->io) { pr_err("invalid input\n"); @@ -1041,10 +1042,18 @@ static int hdmi_ddc_hdcp2p2_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) } DSS_REG_W_ND(io, HDMI_DDC_INT_CTRL5, intr5); - if (data->message_size || data->ready || data->reauth_req) - atomic_set(&ddc_ctrl->rxstatus_busy_wait_done, 1); + if (data->message_size || data->ready || data->reauth_req) { + if (data->wait) { + atomic_set(&ddc_ctrl->rxstatus_busy_wait_done, 1); + } else if (data->link_cb && data->link_data) { + data->link_cb(data->link_data); + } else { + pr_err("new msg/reauth not handled\n"); + rc = -EINVAL; + } + } - return 0; + return rc; } static int hdmi_ddc_scrambling_isr(struct hdmi_tx_ddc_ctrl *ddc_ctrl) @@ -1605,7 +1614,7 @@ void hdmi_hdcp2p2_ddc_disable(struct hdmi_tx_ddc_ctrl *ctrl) DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val); } -int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait) +int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl) { u32 reg_val; u32 intr_en_mask; @@ -1704,7 +1713,7 @@ int hdmi_hdcp2p2_ddc_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait) DSS_REG_W(ctrl->io, HDMI_HW_DDC_CTRL, reg_val); DSS_REG_W(ctrl->io, HDMI_HDCP2P2_DDC_SW_TRIGGER, 1); - if (wait) { + if (data->wait) { while (busy_wait_us > 0 && !atomic_read(&ctrl->rxstatus_busy_wait_done)) { udelay(HDMI_BUSY_WAIT_DELAY_US); diff --git a/drivers/video/fbdev/msm/mdss_hdmi_util.h b/drivers/video/fbdev/msm/mdss_hdmi_util.h index c919865ccf41..88d7828b78d6 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_util.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_util.h @@ -433,7 +433,10 @@ struct hdmi_tx_hdcp2p2_ddc_data { bool ddc_done; bool ddc_read_req; bool ddc_timeout; + bool wait; int irq_wait_count; + void (*link_cb)(void *data); + void *link_data; }; struct hdmi_tx_ddc_ctrl { @@ -500,8 +503,8 @@ 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_read_rxstatus(struct hdmi_tx_ddc_ctrl *ctrl, bool wait); 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);