[PATCH v1] drm/kmb: Handle DSI clock enable failures

Yuho Choi <[email protected]>
Newsgroups gmane.linux.kernel,gmane.comp.video.dri.devel
Message-ID <[email protected]>
Disable clocks that were enabled before a later DSI clock fails, and
track whether the complete DSI clock set is enabled so teardown does
not disable partially initialized clocks.

Propagate kmb_dsi_clk_init() failures through the display hardware
initialization path instead of continuing with a partially initialized
DSI device.

Fixes: 98521f4d4b4c ("drm/kmb: Mipi DSI part of the display driver")
Fixes: 7f7b96a8a0a1 ("drm/kmb: Add support for KeemBay Display")
Signed-off-by: Yuho Choi <[email protected]>
---
 drivers/gpu/drm/kmb/kmb_drv.c | 6 +++++-
 drivers/gpu/drm/kmb/kmb_dsi.c | 9 +++++++++
 drivers/gpu/drm/kmb/kmb_dsi.h | 1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c
index 7c2eb1152fc2..fef76d6781b4 100644
--- a/drivers/gpu/drm/kmb/kmb_drv.c
+++ b/drivers/gpu/drm/kmb/kmb_drv.c
@@ -61,6 +61,8 @@ static int kmb_initialize_clocks(struct kmb_drm_private *kmb, struct device *dev
 	drm_info(&kmb->drm, "system clk = %d Mhz", kmb->sys_clk_mhz);
 
 	ret =  kmb_dsi_clk_init(kmb->kmb_dsi);
+	if (ret)
+		return ret;
 
 	/* Set LCD clock to 200 Mhz */
 	clk_set_rate(kmb->kmb_clk.clk_lcd, KMB_LCD_DEFAULT_CLK);
@@ -130,7 +132,9 @@ static int kmb_hw_init(struct drm_device *drm, unsigned long flags)
 		return ret;
 
 	/* Enable display clocks */
-	kmb_initialize_clocks(kmb, &pdev->dev);
+	ret = kmb_initialize_clocks(kmb, &pdev->dev);
+	if (ret)
+		return ret;
 
 	/* Register irqs here - section 17.3 in databook
 	 * lists LCD at 79 and 82 for MIPI under MSS CPU -
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c
index 59d0e856392f..07dc4e324426 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.c
+++ b/drivers/gpu/drm/kmb/kmb_dsi.c
@@ -175,9 +175,14 @@ mipi_hs_freq_range[MIPI_DPHY_DEFAULT_BIT_RATES] = {
 
 static void kmb_dsi_clk_disable(struct kmb_dsi *kmb_dsi)
 {
+	if (!kmb_dsi->dsi_clk_enabled)
+		return;
+
 	clk_disable_unprepare(kmb_dsi->clk_mipi);
 	clk_disable_unprepare(kmb_dsi->clk_mipi_ecfg);
 	clk_disable_unprepare(kmb_dsi->clk_mipi_cfg);
+
+	kmb_dsi->dsi_clk_enabled = false;
 }
 
 void kmb_dsi_host_unregister(struct kmb_dsi *kmb_dsi)
@@ -1494,15 +1499,19 @@ static int kmb_dsi_clk_enable(struct kmb_dsi *kmb_dsi)
 	ret = clk_prepare_enable(kmb_dsi->clk_mipi_ecfg);
 	if (ret) {
 		dev_err(dev, "Failed to enable MIPI_ECFG clock: %d\n", ret);
+		clk_disable_unprepare(kmb_dsi->clk_mipi);
 		return ret;
 	}
 
 	ret = clk_prepare_enable(kmb_dsi->clk_mipi_cfg);
 	if (ret) {
 		dev_err(dev, "Failed to enable MIPI_CFG clock: %d\n", ret);
+		clk_disable_unprepare(kmb_dsi->clk_mipi_ecfg);
+		clk_disable_unprepare(kmb_dsi->clk_mipi);
 		return ret;
 	}
 
+	kmb_dsi->dsi_clk_enabled = true;
 	dev_info(dev, "SUCCESS : enabled MIPI clocks\n");
 	return 0;
 }
diff --git a/drivers/gpu/drm/kmb/kmb_dsi.h b/drivers/gpu/drm/kmb/kmb_dsi.h
index 0faadeb9f1dd..8fafcf0d2a96 100644
--- a/drivers/gpu/drm/kmb/kmb_dsi.h
+++ b/drivers/gpu/drm/kmb/kmb_dsi.h
@@ -76,6 +76,7 @@ struct kmb_dsi {
 	struct clk *clk_mipi_ecfg;
 	struct clk *clk_mipi_cfg;
 	int sys_clk_mhz;
+	bool dsi_clk_enabled;
 };
 
 /* DPHY Tx test codes */
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.