Signed-off-by: Thomas Zimmermann <[email protected]>
---
drivers/gpu/drm/drm_panic.c | 41 +++++++++++++++++---------
drivers/gpu/drm/tests/drm_panic_test.c | 16 ++++++----
2 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index 96d238bfceee..594235661710 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -478,7 +478,7 @@ static void drm_panic_logo_draw(struct drm_scanout_buffer
*sb, struct drm_rect *
fg_color);
}
-static void draw_panic_screen_user(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_user(struct drm_scanout_buffer *sb)
{
u32 fg_color =
drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -489,7 +489,7 @@ static void draw_panic_screen_user(struct
drm_scanout_buffer *sb)
unsigned int msg_width, msg_height;
if (!font)
- return;
+ return -EINVAL;
r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
drm_panic_logo_rect(&r_logo, font);
@@ -508,6 +508,8 @@ static void draw_panic_screen_user(struct
drm_scanout_buffer *sb)
drm_panic_logo_draw(sb, &r_logo, font, fg_color);
draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color);
+
+ return 0;
}
/*
@@ -547,7 +549,7 @@ static int draw_line_with_wrap(struct drm_scanout_buffer
*sb, const struct font_
* Draw the kmsg buffer to the screen, starting from the youngest message at
the bottom,
* and going up until reaching the top of the screen.
*/
-static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
{
u32 fg_color =
drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR,
sb->format->format);
@@ -562,7 +564,7 @@ static void draw_panic_screen_kmsg(struct
drm_scanout_buffer *sb)
int yoffset;
if (!font || font->width > sb->width)
- return;
+ return -EINVAL;
yoffset = sb->height - font->height - (sb->height % font->height) / 2;
@@ -589,6 +591,8 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
start--;
}
}
+
+ return 0;
}
#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
@@ -814,10 +818,11 @@ static int _draw_panic_screen_qr_code(struct
drm_scanout_buffer *sb)
return 0;
}
-static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
+static int draw_panic_screen_qr_code(struct drm_scanout_buffer *sb)
{
if (_draw_panic_screen_qr_code(sb))
draw_panic_screen_user(sb);
+ return 0;
}
#else
static void drm_panic_qr_init(void) {};
@@ -888,23 +893,25 @@ static bool drm_panic_is_format_supported(const struct
drm_format_info *format)
return drm_draw_can_convert_from_xrgb8888(format->format);
}
-static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
+static int draw_panic_dispatch(struct drm_scanout_buffer *sb)
{
+ int ret;
+
switch (drm_panic_type) {
case DRM_PANIC_TYPE_KMSG:
- draw_panic_screen_kmsg(sb);
+ ret = draw_panic_screen_kmsg(sb);
break;
-
#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
case DRM_PANIC_TYPE_QR:
- draw_panic_screen_qr_code(sb);
+ ret = draw_panic_screen_qr_code(sb);
break;
#endif
-
case DRM_PANIC_TYPE_USER:
default:
- draw_panic_screen_user(sb);
+ ret = draw_panic_screen_user(sb);
}
+
+ return ret;
}
static void drm_panic_set_description(const char *description)
@@ -951,9 +958,15 @@ static void draw_panic_plane(struct drm_plane *plane,
const char *description)
drm_panic_set_description(description);
- draw_panic_dispatch(&sb);
- if (plane->helper_private->panic_flush)
- plane->helper_private->panic_flush(plane);
+ ret = draw_panic_dispatch(&sb);
+ if (!ret) {
+ /*
+ * Only flush if we have a panic screen to display. Otherwise
+ * it's probably better to leave the display output as-is.
+ */
+ if (plane->helper_private->panic_flush)
+ plane->helper_private->panic_flush(plane);
+ }
drm_panic_clear_description();
diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c
index ad2f3a2f93b6..fdd77b0cc54c 100644
--- a/drivers/gpu/drm/tests/drm_panic_test.c
+++ b/drivers/gpu/drm/tests/drm_panic_test.c
@@ -30,7 +30,7 @@ struct drm_test_mode {
const int width;
const int height;
const u32 format;
- void (*draw_screen)(struct drm_scanout_buffer *sb);
+ int (*draw_screen)(struct drm_scanout_buffer *sb);
const char *fname;
};
@@ -87,7 +87,7 @@ static void drm_test_panic_screen_user_map(struct kunit *test)
const struct drm_test_mode *params = test->param_value;
char *fb;
int fb_size;
- int i;
+ int i, ret;
sb->format = drm_format_info(params->format);
fb_size = params->width * params->height * sb->format->cpp[0];
@@ -102,7 +102,8 @@ static void drm_test_panic_screen_user_map(struct kunit
*test)
sb->height = params->height;
sb->pitch[0] = params->width * sb->format->cpp[0];
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
for (i = 0; i < fb_size; i++)
drm_panic_check_color_byte(test, fb[i]);
@@ -119,7 +120,7 @@ static void drm_test_panic_screen_user_page(struct kunit
*test)
{
struct drm_scanout_buffer *sb = test->priv;
const struct drm_test_mode *params = test->param_value;
- int fb_size, p, i, npages;
+ int fb_size, p, i, npages, ret;
struct page **pages;
u8 *vaddr;
@@ -146,7 +147,8 @@ static void drm_test_panic_screen_user_page(struct kunit *test)
sb->height = params->height;
sb->pitch[0] = params->width * sb->format->cpp[0];
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
for (p = 0; p < npages; p++) {
int bytes_in_page = (p == npages - 1) ? fb_size - p * PAGE_SIZE
: PAGE_SIZE;
@@ -182,6 +184,7 @@ static void drm_test_panic_screen_user_set_pixel(struct
kunit *test)
{
struct drm_scanout_buffer *sb = test->priv;
const struct drm_test_mode *params = test->param_value;
+ int ret;
sb->format = drm_format_info(params->format);
sb->set_pixel = drm_test_panic_set_pixel;
@@ -189,7 +192,8 @@ static void drm_test_panic_screen_user_set_pixel(struct
kunit *test)
sb->height = params->height;
sb->private = test;
- params->draw_screen(sb);
+ ret = params->draw_screen(sb);
+ KUNIT_ASSERT_EQ(test, ret, 0);
}
static void drm_test_panic_desc(const struct drm_test_mode *t, char *desc)