Having the DSI interrupt enabled before actually binding the DSI component to the display controller driver is both useless and dangerous: the main purpose of this interrupt is to signal CMD done, LP RX data ready, or VideoMode done, or to reset the HW engine if this doesn't come.
Should this interrupt come too late (during probe), the HW will be reset only at the next occurrence of a timeout, which slows down boot and may render artifacts to the DSI display. Moreover, clearing the DSI interrupt while the display controller is not ready yet, may result in an interrupt storm. In order to prevent this from happening, request the interrupt with IRQF_NO_AUTOEN, and enable it only when binding DSI to its display controller component master. Signed-off-by: AngeloGioacchino Del Regno <[email protected]> --- drivers/gpu/drm/mediatek/mtk_dsi.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c index 3fbcb22ee15e..56c69f80a2ef 100644 --- a/drivers/gpu/drm/mediatek/mtk_dsi.c +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c @@ -225,6 +225,7 @@ struct mtk_dsi { int refcount; bool enabled; bool lanes_ready; + int irq; u32 irq_data; wait_queue_head_t irq_wait_queue; const struct mtk_dsi_driver_data *driver_data; @@ -1048,7 +1049,13 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - return device_reset_optional(dev); + ret = device_reset_optional(dev); + if (ret) + return ret; + + enable_irq(dsi->irq); + + return 0; } static void mtk_dsi_unbind(struct device *dev, struct device *master, @@ -1056,6 +1063,8 @@ static void mtk_dsi_unbind(struct device *dev, struct device *master, { struct mtk_dsi *dsi = dev_get_drvdata(dev); + disable_irq(dsi->irq); + drm_encoder_cleanup(&dsi->encoder); } @@ -1283,7 +1292,6 @@ static int mtk_dsi_probe(struct platform_device *pdev) { struct mtk_dsi *dsi; struct device *dev = &pdev->dev; - int irq_num; int ret; dsi = devm_drm_bridge_alloc(dev, struct mtk_dsi, bridge, @@ -1316,9 +1324,9 @@ static int mtk_dsi_probe(struct platform_device *pdev) if (IS_ERR(dsi->phy)) return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to get MIPI-DPHY\n"); - irq_num = platform_get_irq(pdev, 0); - if (irq_num < 0) - return irq_num; + dsi->irq = platform_get_irq(pdev, 0); + if (dsi->irq < 0) + return dsi->irq; dsi->host.ops = &mtk_dsi_ops; dsi->host.dev = dev; @@ -1331,8 +1339,8 @@ static int mtk_dsi_probe(struct platform_device *pdev) if (ret < 0) return dev_err_probe(dev, ret, "Failed to register DSI host\n"); - ret = devm_request_irq(&pdev->dev, irq_num, mtk_dsi_irq, - IRQF_TRIGGER_NONE, dev_name(&pdev->dev), dsi); + ret = devm_request_irq(&pdev->dev, dsi->irq, mtk_dsi_irq, + IRQF_NO_AUTOEN, dev_name(&pdev->dev), dsi); if (ret) { mipi_dsi_host_unregister(&dsi->host); return dev_err_probe(&pdev->dev, ret, "Failed to request DSI irq\n"); -- 2.54.0
