Commit 1a7aba7f4e45014c5a4741164b1ecb4ffe616fb7
Committed by
Jason Wessel
1 parent
d219adc122
Exists in
master
and in
20 other branches
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 |