aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console/fbcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/console/fbcon.c')
-rw-r--r--drivers/video/console/fbcon.c86
1 files changed, 44 insertions, 42 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index de92afb5eecf4..59e3b4b4e7e3e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,15 +107,15 @@ enum {
};
struct display fb_display[MAX_NR_CONSOLES];
-signed char con2fb_map[MAX_NR_CONSOLES];
-signed char con2fb_map_boot[MAX_NR_CONSOLES];
+static signed char con2fb_map[MAX_NR_CONSOLES];
+static signed char con2fb_map_boot[MAX_NR_CONSOLES];
static int logo_height;
static int logo_lines;
/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
enums. */
static int logo_shown = FBCON_LOGO_CANSHOW;
/* Software scrollback */
-int fbcon_softback_size = 32768;
+static int fbcon_softback_size = 32768;
static unsigned long softback_buf, softback_curr;
static unsigned long softback_in;
static unsigned long softback_top, softback_end;
@@ -130,6 +130,8 @@ static char fontname[40];
/* current fb_info */
static int info_idx = -1;
+static const struct consw fb_con;
+
#define CM_SOFTBACK (8)
#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
@@ -204,8 +206,10 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp)
static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
{
+ struct fbcon_ops *ops = info->fbcon_par;
+
return (info->state != FBINFO_STATE_RUNNING ||
- vc->vc_mode != KD_TEXT);
+ vc->vc_mode != KD_TEXT || ops->graphics);
}
static inline int get_color(struct vc_data *vc, struct fb_info *info,
@@ -307,7 +311,8 @@ static void cursor_timer_handler(unsigned long dev_addr)
mod_timer(&ops->cursor_timer, jiffies + HZ/5);
}
-int __init fb_console_setup(char *this_opt)
+#ifndef MODULE
+static int __init fb_console_setup(char *this_opt)
{
char *options;
int i, j;
@@ -361,6 +366,7 @@ int __init fb_console_setup(char *this_opt)
}
__setup("fbcon=", fb_console_setup);
+#endif
static int search_fb_in_map(int idx)
{
@@ -593,9 +599,12 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
ops->currcon = fg_console;
- if (info->fbops->fb_set_par)
+ if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT))
info->fbops->fb_set_par(info);
+ ops->flags |= FBCON_FLAGS_INIT;
+ ops->graphics = 0;
+
if (vc)
fbcon_set_disp(info, &info->var, vc);
else
@@ -695,6 +704,7 @@ static int var_to_display(struct display *disp,
disp->green = var->green;
disp->blue = var->blue;
disp->transp = var->transp;
+ disp->rotate = var->rotate;
disp->mode = fb_match_mode(var, &info->modelist);
if (disp->mode == NULL)
/* This should not happen */
@@ -718,6 +728,7 @@ static void display_to_var(struct fb_var_screeninfo *var,
var->green = disp->green;
var->blue = disp->blue;
var->transp = disp->transp;
+ var->rotate = disp->rotate;
}
static const char *fbcon_startup(void)
@@ -763,6 +774,7 @@ static const char *fbcon_startup(void)
memset(ops, 0, sizeof(struct fbcon_ops));
ops->currcon = -1;
+ ops->graphics = 1;
info->fbcon_par = ops;
set_blitting_type(vc, info, NULL);
@@ -889,6 +901,7 @@ static const char *fbcon_startup(void)
static void fbcon_init(struct vc_data *vc, int init)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ struct fbcon_ops *ops;
struct vc_data **default_mode = vc->vc_display_fg;
struct vc_data *svc = *default_mode;
struct display *t, *p = &fb_display[vc->vc_num];
@@ -939,6 +952,8 @@ static void fbcon_init(struct vc_data *vc, int init)
new_cols = info->var.xres / vc->vc_font.width;
new_rows = info->var.yres / vc->vc_font.height;
vc_resize(vc, new_cols, new_rows);
+
+ ops = info->fbcon_par;
/*
* We must always set the mode. The mode of the previous console
* driver could be in the same resolution but we are using different
@@ -946,9 +961,14 @@ static void fbcon_init(struct vc_data *vc, int init)
*
* We need to do it in fbcon_init() to prevent screen corruption.
*/
- if (CON_IS_VISIBLE(vc) && info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
+ if (CON_IS_VISIBLE(vc)) {
+ if (info->fbops->fb_set_par &&
+ !(ops->flags & FBCON_FLAGS_INIT))
+ info->fbops->fb_set_par(info);
+ ops->flags |= FBCON_FLAGS_INIT;
+ }
+ ops->graphics = 0;
if ((cap & FBINFO_HWACCEL_COPYAREA) &&
!(cap & FBINFO_HWACCEL_DISABLED))
@@ -1111,7 +1131,7 @@ static int scrollback_phys_max = 0;
static int scrollback_max = 0;
static int scrollback_current = 0;
-int update_var(int con, struct fb_info *info)
+static int update_var(int con, struct fb_info *info)
{
if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon)
return fb_pan_display(info, &info->var);
@@ -1871,7 +1891,6 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
var.activate = FB_ACTIVATE_NOW |
FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
- info->flags &= ~FBINFO_MISC_MODESWITCH;
}
var_to_display(p, &info->var, info);
}
@@ -1884,7 +1903,7 @@ static int fbcon_switch(struct vc_data *vc)
struct fb_info *info;
struct display *p = &fb_display[vc->vc_num];
struct fb_var_screeninfo var;
- int i, prev_console, do_set_par = 0;
+ int i, prev_console;
info = registered_fb[con2fb_map[vc->vc_num]];
@@ -1943,14 +1962,9 @@ static int fbcon_switch(struct vc_data *vc)
fb_set_var(info, &var);
if (prev_console != -1 &&
- registered_fb[con2fb_map[prev_console]] != info)
- do_set_par = 1;
-
- if (do_set_par || info->flags & FBINFO_MISC_MODESWITCH) {
- if (info->fbops->fb_set_par)
- info->fbops->fb_set_par(info);
- info->flags &= ~FBINFO_MISC_MODESWITCH;
- }
+ registered_fb[con2fb_map[prev_console]] != info &&
+ info->fbops->fb_set_par)
+ info->fbops->fb_set_par(info);
set_blitting_type(vc, info, p);
((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
@@ -2013,29 +2027,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
{
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par;
- int active = !fbcon_is_inactive(vc, info);
if (mode_switch) {
struct fb_var_screeninfo var = info->var;
-/*
- * HACK ALERT: Some hardware will require reinitializion at this stage,
- * others will require it to be done as late as possible.
- * For now, we differentiate this with the
- * FBINFO_MISC_MODESWITCHLATE bitflag. Worst case will be
- * hardware that requires it here and another one later.
- * A definitive solution may require fixing X or the VT
- * system.
- */
- if (info->flags & FBINFO_MISC_MODESWITCHLATE)
- info->flags |= FBINFO_MISC_MODESWITCH;
- if (!blank && !(info->flags & FBINFO_MISC_MODESWITCHLATE)) {
+ ops->graphics = 1;
+
+ if (!blank) {
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
+ ops->graphics = 0;
}
}
- if (active) {
+ if (!fbcon_is_inactive(vc, info)) {
if (ops->blank_state != blank) {
ops->blank_state = blank;
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
@@ -2326,6 +2331,9 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
if (fbcon_is_inactive(vc, info))
return -EINVAL;
+ if (!CON_IS_VISIBLE(vc))
+ return 0;
+
depth = fb_get_color_depth(&info->var);
if (depth > 3) {
for (i = j = 0; i < 16; i++) {
@@ -2733,7 +2741,7 @@ static int fbcon_event_notify(struct notifier_block *self,
* The console `switch' structure for the frame buffer based console
*/
-const struct consw fb_con = {
+static const struct consw fb_con = {
.owner = THIS_MODULE,
.con_startup = fbcon_startup,
.con_init = fbcon_init,
@@ -2763,7 +2771,7 @@ static struct notifier_block fbcon_event_notifier = {
.notifier_call = fbcon_event_notify,
};
-int __init fb_console_init(void)
+static int __init fb_console_init(void)
{
int i;
@@ -2791,7 +2799,7 @@ module_init(fb_console_init);
#ifdef MODULE
-void __exit fb_console_exit(void)
+static void __exit fb_console_exit(void)
{
acquire_console_sem();
fb_unregister_client(&fbcon_event_notifier);
@@ -2803,10 +2811,4 @@ module_exit(fb_console_exit);
#endif
-/*
- * Visible symbols for modules
- */
-
-EXPORT_SYMBOL(fb_con);
-
MODULE_LICENSE("GPL");