aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoralf Trønnes <noralf@tronnes.org>2019-02-25 09:42:32 -0500
committerNoralf Trønnes <noralf@tronnes.org>2019-03-04 09:32:21 -0500
commit9d5645ad1b979c99326e13ac51e1826ffe60aaec (patch)
tree31513f9a5bd35f5b572ef7bdd3d91870607b05a0
parent2afd9fcba6b168ab4fa5c38680f98147a745d31c (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
-rw-r--r--drivers/gpu/drm/tinydrm/hx8357d.c9
-rw-r--r--drivers/gpu/drm/tinydrm/ili9225.c23
-rw-r--r--drivers/gpu/drm/tinydrm/ili9341.c9
-rw-r--r--drivers/gpu/drm/tinydrm/mi0283qt.c9
-rw-r--r--drivers/gpu/drm/tinydrm/mipi-dbi.c42
-rw-r--r--drivers/gpu/drm/tinydrm/repaper.c46
-rw-r--r--drivers/gpu/drm/tinydrm/st7586.c24
-rw-r--r--drivers/gpu/drm/tinydrm/st7735r.c9
8 files changed, 139 insertions, 32 deletions
diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c
index e9b9e08fafc7..fab961dded87 100644
--- a/drivers/gpu/drm/tinydrm/hx8357d.c
+++ b/drivers/gpu/drm/tinydrm/hx8357d.c
@@ -50,13 +50,16 @@ static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
50{ 50{
51 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 51 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
52 u8 addr_mode; 52 u8 addr_mode;
53 int ret; 53 int ret, idx;
54
55 if (!drm_dev_enter(pipe->crtc.dev, &idx))
56 return;
54 57
55 DRM_DEBUG_KMS("\n"); 58 DRM_DEBUG_KMS("\n");
56 59
57 ret = mipi_dbi_poweron_conditional_reset(mipi); 60 ret = mipi_dbi_poweron_conditional_reset(mipi);
58 if (ret < 0) 61 if (ret < 0)
59 return; 62 goto out_exit;
60 if (ret == 1) 63 if (ret == 1)
61 goto out_enable; 64 goto out_enable;
62 65
@@ -172,6 +175,8 @@ out_enable:
172 } 175 }
173 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); 176 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
174 mipi_dbi_enable_flush(mipi, crtc_state, plane_state); 177 mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
178out_exit:
179 drm_dev_exit(idx);
175} 180}
176 181
177static const struct drm_simple_display_pipe_funcs hx8357d_pipe_funcs = { 182static const struct drm_simple_display_pipe_funcs hx8357d_pipe_funcs = {
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)
89 bool swap = mipi->swap_bytes; 89 bool swap = mipi->swap_bytes;
90 u16 x_start, y_start; 90 u16 x_start, y_start;
91 u16 x1, x2, y1, y2; 91 u16 x1, x2, y1, y2;
92 int ret = 0; 92 int idx, ret = 0;
93 bool full; 93 bool full;
94 void *tr; 94 void *tr;
95 95
96 if (!mipi->enabled) 96 if (!mipi->enabled)
97 return; 97 return;
98 98
99 if (!drm_dev_enter(fb->dev, &idx))
100 return;
101
99 full = width == fb->width && height == fb->height; 102 full = width == fb->width && height == fb->height;
100 103
101 DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect)); 104 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)
158err_msg: 161err_msg:
159 if (ret) 162 if (ret)
160 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret); 163 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret);
164
165 drm_dev_exit(idx);
161} 166}
162 167
163static void ili9225_pipe_update(struct drm_simple_display_pipe *pipe, 168static 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,
191 .y1 = 0, 196 .y1 = 0,
192 .y2 = fb->height, 197 .y2 = fb->height,
193 }; 198 };
194 int ret; 199 int ret, idx;
195 u8 am_id; 200 u8 am_id;
196 201
202 if (!drm_dev_enter(pipe->crtc.dev, &idx))
203 return;
204
197 DRM_DEBUG_KMS("\n"); 205 DRM_DEBUG_KMS("\n");
198 206
199 mipi_dbi_hw_reset(mipi); 207 mipi_dbi_hw_reset(mipi);
@@ -207,7 +215,7 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
207 ret = ili9225_command(mipi, ILI9225_POWER_CONTROL_1, 0x0000); 215 ret = ili9225_command(mipi, ILI9225_POWER_CONTROL_1, 0x0000);
208 if (ret) { 216 if (ret) {
209 DRM_DEV_ERROR(dev, "Error sending command %d\n", ret); 217 DRM_DEV_ERROR(dev, "Error sending command %d\n", ret);
210 return; 218 goto out_exit;
211 } 219 }
212 ili9225_command(mipi, ILI9225_POWER_CONTROL_2, 0x0000); 220 ili9225_command(mipi, ILI9225_POWER_CONTROL_2, 0x0000);
213 ili9225_command(mipi, ILI9225_POWER_CONTROL_3, 0x0000); 221 ili9225_command(mipi, ILI9225_POWER_CONTROL_3, 0x0000);
@@ -280,6 +288,8 @@ static void ili9225_pipe_enable(struct drm_simple_display_pipe *pipe,
280 288
281 mipi->enabled = true; 289 mipi->enabled = true;
282 ili9225_fb_dirty(fb, &rect); 290 ili9225_fb_dirty(fb, &rect);
291out_exit:
292 drm_dev_exit(idx);
283} 293}
284 294
285static void ili9225_pipe_disable(struct drm_simple_display_pipe *pipe) 295static 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)
288 298
289 DRM_DEBUG_KMS("\n"); 299 DRM_DEBUG_KMS("\n");
290 300
301 /*
302 * This callback is not protected by drm_dev_enter/exit since we want to
303 * turn off the display on regular driver unload. It's highly unlikely
304 * that the underlying SPI controller is gone should this be called after
305 * unplug.
306 */
307
291 if (!mipi->enabled) 308 if (!mipi->enabled)
292 return; 309 return;
293 310
diff --git a/drivers/gpu/drm/tinydrm/ili9341.c b/drivers/gpu/drm/tinydrm/ili9341.c
index 850ce9ed6dd2..d15f85e837ae 100644
--- a/drivers/gpu/drm/tinydrm/ili9341.c
+++ b/drivers/gpu/drm/tinydrm/ili9341.c
@@ -56,13 +56,16 @@ static void yx240qv29_enable(struct drm_simple_display_pipe *pipe,
56{ 56{
57 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 57 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
58 u8 addr_mode; 58 u8 addr_mode;
59 int ret; 59 int ret, idx;
60
61 if (!drm_dev_enter(pipe->crtc.dev, &idx))
62 return;
60 63
61 DRM_DEBUG_KMS("\n"); 64 DRM_DEBUG_KMS("\n");
62 65
63 ret = mipi_dbi_poweron_conditional_reset(mipi); 66 ret = mipi_dbi_poweron_conditional_reset(mipi);
64 if (ret < 0) 67 if (ret < 0)
65 return; 68 goto out_exit;
66 if (ret == 1) 69 if (ret == 1)
67 goto out_enable; 70 goto out_enable;
68 71
@@ -128,6 +131,8 @@ out_enable:
128 addr_mode |= ILI9341_MADCTL_BGR; 131 addr_mode |= ILI9341_MADCTL_BGR;
129 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); 132 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
130 mipi_dbi_enable_flush(mipi, crtc_state, plane_state); 133 mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
134out_exit:
135 drm_dev_exit(idx);
131} 136}
132 137
133static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = { 138static const struct drm_simple_display_pipe_funcs ili9341_pipe_funcs = {
diff --git a/drivers/gpu/drm/tinydrm/mi0283qt.c b/drivers/gpu/drm/tinydrm/mi0283qt.c
index 7aee05586e92..c6dc31084a4e 100644
--- a/drivers/gpu/drm/tinydrm/mi0283qt.c
+++ b/drivers/gpu/drm/tinydrm/mi0283qt.c
@@ -58,13 +58,16 @@ static void mi0283qt_enable(struct drm_simple_display_pipe *pipe,
58{ 58{
59 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 59 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
60 u8 addr_mode; 60 u8 addr_mode;
61 int ret; 61 int ret, idx;
62
63 if (!drm_dev_enter(pipe->crtc.dev, &idx))
64 return;
62 65
63 DRM_DEBUG_KMS("\n"); 66 DRM_DEBUG_KMS("\n");
64 67
65 ret = mipi_dbi_poweron_conditional_reset(mipi); 68 ret = mipi_dbi_poweron_conditional_reset(mipi);
66 if (ret < 0) 69 if (ret < 0)
67 return; 70 goto out_exit;
68 if (ret == 1) 71 if (ret == 1)
69 goto out_enable; 72 goto out_enable;
70 73
@@ -136,6 +139,8 @@ out_enable:
136 addr_mode |= ILI9341_MADCTL_BGR; 139 addr_mode |= ILI9341_MADCTL_BGR;
137 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode); 140 mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
138 mipi_dbi_enable_flush(mipi, crtc_state, plane_state); 141 mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
142out_exit:
143 drm_dev_exit(idx);
139} 144}
140 145
141static const struct drm_simple_display_pipe_funcs mi0283qt_pipe_funcs = { 146static 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 5c848f975ebe..34d544f6e52d 100644
--- a/drivers/gpu/drm/tinydrm/mipi-dbi.c
+++ b/drivers/gpu/drm/tinydrm/mipi-dbi.c
@@ -220,13 +220,16 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
220 unsigned int height = rect->y2 - rect->y1; 220 unsigned int height = rect->y2 - rect->y1;
221 unsigned int width = rect->x2 - rect->x1; 221 unsigned int width = rect->x2 - rect->x1;
222 bool swap = mipi->swap_bytes; 222 bool swap = mipi->swap_bytes;
223 int ret = 0; 223 int idx, ret = 0;
224 bool full; 224 bool full;
225 void *tr; 225 void *tr;
226 226
227 if (!mipi->enabled) 227 if (!mipi->enabled)
228 return; 228 return;
229 229
230 if (!drm_dev_enter(fb->dev, &idx))
231 return;
232
230 full = width == fb->width && height == fb->height; 233 full = width == fb->width && height == fb->height;
231 234
232 DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect)); 235 DRM_DEBUG_KMS("Flushing [FB:%d] " DRM_RECT_FMT "\n", fb->base.id, DRM_RECT_ARG(rect));
@@ -253,6 +256,8 @@ static void mipi_dbi_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
253err_msg: 256err_msg:
254 if (ret) 257 if (ret)
255 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret); 258 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret);
259
260 drm_dev_exit(idx);
256} 261}
257 262
258/** 263/**
@@ -307,10 +312,16 @@ void mipi_dbi_enable_flush(struct mipi_dbi *mipi,
307 .y1 = 0, 312 .y1 = 0,
308 .y2 = fb->height, 313 .y2 = fb->height,
309 }; 314 };
315 int idx;
316
317 if (!drm_dev_enter(&mipi->drm, &idx))
318 return;
310 319
311 mipi->enabled = true; 320 mipi->enabled = true;
312 mipi_dbi_fb_dirty(fb, &rect); 321 mipi_dbi_fb_dirty(fb, &rect);
313 backlight_enable(mipi->backlight); 322 backlight_enable(mipi->backlight);
323
324 drm_dev_exit(idx);
314} 325}
315EXPORT_SYMBOL(mipi_dbi_enable_flush); 326EXPORT_SYMBOL(mipi_dbi_enable_flush);
316 327
@@ -320,6 +331,10 @@ static void mipi_dbi_blank(struct mipi_dbi *mipi)
320 u16 height = drm->mode_config.min_height; 331 u16 height = drm->mode_config.min_height;
321 u16 width = drm->mode_config.min_width; 332 u16 width = drm->mode_config.min_width;
322 size_t len = width * height * 2; 333 size_t len = width * height * 2;
334 int idx;
335
336 if (!drm_dev_enter(drm, &idx))
337 return;
323 338
324 memset(mipi->tx_buf, 0, len); 339 memset(mipi->tx_buf, 0, len);
325 340
@@ -329,6 +344,8 @@ static void mipi_dbi_blank(struct mipi_dbi *mipi)
329 (height >> 8) & 0xFF, (height - 1) & 0xFF); 344 (height >> 8) & 0xFF, (height - 1) & 0xFF);
330 mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, 345 mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START,
331 (u8 *)mipi->tx_buf, len); 346 (u8 *)mipi->tx_buf, len);
347
348 drm_dev_exit(idx);
332} 349}
333 350
334/** 351/**
@@ -343,6 +360,9 @@ void mipi_dbi_pipe_disable(struct drm_simple_display_pipe *pipe)
343{ 360{
344 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 361 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
345 362
363 if (!mipi->enabled)
364 return;
365
346 DRM_DEBUG_KMS("\n"); 366 DRM_DEBUG_KMS("\n");
347 367
348 mipi->enabled = false; 368 mipi->enabled = false;
@@ -991,11 +1011,16 @@ static ssize_t mipi_dbi_debugfs_command_write(struct file *file,
991 u8 val, cmd = 0, parameters[64]; 1011 u8 val, cmd = 0, parameters[64];
992 char *buf, *pos, *token; 1012 char *buf, *pos, *token;
993 unsigned int i; 1013 unsigned int i;
994 int ret; 1014 int ret, idx;
1015
1016 if (!drm_dev_enter(&mipi->drm, &idx))
1017 return -ENODEV;
995 1018
996 buf = memdup_user_nul(ubuf, count); 1019 buf = memdup_user_nul(ubuf, count);
997 if (IS_ERR(buf)) 1020 if (IS_ERR(buf)) {
998 return PTR_ERR(buf); 1021 ret = PTR_ERR(buf);
1022 goto err_exit;
1023 }
999 1024
1000 /* strip trailing whitespace */ 1025 /* strip trailing whitespace */
1001 for (i = count - 1; i > 0; i--) 1026 for (i = count - 1; i > 0; i--)
@@ -1031,6 +1056,8 @@ static ssize_t mipi_dbi_debugfs_command_write(struct file *file,
1031 1056
1032err_free: 1057err_free:
1033 kfree(buf); 1058 kfree(buf);
1059err_exit:
1060 drm_dev_exit(idx);
1034 1061
1035 return ret < 0 ? ret : count; 1062 return ret < 0 ? ret : count;
1036} 1063}
@@ -1039,8 +1066,11 @@ static int mipi_dbi_debugfs_command_show(struct seq_file *m, void *unused)
1039{ 1066{
1040 struct mipi_dbi *mipi = m->private; 1067 struct mipi_dbi *mipi = m->private;
1041 u8 cmd, val[4]; 1068 u8 cmd, val[4];
1069 int ret, idx;
1042 size_t len; 1070 size_t len;
1043 int ret; 1071
1072 if (!drm_dev_enter(&mipi->drm, &idx))
1073 return -ENODEV;
1044 1074
1045 for (cmd = 0; cmd < 255; cmd++) { 1075 for (cmd = 0; cmd < 255; cmd++) {
1046 if (!mipi_dbi_command_is_read(mipi, cmd)) 1076 if (!mipi_dbi_command_is_read(mipi, cmd))
@@ -1071,6 +1101,8 @@ static int mipi_dbi_debugfs_command_show(struct seq_file *m, void *unused)
1071 seq_printf(m, "%*phN\n", (int)len, val); 1101 seq_printf(m, "%*phN\n", (int)len, val);
1072 } 1102 }
1073 1103
1104 drm_dev_exit(idx);
1105
1074 return 0; 1106 return 0;
1075} 1107}
1076 1108
diff --git a/drivers/gpu/drm/tinydrm/repaper.c b/drivers/gpu/drm/tinydrm/repaper.c
index b1acf5aebe32..3f3632457079 100644
--- a/drivers/gpu/drm/tinydrm/repaper.c
+++ b/drivers/gpu/drm/tinydrm/repaper.c
@@ -533,8 +533,14 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
533 struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; 533 struct dma_buf_attachment *import_attach = cma_obj->base.import_attach;
534 struct repaper_epd *epd = drm_to_epd(fb->dev); 534 struct repaper_epd *epd = drm_to_epd(fb->dev);
535 struct drm_rect clip; 535 struct drm_rect clip;
536 int idx, ret = 0;
536 u8 *buf = NULL; 537 u8 *buf = NULL;
537 int ret = 0; 538
539 if (!epd->enabled)
540 return 0;
541
542 if (!drm_dev_enter(fb->dev, &idx))
543 return -ENODEV;
538 544
539 /* repaper can't do partial updates */ 545 /* repaper can't do partial updates */
540 clip.x1 = 0; 546 clip.x1 = 0;
@@ -542,17 +548,16 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
542 clip.y1 = 0; 548 clip.y1 = 0;
543 clip.y2 = fb->height; 549 clip.y2 = fb->height;
544 550
545 if (!epd->enabled)
546 return 0;
547
548 repaper_get_temperature(epd); 551 repaper_get_temperature(epd);
549 552
550 DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, 553 DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id,
551 epd->factored_stage_time); 554 epd->factored_stage_time);
552 555
553 buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL); 556 buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL);
554 if (!buf) 557 if (!buf) {
555 return -ENOMEM; 558 ret = -ENOMEM;
559 goto out_exit;
560 }
556 561
557 if (import_attach) { 562 if (import_attach) {
558 ret = dma_buf_begin_cpu_access(import_attach->dmabuf, 563 ret = dma_buf_begin_cpu_access(import_attach->dmabuf,
@@ -621,6 +626,8 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb)
621 626
622out_free: 627out_free:
623 kfree(buf); 628 kfree(buf);
629out_exit:
630 drm_dev_exit(idx);
624 631
625 return ret; 632 return ret;
626} 633}
@@ -650,7 +657,10 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
650 struct spi_device *spi = epd->spi; 657 struct spi_device *spi = epd->spi;
651 struct device *dev = &spi->dev; 658 struct device *dev = &spi->dev;
652 bool dc_ok = false; 659 bool dc_ok = false;
653 int i, ret; 660 int i, ret, idx;
661
662 if (!drm_dev_enter(pipe->crtc.dev, &idx))
663 return;
654 664
655 DRM_DEBUG_DRIVER("\n"); 665 DRM_DEBUG_DRIVER("\n");
656 666
@@ -689,7 +699,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
689 if (!i) { 699 if (!i) {
690 DRM_DEV_ERROR(dev, "timeout waiting for panel to become ready.\n"); 700 DRM_DEV_ERROR(dev, "timeout waiting for panel to become ready.\n");
691 power_off(epd); 701 power_off(epd);
692 return; 702 goto out_exit;
693 } 703 }
694 704
695 repaper_read_id(spi); 705 repaper_read_id(spi);
@@ -700,7 +710,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
700 else 710 else
701 dev_err(dev, "wrong COG ID 0x%02x\n", ret); 711 dev_err(dev, "wrong COG ID 0x%02x\n", ret);
702 power_off(epd); 712 power_off(epd);
703 return; 713 goto out_exit;
704 } 714 }
705 715
706 /* Disable OE */ 716 /* Disable OE */
@@ -713,7 +723,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
713 else 723 else
714 DRM_DEV_ERROR(dev, "panel is reported broken\n"); 724 DRM_DEV_ERROR(dev, "panel is reported broken\n");
715 power_off(epd); 725 power_off(epd);
716 return; 726 goto out_exit;
717 } 727 }
718 728
719 /* Power saving mode */ 729 /* Power saving mode */
@@ -753,7 +763,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
753 if (ret < 0) { 763 if (ret < 0) {
754 DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret); 764 DRM_DEV_ERROR(dev, "failed to read chip (%d)\n", ret);
755 power_off(epd); 765 power_off(epd);
756 return; 766 goto out_exit;
757 } 767 }
758 768
759 if (ret & 0x40) { 769 if (ret & 0x40) {
@@ -765,7 +775,7 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
765 if (!dc_ok) { 775 if (!dc_ok) {
766 DRM_DEV_ERROR(dev, "dc/dc failed\n"); 776 DRM_DEV_ERROR(dev, "dc/dc failed\n");
767 power_off(epd); 777 power_off(epd);
768 return; 778 goto out_exit;
769 } 779 }
770 780
771 /* 781 /*
@@ -776,6 +786,8 @@ static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe,
776 786
777 epd->enabled = true; 787 epd->enabled = true;
778 epd->partial = false; 788 epd->partial = false;
789out_exit:
790 drm_dev_exit(idx);
779} 791}
780 792
781static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe) 793static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
@@ -784,6 +796,16 @@ static void repaper_pipe_disable(struct drm_simple_display_pipe *pipe)
784 struct spi_device *spi = epd->spi; 796 struct spi_device *spi = epd->spi;
785 unsigned int line; 797 unsigned int line;
786 798
799 /*
800 * This callback is not protected by drm_dev_enter/exit since we want to
801 * turn off the display on regular driver unload. It's highly unlikely
802 * that the underlying SPI controller is gone should this be called after
803 * unplug.
804 */
805
806 if (!epd->enabled)
807 return;
808
787 DRM_DEBUG_DRIVER("\n"); 809 DRM_DEBUG_DRIVER("\n");
788 810
789 epd->enabled = false; 811 epd->enabled = false;
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,
119static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect) 119static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
120{ 120{
121 struct mipi_dbi *mipi = drm_to_mipi_dbi(fb->dev); 121 struct mipi_dbi *mipi = drm_to_mipi_dbi(fb->dev);
122 int start, end; 122 int start, end, idx, ret = 0;
123 int ret = 0;
124 123
125 if (!mipi->enabled) 124 if (!mipi->enabled)
126 return; 125 return;
127 126
127 if (!drm_dev_enter(fb->dev, &idx))
128 return;
129
128 /* 3 pixels per byte, so grow clip to nearest multiple of 3 */ 130 /* 3 pixels per byte, so grow clip to nearest multiple of 3 */
129 rect->x1 = rounddown(rect->x1, 3); 131 rect->x1 = rounddown(rect->x1, 3);
130 rect->x2 = roundup(rect->x2, 3); 132 rect->x2 = roundup(rect->x2, 3);
@@ -152,6 +154,8 @@ static void st7586_fb_dirty(struct drm_framebuffer *fb, struct drm_rect *rect)
152err_msg: 154err_msg:
153 if (ret) 155 if (ret)
154 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret); 156 dev_err_once(fb->dev->dev, "Failed to update display %d\n", ret);
157
158 drm_dev_exit(idx);
155} 159}
156 160
157static void st7586_pipe_update(struct drm_simple_display_pipe *pipe, 161static 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,
184 .y1 = 0, 188 .y1 = 0,
185 .y2 = fb->height, 189 .y2 = fb->height,
186 }; 190 };
187 int ret; 191 int idx, ret;
188 u8 addr_mode; 192 u8 addr_mode;
189 193
194 if (!drm_dev_enter(pipe->crtc.dev, &idx))
195 return;
196
190 DRM_DEBUG_KMS("\n"); 197 DRM_DEBUG_KMS("\n");
191 198
192 ret = mipi_dbi_poweron_reset(mipi); 199 ret = mipi_dbi_poweron_reset(mipi);
193 if (ret) 200 if (ret)
194 return; 201 goto out_exit;
195 202
196 mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f); 203 mipi_dbi_command(mipi, ST7586_AUTO_READ_CTRL, 0x9f);
197 mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00); 204 mipi_dbi_command(mipi, ST7586_OTP_RW_CTRL, 0x00);
@@ -244,12 +251,21 @@ static void st7586_pipe_enable(struct drm_simple_display_pipe *pipe,
244 st7586_fb_dirty(fb, &rect); 251 st7586_fb_dirty(fb, &rect);
245 252
246 mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON); 253 mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
254out_exit:
255 drm_dev_exit(idx);
247} 256}
248 257
249static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe) 258static void st7586_pipe_disable(struct drm_simple_display_pipe *pipe)
250{ 259{
251 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 260 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
252 261
262 /*
263 * This callback is not protected by drm_dev_enter/exit since we want to
264 * turn off the display on regular driver unload. It's highly unlikely
265 * that the underlying SPI controller is gone should this be called after
266 * unplug.
267 */
268
253 DRM_DEBUG_KMS("\n"); 269 DRM_DEBUG_KMS("\n");
254 270
255 if (!mipi->enabled) 271 if (!mipi->enabled)
diff --git a/drivers/gpu/drm/tinydrm/st7735r.c b/drivers/gpu/drm/tinydrm/st7735r.c
index 0f8a346026ac..022e9849b95b 100644
--- a/drivers/gpu/drm/tinydrm/st7735r.c
+++ b/drivers/gpu/drm/tinydrm/st7735r.c
@@ -44,14 +44,17 @@ static void jd_t18003_t01_pipe_enable(struct drm_simple_display_pipe *pipe,
44 struct drm_plane_state *plane_state) 44 struct drm_plane_state *plane_state)
45{ 45{
46 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev); 46 struct mipi_dbi *mipi = drm_to_mipi_dbi(pipe->crtc.dev);
47 int ret; 47 int ret, idx;
48 u8 addr_mode; 48 u8 addr_mode;
49 49
50 if (!drm_dev_enter(pipe->crtc.dev, &idx))
51 return;
52
50 DRM_DEBUG_KMS("\n"); 53 DRM_DEBUG_KMS("\n");
51 54
52 ret = mipi_dbi_poweron_reset(mipi); 55 ret = mipi_dbi_poweron_reset(mipi);
53 if (ret) 56 if (ret)
54 return; 57 goto out_exit;
55 58
56 msleep(150); 59 msleep(150);
57 60
@@ -102,6 +105,8 @@ static void jd_t18003_t01_pipe_enable(struct drm_simple_display_pipe *pipe,
102 msleep(20); 105 msleep(20);
103 106
104 mipi_dbi_enable_flush(mipi, crtc_state, plane_state); 107 mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
108out_exit:
109 drm_dev_exit(idx);
105} 110}
106 111
107static const struct drm_simple_display_pipe_funcs jd_t18003_t01_pipe_funcs = { 112static const struct drm_simple_display_pipe_funcs jd_t18003_t01_pipe_funcs = {