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);