2019-05-19 13:08:55 +01:00
// SPDX-License-Identifier: GPL-2.0-only
2005-04-16 15:20:36 -07: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 04:44:13 -07:00
# include <linux/screen_info.h>
2005-04-16 15:20:36 -07:00
# include <linux/init.h>
# include <linux/module.h>
/*
* Dummy console driver
*/
dummycon: limit Arm console size hack to footbridge
The dummycon default console size used to be determined by architecture,
but now this is a Kconfig setting on everything except ARM. Tracing this
back in the historic git trees, this was used to match the size of VGA
console or VGA framebuffer on early machines, but nowadays that code is
no longer used, except probably on the old footbridge/netwinder since
that is the only one that supports vgacon.
On machines with a framebuffer, booting with DT so far results in always
using the hardcoded 80x30 size in dummycon, while on ATAGS the setting
can come from a bootloader specific override. Both seem to be worse
choices than the Kconfig setting, since the actual text size for fbcon
also depends on the selected font.
Make this work the same way as everywhere else and use the normal
Kconfig setting, except for the footbridge with vgacon, which keeps
using the traditional code. If vgacon is disabled, footbridge can
also ignore the setting. This means the screen_info only has to be
provided when either vgacon or EFI are enabled now.
To limit the amount of surprises on Arm, change the Kconfig default
to the previously used 80x30 setting instead of the usual 80x25.
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Acked-by: Helge Deller <deller@gmx.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20231009211845.3136536-4-arnd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2023-10-09 23:18:39 +02:00
# if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_VGA_CONSOLE)
2023-10-17 11:39:47 +02:00
# include <asm/vga.h>
# define DUMMY_COLUMNS vgacon_screen_info.orig_video_cols
# define DUMMY_ROWS vgacon_screen_info.orig_video_lines
2015-01-12 21:17:02 +01:00
# else
2005-04-16 15:20:36 -07: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 15:20:30 +02: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 11:02:32 +02:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 15:20:30 +02: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 11:02:32 +02:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 15:20:30 +02: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 11:02:32 +02:00
WARN_CONSOLE_UNLOCKED ( ) ;
2018-06-28 15:20:30 +02: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-16 15:20:36 -07: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-26 16:04:20 -08: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-16 15:20:36 -07:00
{
2018-02-26 16:04:20 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
/*
* The console ` switch ' structure for the dummy console
*
* Most of the operations are dummies .
*/
const struct consw dummy_con = {
2018-02-26 16:04:20 -08: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-16 15:20:36 -07:00
} ;
2014-06-05 16:20:46 +02:00
EXPORT_SYMBOL_GPL ( dummy_con ) ;