Commit 1a7aba7f4e45014c5a4741164b1ecb4ffe616fb7

Authored by Jesse Barnes
Committed by Jason Wessel
1 parent d219adc122

drm: add KGDB/KDB support

Implement the callbacks for KDB entry/exit via the drm helpers.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>

Showing 3 changed files with 81 additions and 0 deletions Side-by-side Diff

drivers/gpu/drm/drm_fb_helper.c
... ... @@ -241,6 +241,80 @@
241 241 return 0;
242 242 }
243 243  
  244 +int drm_fb_helper_debug_enter(struct fb_info *info)
  245 +{
  246 + struct drm_fb_helper *helper = info->par;
  247 + struct drm_crtc_helper_funcs *funcs;
  248 + int i;
  249 +
  250 + if (list_empty(&kernel_fb_helper_list))
  251 + return false;
  252 +
  253 + list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
  254 + for (i = 0; i < helper->crtc_count; i++) {
  255 + struct drm_mode_set *mode_set =
  256 + &helper->crtc_info[i].mode_set;
  257 +
  258 + if (!mode_set->crtc->enabled)
  259 + continue;
  260 +
  261 + funcs = mode_set->crtc->helper_private;
  262 + funcs->mode_set_base_atomic(mode_set->crtc,
  263 + mode_set->fb,
  264 + mode_set->x,
  265 + mode_set->y);
  266 +
  267 + }
  268 + }
  269 +
  270 + return 0;
  271 +}
  272 +EXPORT_SYMBOL(drm_fb_helper_debug_enter);
  273 +
  274 +/* Find the real fb for a given fb helper CRTC */
  275 +static struct drm_framebuffer *drm_mode_config_fb(struct drm_crtc *crtc)
  276 +{
  277 + struct drm_device *dev = crtc->dev;
  278 + struct drm_crtc *c;
  279 +
  280 + list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
  281 + if (crtc->base.id == c->base.id)
  282 + return c->fb;
  283 + }
  284 +
  285 + return NULL;
  286 +}
  287 +
  288 +int drm_fb_helper_debug_leave(struct fb_info *info)
  289 +{
  290 + struct drm_fb_helper *helper = info->par;
  291 + struct drm_crtc *crtc;
  292 + struct drm_crtc_helper_funcs *funcs;
  293 + struct drm_framebuffer *fb;
  294 + int i;
  295 +
  296 + for (i = 0; i < helper->crtc_count; i++) {
  297 + struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set;
  298 + crtc = mode_set->crtc;
  299 + funcs = crtc->helper_private;
  300 + fb = drm_mode_config_fb(crtc);
  301 +
  302 + if (!crtc->enabled)
  303 + continue;
  304 +
  305 + if (!fb) {
  306 + DRM_ERROR("no fb to restore??\n");
  307 + continue;
  308 + }
  309 +
  310 + funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
  311 + crtc->y);
  312 + }
  313 +
  314 + return 0;
  315 +}
  316 +EXPORT_SYMBOL(drm_fb_helper_debug_leave);
  317 +
244 318 bool drm_fb_helper_force_kernel_mode(void)
245 319 {
246 320 int i = 0;
include/drm/drm_crtc_helper.h
... ... @@ -60,6 +60,8 @@
60 60 /* Move the crtc on the current fb to the given position *optional* */
61 61 int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
62 62 struct drm_framebuffer *old_fb);
  63 + int (*mode_set_base_atomic)(struct drm_crtc *crtc,
  64 + struct drm_framebuffer *fb, int x, int y);
63 65  
64 66 /* reload the current crtc LUT */
65 67 void (*load_lut)(struct drm_crtc *crtc);
include/drm/drm_fb_helper.h
... ... @@ -32,6 +32,8 @@
32 32  
33 33 struct drm_fb_helper;
34 34  
  35 +#include <linux/kgdb.h>
  36 +
35 37 struct drm_fb_helper_crtc {
36 38 uint32_t crtc_id;
37 39 struct drm_mode_set mode_set;
... ... @@ -78,6 +80,7 @@
78 80  
79 81 struct drm_fb_helper {
80 82 struct drm_framebuffer *fb;
  83 + struct drm_framebuffer *saved_fb;
81 84 struct drm_device *dev;
82 85 struct drm_display_mode *mode;
83 86 int crtc_count;
... ... @@ -126,6 +129,8 @@
126 129 bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
127 130 bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel);
128 131 int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);
  132 +int drm_fb_helper_debug_enter(struct fb_info *info);
  133 +int drm_fb_helper_debug_leave(struct fb_info *info);
129 134  
130 135 #endif