diff options
| author | Venkata Prahlad Valluru <vvalluru@codeaurora.org> | 2020-03-06 19:12:30 +0530 |
|---|---|---|
| committer | Venkata Prahlad Valluru <vvalluru@codeaurora.org> | 2020-03-06 19:14:00 +0530 |
| commit | fd06f35834d58041efd3b804ba33767dd808f188 (patch) | |
| tree | 186ee84e658292d38bd977765cfef40d50d0ef5c | |
| parent | ffd87dde76f6c9b6a134c981c877c2e25c350ea2 (diff) | |
mdss: msm: hdmi: fix CEC broadcast loopback issue
A new logical address is searched and allocated when
HDMI hotplug interrupt happens. But there might be
pending broadcast messages which are being handled with
the old logical address, then the messages are received
back again causing loopback issue.
To fix this, abort CEC message sending if the message is
broadcasting and the sender's logical address is different
than the current logical address.
Change-Id: I26c487bac8749c9de81b176d611f1263eab0d9ad
Signed-off-by: Venkata Prahlad Valluru <vvalluru@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_hdmi_cec.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/video/fbdev/msm/mdss_hdmi_cec.c b/drivers/video/fbdev/msm/mdss_hdmi_cec.c index 872e3594715f..3eda29edff4d 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_cec.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_cec.c @@ -42,7 +42,7 @@ struct hdmi_cec_ctrl { bool cec_wakeup_en; bool cec_device_suspend; bool cec_clear_logical_addr; - + u32 cec_logical_addr; u32 cec_msg_wr_status; struct cec_msg recv_msg[CEC_RECV_Q_SIZE]; u32 head; @@ -68,6 +68,20 @@ static int hdmi_cec_msg_send(void *data, struct cec_msg *msg) return -EINVAL; } + if (msg->sender_id != cec_ctrl->cec_logical_addr && + msg->recvr_id == 0xF) { + /* + * If the current logical address is not the + * same as the sender_id and if the message is + * broadcasting, the message is looping back. + * Abort the message sending in that case + */ + DEV_ERR("%s: abort potential MAL msg %d:%d logical %d\n", + __func__, msg->sender_id, msg->recvr_id, + cec_ctrl->cec_logical_addr); + return -EINVAL; + } + io = cec_ctrl->init_data.io; reinit_completion(&cec_ctrl->cec_msg_wr_done); @@ -414,8 +428,10 @@ static void hdmi_cec_write_logical_addr(void *input, u8 addr) return; } - if (cec_ctrl->cec_enabled) + if (cec_ctrl->cec_enabled) { DSS_REG_W(cec_ctrl->init_data.io, HDMI_CEC_ADDR, addr & 0xF); + cec_ctrl->cec_logical_addr = addr & 0xF; + } } static void hdmi_cec_clear_logical_addr(void *input, bool clear_flag) |
