[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