From 13ca991025db2935127c8803f5dea7efb19a1bea Mon Sep 17 00:00:00 2001 From: Zheng Yang Date: Mon, 19 Jun 2017 17:49:31 +0800 Subject: [PATCH] drm: bridge: dw-hdmi: add more check for HDCP function On RK3328, dw-hdmi HDCP driver is loaded slower than dw-hdmi. hdmi->hdcp->hdcp_start is NULL when dw-hdmi call the hdcp_start, cause following system crash: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = ffffff8009292000 [00000000] *pgd=000000007e1fe003, *pud=000000007e1fe003, *pmd=0000000000000000 Internal error: Oops: 86000005 [#1] SMP Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.70 #418 Hardware name: Rockchip RK3328 EVB (DT) task: ffffffc0003a0000 ti: ffffffc0003a8000 task.ti: ffffffc0003a8000 PC is at 0x0 LR is at dw_hdmi_update_power+0xef4/0x1004 pc : [<0000000000000000>] lr : [] pstate: 60000045 sp : ffffffc0003ab3b0 x29: ffffffc0003ab3b0 x28: 000000000000410b x27: 0000000000000000 x26: 0000000000000000 x25: ffffffc07770d028 x24: 000000000000410b x23: 0000000000000000 x22: 0000000000000001 x21: 0000000000000002 x20: ffffff8008c02000 x19: ffffff8008c02d90 x18: 0000000062475a46 x17: 0000000000000000 x16: 000000000000000e x15: 0000000000000007 x14: 0ffffffffffffffd x13: 0000000000000018 x12: 0101010101010101 x11: 7f7f7f7f7f7fff7f x10: fefefefeff01f305 x9 : ff7fff7f7f7f7f7f x8 : ffffff80091db5df x7 : 0000000000000000 x6 : 0000000000000004 x5 : 0000000000000015 x4 : 0000000000140b82 x3 : 000000000106b1af x2 : 0000000000000001 x1 : 0000000000000000 x0 : ffffffc076e25e00 Change-Id: I0fccf9d8e06f7acdb56d8e5360acf0df026fee10 Signed-off-by: Zheng Yang --- drivers/gpu/drm/bridge/dw-hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 6e34106c0a06..c5b5963f3923 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -1581,7 +1581,7 @@ static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi, hdmi_modb(hdmi, hdmi_dvi, HDMI_A_HDCPCFG0_HDMIDVI_MASK, HDMI_A_HDCPCFG0); - if (hdmi->hdcp) + if (hdmi->hdcp && hdmi->hdcp->hdcp_start) hdmi->hdcp->hdcp_start(hdmi->hdcp); } @@ -2159,7 +2159,7 @@ static void dw_hdmi_poweroff(struct dw_hdmi *hdmi) hdmi->phy.enabled = false; } - if (hdmi->hdcp) + if (hdmi->hdcp && hdmi->hdcp->hdcp_stop) hdmi->hdcp->hdcp_stop(hdmi->hdcp); hdmi->bridge_is_on = false; } @@ -2478,7 +2478,7 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) hdcp_stat = hdmi_readb(hdmi, HDMI_A_APIINTSTAT); if (hdcp_stat) { - if (hdmi->hdcp) + if (hdmi->hdcp && hdmi->hdcp->hdcp_isr) hdmi->hdcp->hdcp_isr(hdmi->hdcp, hdcp_stat); hdmi_writeb(hdmi, hdcp_stat, HDMI_A_APIINTCLR); hdmi_writeb(hdmi, 0x00, HDMI_A_APIINTMSK); -- 2.34.1