diff options
author | Noralf Trønnes <noralf@tronnes.org> | 2019-02-25 15:42:32 +0100 |
---|---|---|
committer | Noralf Trønnes <noralf@tronnes.org> | 2019-03-04 15:32:21 +0100 |
commit | 9d5645ad1b979c99326e13ac51e1826ffe60aaec (patch) | |
tree | 31513f9a5bd35f5b572ef7bdd3d91870607b05a0 /drivers/gpu/drm/tinydrm/ili9225.c | |
parent | 2afd9fcba6b168ab4fa5c38680f98147a745d31c (diff) |
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/ili9225.c')
-rw-r--r-- | drivers/gpu/drm/tinydrm/ili9225.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c index 4d387a07c48b..0e9fde47b53b 100644 --- a/drivers/gpu/drm/tinydrm/ili9225.c +++ b/drivers/gpu/drm/tinydrm/ili9225.c @@ -89,13 +89,16 @@ static void ili9225_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) bool swap = mipi->swap_bytes; u16 x_start, y_start; u16 x1, x2, y1, y2; - int ret = 0; + int idx, ret = 0; bool full; void *tr; if (!mipi->enabled) return; + if (!drm_dev_enter(fb->dev, &idx)) + return; + full = width == fb->width && height == fb->height; DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect)); @@ -158,6 +161,8 @@ static void ili9225_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 ili9225_pipe_update(struct drm_simple_display_pipe *pipe, @@ -191,9 +196,12 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe, .y1 = 0, .y2 = fb->height, }; - int ret; + int ret, idx; u8 am_id; + if (!drm_dev_enter(pipe->crtc.dev, &idx)) + return; + DRM_DEBUG_KMS("\n"); mipi_dbi_hw_reset(mipi); @@ -207,7 +215,7 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe, ret = ili9225_command(mipi, ILI9225_POWER_CONTROL_1, 0x0000); if (ret) { DRM_DEV_ERROR(dev, "Error sending command %d\n", ret); - return; + goto out_exit; } ili9225_command(mipi, ILI9225_POWER_CONTROL_2, 0x0000); ili9225_command(mipi, ILI9225_POWER_CONTROL_3, 0x0000); @@ -280,6 +288,8 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe, mipi->enabled = true; ili9225_fb_dirty(fb, &rect); +out_exit: + drm_dev_exit(idx); } static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe) @@ -288,6 +298,13 @@ static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe) DRM_DEBUG_KMS("\n"); + /* + * 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. + */ + if (!mipi->enabled) return; |