summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tinydrm/st7586.c
diff options
context:
space:
mode:
authorNoralf Trønnes <noralf@tronnes.org>2019-02-25 17:42:32 +0300
committerNoralf Trønnes <noralf@tronnes.org>2019-03-04 17:32:21 +0300
commit9d5645ad1b979c99326e13ac51e1826ffe60aaec (patch)
tree31513f9a5bd35f5b572ef7bdd3d91870607b05a0 /drivers/gpu/drm/tinydrm/st7586.c
parent2afd9fcba6b168ab4fa5c38680f98147a745d31c (diff)
downloadlinux-9d5645ad1b979c99326e13ac51e1826ffe60aaec.tar.xz
drm/tinydrm: Use drm_dev_enter/exit()
This protects device resources from use after device removal. There are 3 ways for driver-device unbinding to happen: - The driver module is unloaded causing the driver to be unregistered. This can't happen as long as there are open file handles because a reference is taken on the module. - The device is removed (Device Tree overlay unloading). This can happen at any time. - The driver sysfs unbind file can be used to unbind the driver from the device. This can happen any time. v2: Since drm_atomic_helper_shutdown() has to be called after drm_dev_unplug() we don't want do block ->disable after unplug. Signed-off-by: Noralf Trønnes <noralf@tronnes.org> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190225144232.20761-8-noralf@tronnes.org
Diffstat (limited to 'drivers/gpu/drm/tinydrm/st7586.c')
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/gpu/drm/tinydrm/st7586.c b/drivers/gpu/drm/tinydrm/st7586.c
index 6e92de809b63..d99957bac532 100644
--- a/drivers/gpu/drm/tinydrm/st7586.c
+++ b/drivers/gpu/drm/tinydrm/st7586.c
@@ -119,12 +119,14 @@ static int st7586_buf_copy(void *dst, struct drm_framebuffer *fb,
static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
{
struct mipi_dbi *mipi = drm_to_mipi_dbi(fb->dev);
- int start, end;
- int ret = 0;
+ int start, end, idx, ret = 0;
if (!mipi->enabled)
return;
+ if (!drm_dev_enter(fb->dev, &idx))
+ return;
+
/* 3 pixels per byte, so grow clip to nearest multiple of 3 */
rect->x1 = rounddown(rect->x1, 3);
rect->x2 = roundup(rect->x2, 3);
@@ -152,6 +154,8 @@ static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
err_msg:
if (ret)
dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret);
+
+ drm_dev_exit(idx);
}
static void st7586_pipe_update(struct drm_simple_display_pipe *pipe,
@@ -184,14 +188,17 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
.y1 = 0,
.y2 = fb->height,
};
- int ret;
+ int idx, ret;
u8 addr_mode;
+ if (!drm_dev_enter(pipe->crtc.dev, &idx))
+ return;
+
DRM_DEBUG_KMS("\n");
ret = mipi_dbi_poweron_reset(mipi);
if (ret)
- return;
+ goto out_exit;
mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
@@ -244,12 +251,21 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
st7586_fb_dirty(fb, &rect);
mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
+out_exit:
+ drm_dev_exit(idx);
}
static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
{
struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
+ /*
+ * This callback is not protected by drm_dev_enter/exit since we want to
+ * turn off the display on regular driver unload. It's highly unlikely
+ * that the underlying SPI controller is gone should this be called after
+ * unplug.
+ */
+
DRM_DEBUG_KMS("\n");
if (!mipi->enabled)