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 EXPORT_SYMBOL_GPL(dummycon_register_output_notifier); 42 43 void dummycon_unregister_output_notifier(struct notifier_block *nb) 44 { 45 raw_notifier_chain_unregister(&dummycon_output_nh, nb); 46 } 47 EXPORT_SYMBOL_GPL(dummycon_unregister_output_notifier); 48 49 static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) 50 { 51 dummycon_putc_called = true; 52 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); 53 } 54 55 static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, 56 int count, int ypos, int xpos) 57 { 58 int i; 59 60 if (!dummycon_putc_called) { 61 /* Ignore erases */ 62 for (i = 0 ; i < count; i++) { 63 if (s[i] != vc->vc_video_erase_char) 64 break; 65 } 66 if (i == count) 67 return; 68 69 dummycon_putc_called = true; 70 } 71 72 raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); 73 } 74 75 static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) 76 { 77 /* Redraw, so that we get putc(s) for output done while blanked */ 78 return 1; 79 } 80 #else 81 static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { } 82 static void dummycon_putcs(struct vc_data *vc, const unsigned short *s, 83 int count, int ypos, int xpos) { } 84 static int dummycon_blank(struct vc_data *vc, int blank, int mode_switch) 85 { 86 return 0; 87 } 88 #endif 89 90 static const char *dummycon_startup(void) 91 { 92 return "dummy device"; 93 } 94 95 static void dummycon_init(struct vc_data *vc, int init) 96 { 97 vc->vc_can_do_color = 1; 98 if (init) { 99 vc->vc_cols = DUMMY_COLUMNS; 100 vc->vc_rows = DUMMY_ROWS; 101 } else 102 vc_resize(vc, DUMMY_COLUMNS, DUMMY_ROWS); 103 } 104 105 static void dummycon_deinit(struct vc_data *vc) { } 106 static void dummycon_clear(struct vc_data *vc, int sy, int sx, int height, 107 int width) { } 108 static void dummycon_cursor(struct vc_data *vc, int mode) { } 109 110 static bool dummycon_scroll(struct vc_data *vc, unsigned int top, 111 unsigned int bottom, enum con_scroll dir, 112 unsigned int lines) 113 { 114 return false; 115 } 116 117 static int dummycon_switch(struct vc_data *vc) 118 { 119 return 0; 120 } 121 122 static int dummycon_font_set(struct vc_data *vc, struct console_font *font, 123 unsigned int flags) 124 { 125 return 0; 126 } 127 128 static int dummycon_font_default(struct vc_data *vc, 129 struct console_font *font, char *name) 130 { 131 return 0; 132 } 133 134 static int dummycon_font_copy(struct vc_data *vc, int con) 135 { 136 return 0; 137 } 138 139 /* 140 * The console `switch' structure for the dummy console 141 * 142 * Most of the operations are dummies. 143 */ 144 145 const struct consw dummy_con = { 146 .owner = THIS_MODULE, 147 .con_startup = dummycon_startup, 148 .con_init = dummycon_init, 149 .con_deinit = dummycon_deinit, 150 .con_clear = dummycon_clear, 151 .con_putc = dummycon_putc, 152 .con_putcs = dummycon_putcs, 153 .con_cursor = dummycon_cursor, 154 .con_scroll = dummycon_scroll, 155 .con_switch = dummycon_switch, 156 .con_blank = dummycon_blank, 157 .con_font_set = dummycon_font_set, 158 .con_font_default = dummycon_font_default, 159 .con_font_copy = dummycon_font_copy, 160 }; 161 EXPORT_SYMBOL_GPL(dummy_con); 162