From: Jacob Chen Date: Wed, 4 Jan 2017 06:01:02 +0000 (+0800) Subject: drm: bridge: analogix/dp: Fix the dead lock when disable bridge X-Git-Tag: firefly_0821_release~153 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=dcfa807652af5b7d6daac23e880bf7860989ada2 drm: bridge: analogix/dp: Fix the dead lock when disable bridge dead lock : IN --> drm_fb_helper_restore_fbdev_mode_unlocked 1. Acquire mode_config lock IN --> atomic commit IN --> rockchip_atomic_commit_complete IN --> drm_atomic_helper_commit_modeset_disables IN --> bridge disable IN --> analogix_dp_irq_thread IN --> drm_helper_hpd_irq_event 3. Acquire mode_config lock (have been acquired) [ 363.054554] INFO: task irq/54-analogix:174 blocked for more than 120 seconds. [ 363.054612] Not tainted 4.4.55 #31 [ 363.054631] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 363.054651] irq/54-analogix D ffffff8008084f98 0 174 2 0x00000000 [ 363.054691] Call trace: [ 363.054726] [] __switch_to+0xb4/0xc0 [ 363.054759] [] __schedule+0x3f0/0x670 [ 363.054785] [] schedule+0x84/0xa4 [ 363.054813] [] schedule_preempt_disabled+0x20/0x38 [ 363.054842] [] __mutex_lock_slowpath+0xfc/0x178 [ 363.054869] [] mutex_lock+0x2c/0x44 [ 363.054897] [] drm_helper_hpd_irq_event+0x34/0x154 [ 363.054929] [] analogix_dp_irq_thread+0x30/0x58 [ 363.054957] [] irq_thread_fn+0x28/0x68 [ 363.054991] [] irq_thread+0x10c/0x1ec [ 363.055016] [] kthread+0xe8/0xf0 [ 363.055042] [] ret_from_fork+0x10/0x40 [ 363.055097] INFO: task surfaceflinger:240 blocked for more than 120 seconds. [ 363.055119] Not tainted 4.4.55 #31 [ 363.055136] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 363.055155] surfaceflinger D ffffff8008084f98 0 240 1 0x00000009 [ 363.055191] Call trace: [ 363.055214] [] __switch_to+0xb4/0xc0 [ 363.055241] [] __schedule+0x3f0/0x670 [ 363.055268] [] schedule+0x84/0xa4 [ 363.055292] [] synchronize_irq+0x64/0x98 [ 363.055316] [] disable_irq+0x20/0x2c [ 363.055344] [] analogix_dp_bridge_disable+0x70/0xa8 [ 363.055370] [] drm_bridge_disable+0x2c/0x38 [ 363.055403] [] drm_atomic_helper_commit_modeset_disables+0x120/0x39c [ 363.055432] [] rockchip_atomic_commit_complete+0x30/0x14c [ 363.055459] [] rockchip_drm_atomic_commit+0x7c/0x9c [ 363.055484] [] drm_atomic_commit+0x64/0x70 [ 363.055511] [] drm_atomic_helper_connector_dpms+0xf4/0x154 [ 363.055541] [] drm_mode_obj_set_property_ioctl+0x148/0x204 [ 363.055575] [] drm_mode_connector_property_set_ioctl+0x40/0x60 [ 363.055602] [] drm_ioctl+0x27c/0x400 [ 363.055630] [] do_vfs_ioctl+0x4d0/0x5c0 [ 363.055655] [] SyS_ioctl+0x60/0x88 [ 363.055680] [] el0_svc_naked+0x24/0x28 Change-Id: I6d5eeb83b9640a54b33b1cad03c2207196a56e16 Signed-off-by: Jacob Chen Signed-off-by: Mark Yao --- diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 31f384b096a6..df3d47b176bb 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -871,6 +871,11 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void *arg) struct analogix_dp_device *dp = arg; enum dp_irq_type irq_type; + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return IRQ_HANDLED; + + pm_runtime_get_sync(dp->dev); + irq_type = analogix_dp_get_irq_type(dp); if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN || irq_type & DP_IRQ_TYPE_HP_CABLE_OUT) { @@ -884,6 +889,8 @@ static irqreturn_t analogix_dp_irq_thread(int irq, void *arg) analogix_dp_unmute_hpd_interrupt(dp); } + pm_runtime_put(dp->dev); + return IRQ_HANDLED; } @@ -1099,7 +1106,7 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) } } - disable_irq(dp->irq); + disable_irq_nosync(dp->irq); phy_power_off(dp->phy); if (dp->plat_data->power_off)