2019-05-19 15:08:55 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-17 02:20:36 +04:00
/*
* linux / drivers / video / dummycon . c - - A dummy console driver
*
* To be used if there ' s no other console driver ( e . g . for plain VGA text )
* available , usually until fbcon takes console over .
*/
# include <linux/types.h>
# include <linux/kdev_t.h>
# include <linux/console.h>
# include <linux/vt_kern.h>
2006-07-10 15:44:13 +04:00
# include <linux/screen_info.h>
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/module.h>
/*
* Dummy console driver
*/
# if defined(__arm__)
2007-10-17 09:36:04 +04:00
# define DUMMY_COLUMNS screen_info.orig_video_cols
# define DUMMY_ROWS screen_info.orig_video_lines
2015-01-12 23:17:02 +03:00
# else
2005-04-17 02:20:36 +04:00
/* set by Kconfig. Use 80x25 for 640x480 and 160x64 for 1280x1024 */
# define DUMMY_COLUMNS CONFIG_DUMMY_CONSOLE_COLUMNS
# define DUMMY_ROWS CONFIG_DUMMY_CONSOLE_ROWS
# endif
2018-06-28 16:20:30 +03:00
# ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
/* These are both protected by the console_lock */
static RAW_NOTIFIER_HEAD ( dummycon_output_nh ) ;
static bool dummycon_putc_called ;
void dummycon_register_output_notifier ( struct notifier_block * nb )
{
2019-05-28 12:02:32 +03:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 16:20:30 +03:00
raw_notifier_chain_register ( & dummycon_output_nh , nb ) ;
if ( dummycon_putc_called )
nb - > notifier_call ( nb , 0 , NULL ) ;
}
void dummycon_unregister_output_notifier ( struct notifier_block * nb )
{
2019-05-28 12:02:32 +03:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 16:20:30 +03:00
raw_notifier_chain_unregister ( & dummycon_output_nh , nb ) ;
}
static void dummycon_putc ( struct vc_data * vc , int c , int ypos , int xpos )
{
2019-05-28 12:02:32 +03:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 16:20:30 +03:00
dummycon_putc_called = true ;
raw_notifier_call_chain ( & dummycon_output_nh , 0 , NULL ) ;
}
static void dummycon_putcs ( struct vc_data * vc , const unsigned short * s ,
int count , int ypos , int xpos )
{
int i ;
if ( ! dummycon_putc_called ) {
/* Ignore erases */
for ( i = 0 ; i < count ; i + + ) {
if ( s [ i ] ! = vc - > vc_video_erase_char )
break ;
}
if ( i = = count )
return ;
dummycon_putc_called = true ;
}
raw_notifier_call_chain ( & dummycon_output_nh , 0 , NULL ) ;
}
static int dummycon_blank ( struct vc_data * vc , int blank , int mode_switch )
{
/* Redraw, so that we get putc(s) for output done while blanked */
return 1 ;
}
# else
static void dummycon_putc ( struct vc_data * vc , int c , int ypos , int xpos ) { }
static void dummycon_putcs ( struct vc_data * vc , const unsigned short * s ,
int count , int ypos , int xpos ) { }
static int dummycon_blank ( struct vc_data * vc , int blank , int mode_switch )
{
return 0 ;
}
# endif
2005-04-17 02:20:36 +04:00
static const char * dummycon_startup ( void )
{
return " dummy device " ;
}
static void dummycon_init ( struct vc_data * vc , int init )
{
vc - > vc_can_do_color = 1 ;
if ( init ) {
vc - > vc_cols = DUMMY_COLUMNS ;
vc - > vc_rows = DUMMY_ROWS ;
} else
vc_resize ( vc , DUMMY_COLUMNS , DUMMY_ROWS ) ;
}
2018-02-27 03:04:20 +03:00
static void dummycon_deinit ( struct vc_data * vc ) { }
static void dummycon_clear ( struct vc_data * vc , int sy , int sx , int height ,
int width ) { }
static void dummycon_cursor ( struct vc_data * vc , int mode ) { }
static bool dummycon_scroll ( struct vc_data * vc , unsigned int top ,
unsigned int bottom , enum con_scroll dir ,
unsigned int lines )
{
return false ;
}
static int dummycon_switch ( struct vc_data * vc )
2005-04-17 02:20:36 +04:00
{
2018-02-27 03:04:20 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
/*
* The console ` switch ' structure for the dummy console
*
* Most of the operations are dummies .
*/
const struct consw dummy_con = {
2018-02-27 03:04:20 +03:00
. owner = THIS_MODULE ,
. con_startup = dummycon_startup ,
. con_init = dummycon_init ,
. con_deinit = dummycon_deinit ,
. con_clear = dummycon_clear ,
. con_putc = dummycon_putc ,
. con_putcs = dummycon_putcs ,
. con_cursor = dummycon_cursor ,
. con_scroll = dummycon_scroll ,
. con_switch = dummycon_switch ,
. con_blank = dummycon_blank ,
2005-04-17 02:20:36 +04:00
} ;
2014-06-05 18:20:46 +04:00
EXPORT_SYMBOL_GPL ( dummy_con ) ;