Add devlink to cmdq to make sure the order of suspend and resume
is correct.

Signed-off-by: jason-jh.lin <jason-jh....@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 43 ++++++++++++++++++-------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 0b4012335e7a..612d1d69c16c 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -60,6 +60,7 @@ struct mtk_drm_crtc {
 #endif
 
        struct device                   *mmsys_dev;
+       struct device                   *drm_dev;
        struct mtk_mutex                *mutex;
        unsigned int                    ddp_comp_nr;
        struct mtk_ddp_comp             **ddp_comp;
@@ -159,6 +160,7 @@ static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
        mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
 
        if (mtk_crtc->cmdq_client.chan) {
+               device_link_remove(mtk_crtc->drm_dev, 
mtk_crtc->cmdq_client.chan->mbox->dev);
                mbox_free_channel(mtk_crtc->cmdq_client.chan);
                mtk_crtc->cmdq_client.chan = NULL;
        }
@@ -902,6 +904,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                return -ENOMEM;
 
        mtk_crtc->mmsys_dev = priv->mmsys_dev;
+       mtk_crtc->drm_dev = priv->dev;
        mtk_crtc->ddp_comp_nr = path_len;
        mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
                                                sizeof(*mtk_crtc->ddp_comp),
@@ -969,6 +972,18 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        }
 
        if (mtk_crtc->cmdq_client.chan) {
+               struct device_link *link;
+
+               /* add devlink to cmdq dev to make sure suspend/resume order is 
correct */
+               link = device_link_add(priv->dev, 
mtk_crtc->cmdq_client.chan->mbox->dev,
+                                      DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+               if (!link) {
+                       dev_err(priv->dev, "Unable to link dev=%s\n",
+                               
dev_name(mtk_crtc->cmdq_client.chan->mbox->dev));
+                       ret = -ENODEV;
+                       goto cmdq_err;
+               }
+
                ret = of_property_read_u32_index(priv->mutex_node,
                                                 "mediatek,gce-events",
                                                 i,
@@ -976,22 +991,26 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
                if (ret) {
                        dev_dbg(dev, "mtk_crtc %d failed to get 
mediatek,gce-events property\n",
                                drm_crtc_index(&mtk_crtc->base));
-                       mbox_free_channel(mtk_crtc->cmdq_client.chan);
-                       mtk_crtc->cmdq_client.chan = NULL;
-               } else {
-                       ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
-                                                     &mtk_crtc->cmdq_handle,
-                                                     PAGE_SIZE);
-                       if (ret) {
-                               dev_dbg(dev, "mtk_crtc %d failed to create cmdq 
packet\n",
-                                       drm_crtc_index(&mtk_crtc->base));
-                               mbox_free_channel(mtk_crtc->cmdq_client.chan);
-                               mtk_crtc->cmdq_client.chan = NULL;
-                       }
+                       goto cmdq_err;
+               }
+
+               ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
+                                             &mtk_crtc->cmdq_handle,
+                                             PAGE_SIZE);
+               if (ret) {
+                       dev_dbg(dev, "mtk_crtc %d failed to create cmdq 
packet\n",
+                               drm_crtc_index(&mtk_crtc->base));
+                       goto cmdq_err;
                }
 
                /* for sending blocking cmd in crtc disable */
                init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
+
+cmdq_err:
+               if (ret) {
+                       mbox_free_channel(mtk_crtc->cmdq_client.chan);
+                       mtk_crtc->cmdq_client.chan = NULL;
+               }
        }
 #endif
        return 0;
-- 
2.18.0

Reply via email to