fb: add hooks to handle KDB enter/exit
authorJesse Barnes <jbarnes@virtuousgeek.org>
Mon, 2 Aug 2010 19:05:41 +0000 (12:05 -0700)
committerJason Wessel <jason.wessel@windriver.com>
Thu, 5 Aug 2010 14:22:31 +0000 (09:22 -0500)
Add fb ops to handle enter/exit of the kernel debugger.  If present, the
fb core will register them with KGDB and they'll be called when the
debugger is entered and exited.  The new functions are responsible for
switching to an appropriate debug framebuffer and restoring the
interrupted state at exit time.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
include/linux/fb.h

index b0a3fa00706d2e25896fc862aa1bcc116010a6c7..3b3f5749af925c83d055fa41df0a1c6baed92e5a 100644 (file)
@@ -2342,6 +2342,30 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
        return 0;
 }
 
+static int fbcon_debug_enter(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->save_graphics = ops->graphics;
+       ops->graphics = 0;
+       if (info->fbops->fb_debug_enter)
+               info->fbops->fb_debug_enter(info);
+       fbcon_set_palette(vc, color_table);
+       return 0;
+}
+
+static int fbcon_debug_leave(struct vc_data *vc)
+{
+       struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+       struct fbcon_ops *ops = info->fbcon_par;
+
+       ops->graphics = ops->save_graphics;
+       if (info->fbops->fb_debug_leave)
+               info->fbops->fb_debug_leave(info);
+       return 0;
+}
+
 static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
 {
        u8 *fontdata = vc->vc_font.data;
@@ -3276,6 +3300,8 @@ static const struct consw fb_con = {
        .con_screen_pos         = fbcon_screen_pos,
        .con_getxy              = fbcon_getxy,
        .con_resize             = fbcon_resize,
+       .con_debug_enter        = fbcon_debug_enter,
+       .con_debug_leave        = fbcon_debug_leave,
 };
 
 static struct notifier_block fbcon_event_notifier = {
index 89a346880ec014897f051168013d4af7fc5cd091..6bd2e0c7f209d402cbbf75bb3b088a7c58f3ed24 100644 (file)
@@ -74,6 +74,7 @@ struct fbcon_ops {
        int    cursor_reset;
        int    blank_state;
        int    graphics;
+       int    save_graphics; /* for debug enter/leave */
        int    flags;
        int    rotate;
        int    cur_rotate;
index e7445df44d6c9324fd32a85ee1145415ecbd7960..0c5659c41b01c502160ca089bd758a36963f7918 100644 (file)
@@ -3,6 +3,9 @@
 
 #include <linux/types.h>
 #include <linux/i2c.h>
+#ifdef __KERNEL__
+#include <linux/kgdb.h>
+#endif /* __KERNEL__ */
 
 /* Definitions of frame buffers                                                */
 
@@ -607,6 +610,12 @@ struct fb_deferred_io {
  * LOCKING NOTE: those functions must _ALL_ be called with the console
  * semaphore held, this is the only suitable locking mechanism we have
  * in 2.6. Some may be called at interrupt time at this point though.
+ *
+ * The exception to this is the debug related hooks.  Putting the fb
+ * into a debug state (e.g. flipping to the kernel console) and restoring
+ * it must be done in a lock-free manner, so low level drivers should
+ * keep track of the initial console (if applicable) and may need to
+ * perform direct, unlocked hardware writes in these hooks.
  */
 
 struct fb_ops {
@@ -676,6 +685,10 @@ struct fb_ops {
 
        /* teardown any resources to do with this framebuffer */
        void (*fb_destroy)(struct fb_info *info);
+
+       /* called at KDB enter and leave time to prepare the console */
+       int (*fb_debug_enter)(struct fb_info *info);
+       int (*fb_debug_leave)(struct fb_info *info);
 };
 
 #ifdef CONFIG_FB_TILEBLITTING