1 /* 2 * linux/drivers/video/dummycon.c -- A dummy console driver 3 * 4 * To be used if there's no other console driver (e.g. for plain VGA text) 5 * available, usually until fbcon takes console over. 6 */ 7 8 #include <linux/types.h> 9 #include <linux/kdev_t.h> 10 #include <linux/console.h> 11 #include <linux/vt_kern.h> 12 #include <linux/screen_info.h> 13 #include <linux/init.h> 14 #include <linux/module.h> 15 16 /* 17 * Dummy console driver 18 */ 19 20 #if defined(__arm__) 21 #define DUMMY_COLUMNS screen_info.orig_video_cols 22 #define DUMMY_ROWS screen_info.orig_video_lines 23 #else 24 /* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */ 25 #define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS 26 #define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS 27 #endif 28 29 #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER 30 /* These are both protected by the console_lock */ 31 static RAW_NOTIFIER_HEAD(dummycon_output_nh); 32 static bool dummycon_putc_called; 33 34 void dummycon_register_output_notifier(struct notifier_block *nb) 35 { 36 raw_notifier_chain_register(&dummycon_output_nh, nb); 37 38 if (dummycon_putc_called) 39 nb->notifier_call(nb, 0, NULL); 40 } 41 42 void dummycon_unregister_output_notifier(struct notifier_block *nb) 43 { 44 raw_notifier_chain_unregister(&dummycon_output_nh, nb); 45 } 46 47 static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) 48 { 49 dummycon_putc_called = true; 50 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); 51 } 52 53 static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, 54 int count, int ypos, int xpos) 55 { 56 int i; 57 58 if (!dummycon_putc_called) { 59 /* Ignore erases */ 60 for (i = 0 ; i < count; i++) { 61 if (s[i] != vc->vc_video_erase_char) 62 break; 63 } 64 if (i == count) 65 return; 66 67 dummycon_putc_called = true; 68 } 69 70 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); 71 } 72 73 static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) 74 { 75 /* Redraw, so that we get putc(s) for output done while blanked */ 76 return 1; 77 } 78 #else 79 static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } 80 static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, 81 int count, int ypos, int xpos) { } 82 static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) 83 { 84 return 0; 85 } 86 #endif 87 88 static const char *dummycon_startup(void) 89 { 90 return "dummy device"; 91 } 92 93 static void dummycon_init(struct vc_data *vc, int init) 94 { 95 vc->vc_can_do_color = 1; 96 if (init) { 97 vc->vc_cols = DUMMY_COLUMNS; 98 vc->vc_rows = DUMMY_ROWS; 99 } else 100 vc_resize(vc, DUMMY_COLUMNS, DUMMY_ROWS); 101 } 102 103 static void dummycon_deinit(struct vc_data *vc) { } 104 static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height, 105 int width) { } 106 static void dummycon_cursor(struct vc_data *vc, int mode) { } 107 108 static bool dummycon_scroll(struct vc_data *vc, unsigned int top, 109 unsigned int bottom, enum con_scroll dir, 110 unsigned int lines) 111 { 112 return false; 113 } 114 115 static int dummycon_switch(struct vc_data *vc) 116 { 117 return 0; 118 } 119 120 static int dummycon_font_set(struct vc_data *vc, struct console_font *font, 121 unsigned int flags) 122 { 123 return 0; 124 } 125 126 static int dummycon_font_default(struct vc_data *vc, 127 struct console_font *font, char *name) 128 { 129 return 0; 130 } 131 132 static int dummycon_font_copy(struct vc_data *vc, int con) 133 { 134 return 0; 135 } 136 137 /* 138 * The console `switch' structure for the dummy console 139 * 140 * Most of the operations are dummies. 141 */ 142 143 const struct consw dummy_con = { 144 .owner = THIS_MODULE, 145 .con_startup = dummycon_startup, 146 .con_init = dummycon_init, 147 .con_deinit = dummycon_deinit, 148 .con_clear = dummycon_clear, 149 .con_putc = dummycon_putc, 150 .con_putcs = dummycon_putcs, 151 .con_cursor = dummycon_cursor, 152 .con_scroll = dummycon_scroll, 153 .con_switch = dummycon_switch, 154 .con_blank = dummycon_blank, 155 .con_font_set = dummycon_font_set, 156 .con_font_default = dummycon_font_default, 157 .con_font_copy = dummycon_font_copy, 158 }; 159 EXPORT_SYMBOL_GPL(dummy_con); 160