[PATCH v2 11/11] drm/tinydrm: Support device unplug in drivers

Noralf Trønnes noralf at tronnes.org
Fri Sep 8 15:07:30 UTC 2017


Protect device resource by adding drm_dev_enter() and drm_dev_exit().

Cc: David Lechner <david at lechnology.com>
Signed-off-by: Noralf Trønnes <noralf at tronnes.org>
---
 drivers/gpu/drm/tinydrm/mi0283qt.c | 11 ++++++++---
 drivers/gpu/drm/tinydrm/mipi-dbi.c | 18 +++++++++++++++++-
 drivers/gpu/drm/tinydrm/repaper.c  | 30 +++++++++++++++++++++++-------
 drivers/gpu/drm/tinydrm/st7586.c   | 23 +++++++++++++++++++----
 4 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 9495c9a..f85a404 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -27,14 +27,17 @@ static void mi0283qt_enable(struct drm_simple_display_pipe *pipe,
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
 	struct device *dev = tdev->drm.dev;
 	u8 addr_mode;
-	int ret;
+	int ret, idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	DRM_DEBUG_KMS("\n");
 
 	ret = regulator_enable(mipi->regulator);
 	if (ret) {
 		dev_err(dev, "Failed to enable regulator (%d)\n", ret);
-		return;
+		goto exit;
 	}
 
 	if (mipi_dbi_display_is_on(mipi))
@@ -45,7 +48,7 @@ static void mi0283qt_enable(struct drm_simple_display_pipe *pipe,
 	if (ret) {
 		dev_err(dev, "Error sending command (%d)\n", ret);
 		regulator_disable(mipi->regulator);
-		return;
+		goto exit;
 	}
 
 	msleep(20);
@@ -113,6 +116,8 @@ static void mi0283qt_enable(struct drm_simple_display_pipe *pipe,
 
 out_enable:
 	mipi_dbi_pipe_enable(pipe, crtc_state);
+exit:
+	drm_dev_exit(idx);
 }
 
 static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = {
diff --git a/drivers/gpu/drm/tinydrm/mipi-dbi.c b/drivers/gpu/drm/tinydrm/mipi-dbi.c
index 8498b49..8b72cfb 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -203,10 +203,13 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
 	bool swap = mipi->swap_bytes;
 	struct drm_clip_rect clip;
-	int ret = 0;
+	int ret = 0, idx;
 	bool full;
 	void *tr;
 
+	if (!drm_dev_enter(fb->dev, &idx))
+		return -ENODEV;
+
 	mutex_lock(&tdev->dirty_lock);
 
 	if (!mipi->enabled)
@@ -244,6 +247,7 @@ static int mipi_dbi_fb_dirty(struct drm_framebuffer *fb,
 
 out_unlock:
 	mutex_unlock(&tdev->dirty_lock);
+	drm_dev_exit(idx);
 
 	if (ret)
 		dev_err_once(fb->dev->dev, "Failed to update display %d\n",
@@ -273,12 +277,18 @@ void mipi_dbi_pipe_enable(struct drm_simple_display_pipe *pipe,
 	struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
 	struct drm_framebuffer *fb = pipe->plane.fb;
+	int idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	mipi->enabled = true;
 	if (fb)
 		fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0);
 
 	tinydrm_enable_backlight(mipi->backlight);
+
+	drm_dev_exit(idx);
 }
 EXPORT_SYMBOL(mipi_dbi_pipe_enable);
 
@@ -311,6 +321,10 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
 {
 	struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+	int idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	DRM_DEBUG_KMS("\n");
 
@@ -323,6 +337,8 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
 
 	if (mipi->regulator)
 		regulator_disable(mipi->regulator);
+
+	drm_dev_exit(idx);
 }
 EXPORT_SYMBOL(mipi_dbi_pipe_disable);
 
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
index 9236efb..207a031 100644
--- a/drivers/gpu/drm/tinydrm/repaper.c
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -531,8 +531,11 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
 	struct tinydrm_device *tdev = drm_to_tinydrm(fb->dev);
 	struct repaper_epd *epd = epd_from_tinydrm(tdev);
 	struct drm_clip_rect clip;
+	int ret = 0, idx;
 	u8 *buf = NULL;
-	int ret = 0;
+
+	if (!drm_dev_enter(fb->dev, &idx))
+		return -ENODEV;
 
 	/* repaper can't do partial updates */
 	clip.x1 = 0;
@@ -632,6 +635,8 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb,
 		dev_err(fb->dev->dev, "Failed to update display (%d)\n", ret);
 	kfree(buf);
 
+	drm_dev_exit(idx);
+
 	return ret;
 }
 
@@ -666,7 +671,10 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 	struct spi_device *spi = epd->spi;
 	struct device *dev = &spi->dev;
 	bool dc_ok = false;
-	int i, ret;
+	int i, ret, idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	DRM_DEBUG_DRIVER("\n");
 
@@ -705,7 +713,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 	if (!i) {
 		dev_err(dev, "timeout waiting for panel to become ready.\n");
 		power_off(epd);
-		return;
+		goto exit;
 	}
 
 	repaper_read_id(spi);
@@ -716,7 +724,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 		else
 			dev_err(dev, "wrong COG ID 0x%02x\n", ret);
 		power_off(epd);
-		return;
+		goto exit;
 	}
 
 	/* Disable OE */
@@ -729,7 +737,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 		else
 			dev_err(dev, "panel is reported broken\n");
 		power_off(epd);
-		return;
+		goto exit;
 	}
 
 	/* Power saving mode */
@@ -769,7 +777,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 		if (ret < 0) {
 			dev_err(dev, "failed to read chip (%d)\n", ret);
 			power_off(epd);
-			return;
+			goto exit;
 		}
 
 		if (ret & 0x40) {
@@ -781,7 +789,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 	if (!dc_ok) {
 		dev_err(dev, "dc/dc failed\n");
 		power_off(epd);
-		return;
+		goto exit;
 	}
 
 	/*
@@ -792,6 +800,8 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
 
 	epd->enabled = true;
 	epd->partial = false;
+exit:
+	drm_dev_exit(idx);
 }
 
 static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -800,6 +810,10 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
 	struct repaper_epd *epd = epd_from_tinydrm(tdev);
 	struct spi_device *spi = epd->spi;
 	unsigned int line;
+	int idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	DRM_DEBUG_DRIVER("\n");
 
@@ -846,6 +860,8 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
 	msleep(50);
 
 	power_off(epd);
+
+	drm_dev_exit(idx);
 }
 
 static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = {
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index 67f5c83..874429c 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -115,8 +115,11 @@ static int st7586_fb_dirty(struct drm_framebuffer *fb,
 	struct tinydrm_device *tdev = drm_to_tinydrm(fb->dev);
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
 	struct drm_clip_rect clip;
+	int ret = 0, idx;
 	int start, end;
-	int ret = 0;
+
+	if (!drm_dev_enter(fb->dev, &idx))
+		return -ENODEV;
 
 	mutex_lock(&tdev->dirty_lock);
 
@@ -158,6 +161,7 @@ static int st7586_fb_dirty(struct drm_framebuffer *fb,
 
 out_unlock:
 	mutex_unlock(&tdev->dirty_lock);
+	drm_dev_exit(idx);
 
 	if (ret)
 		dev_err_once(fb->dev->dev, "Failed to update display %d\n",
@@ -179,16 +183,19 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
 	struct drm_framebuffer *fb = pipe->plane.fb;
 	struct device *dev = tdev->drm.dev;
-	int ret;
+	int ret, idx;
 	u8 addr_mode;
 
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
+
 	DRM_DEBUG_KMS("\n");
 
 	mipi_dbi_hw_reset(mipi);
 	ret = mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
 	if (ret) {
 		dev_err(dev, "Error sending command %d\n", ret);
-		return;
+		goto exit;
 	}
 
 	mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
@@ -243,20 +250,28 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
 
 	if (fb)
 		fb->funcs->dirty(fb, NULL, 0, 0, NULL, 0);
+exit:
+	drm_dev_exit(idx);
 }
 
 static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
 {
 	struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
 	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
+	int idx;
+
+	if (!drm_dev_enter(&tdev->drm, &idx))
+		return;
 
 	DRM_DEBUG_KMS("\n");
 
 	if (!mipi->enabled)
-		return;
+		goto exit;
 
 	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
 	mipi->enabled = false;
+exit:
+	drm_dev_exit(idx);
 }
 
 static const u32 st7586_formats[] = {
-- 
2.7.4



More information about the dri-devel mailing list