aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorArchit Taneja <architt@codeaurora.org>2016-10-25 02:47:59 -0400
committerRob Clark <robdclark@gmail.com>2016-11-02 10:48:09 -0400
commit8d23ea403044efe97553dd64228b172c8ffca047 (patch)
treea2a9244f5ed21c2a3732d7be14d04d069caaa767 /drivers/gpu
parentb0a6af8b34c9ad20894aa46f85f4bf59d444f286 (diff)
drm/msm/dsi: Queue HPD helper work in attach/detach callbacks
The msm/dsi host drivers calls drm_helper_hpd_irq_event in the mipi_dsi_host attach/detatch callbacks. mipi_dsi_attach()/mipi_dsi_detach() from a panel/bridge driver could be called from a context where the drm_device's mode_config.mutex is already held, resulting in a deadlock. Queue it as work instead. Signed-off-by: Archit Taneja <architt@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_host.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index f05ed0e1f3d6..6f240021705b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -139,6 +139,7 @@ struct msm_dsi_host {
139 139
140 u32 err_work_state; 140 u32 err_work_state;
141 struct work_struct err_work; 141 struct work_struct err_work;
142 struct work_struct hpd_work;
142 struct workqueue_struct *workqueue; 143 struct workqueue_struct *workqueue;
143 144
144 /* DSI 6G TX buffer*/ 145 /* DSI 6G TX buffer*/
@@ -1294,6 +1295,14 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host)
1294 wmb(); /* make sure dsi controller enabled again */ 1295 wmb(); /* make sure dsi controller enabled again */
1295} 1296}
1296 1297
1298static void dsi_hpd_worker(struct work_struct *work)
1299{
1300 struct msm_dsi_host *msm_host =
1301 container_of(work, struct msm_dsi_host, hpd_work);
1302
1303 drm_helper_hpd_irq_event(msm_host->dev);
1304}
1305
1297static void dsi_err_worker(struct work_struct *work) 1306static void dsi_err_worker(struct work_struct *work)
1298{ 1307{
1299 struct msm_dsi_host *msm_host = 1308 struct msm_dsi_host *msm_host =
@@ -1480,7 +1489,7 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
1480 1489
1481 DBG("id=%d", msm_host->id); 1490 DBG("id=%d", msm_host->id);
1482 if (msm_host->dev) 1491 if (msm_host->dev)
1483 drm_helper_hpd_irq_event(msm_host->dev); 1492 queue_work(msm_host->workqueue, &msm_host->hpd_work);
1484 1493
1485 return 0; 1494 return 0;
1486} 1495}
@@ -1494,7 +1503,7 @@ static int dsi_host_detach(struct mipi_dsi_host *host,
1494 1503
1495 DBG("id=%d", msm_host->id); 1504 DBG("id=%d", msm_host->id);
1496 if (msm_host->dev) 1505 if (msm_host->dev)
1497 drm_helper_hpd_irq_event(msm_host->dev); 1506 queue_work(msm_host->workqueue, &msm_host->hpd_work);
1498 1507
1499 return 0; 1508 return 0;
1500} 1509}
@@ -1748,6 +1757,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
1748 /* setup workqueue */ 1757 /* setup workqueue */
1749 msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0); 1758 msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
1750 INIT_WORK(&msm_host->err_work, dsi_err_worker); 1759 INIT_WORK(&msm_host->err_work, dsi_err_worker);
1760 INIT_WORK(&msm_host->hpd_work, dsi_hpd_worker);
1751 1761
1752 msm_dsi->host = &msm_host->base; 1762 msm_dsi->host = &msm_host->base;
1753 msm_dsi->id = msm_host->id; 1763 msm_dsi->id = msm_host->id;