diff options
Diffstat (limited to 'drivers/video/console/fbcon.c')
-rw-r--r-- | drivers/video/console/fbcon.c | 92 |
1 files changed, 50 insertions, 42 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index bb4ea50b54a3..2e93224d2d55 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -331,6 +331,35 @@ static void cursor_timer_handler(unsigned long dev_addr) | |||
331 | mod_timer(&ops->cursor_timer, jiffies + HZ/5); | 331 | mod_timer(&ops->cursor_timer, jiffies + HZ/5); |
332 | } | 332 | } |
333 | 333 | ||
334 | static void fbcon_add_cursor_timer(struct fb_info *info) | ||
335 | { | ||
336 | struct fbcon_ops *ops = info->fbcon_par; | ||
337 | |||
338 | if ((!info->queue.func || info->queue.func == fb_flashcursor) && | ||
339 | !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { | ||
340 | if (!info->queue.func) | ||
341 | INIT_WORK(&info->queue, fb_flashcursor, info); | ||
342 | |||
343 | init_timer(&ops->cursor_timer); | ||
344 | ops->cursor_timer.function = cursor_timer_handler; | ||
345 | ops->cursor_timer.expires = jiffies + HZ / 5; | ||
346 | ops->cursor_timer.data = (unsigned long ) info; | ||
347 | add_timer(&ops->cursor_timer); | ||
348 | ops->flags |= FBCON_FLAGS_CURSOR_TIMER; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | static void fbcon_del_cursor_timer(struct fb_info *info) | ||
353 | { | ||
354 | struct fbcon_ops *ops = info->fbcon_par; | ||
355 | |||
356 | if (info->queue.func == fb_flashcursor && | ||
357 | ops->flags & FBCON_FLAGS_CURSOR_TIMER) { | ||
358 | del_timer_sync(&ops->cursor_timer); | ||
359 | ops->flags &= ~FBCON_FLAGS_CURSOR_TIMER; | ||
360 | } | ||
361 | } | ||
362 | |||
334 | #ifndef MODULE | 363 | #ifndef MODULE |
335 | static int __init fb_console_setup(char *this_opt) | 364 | static int __init fb_console_setup(char *this_opt) |
336 | { | 365 | { |
@@ -583,9 +612,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, | |||
583 | } | 612 | } |
584 | 613 | ||
585 | if (!err) { | 614 | if (!err) { |
586 | if (oldinfo->queue.func == fb_flashcursor) | 615 | fbcon_del_cursor_timer(oldinfo); |
587 | del_timer_sync(&ops->cursor_timer); | ||
588 | |||
589 | kfree(ops->cursor_state.mask); | 616 | kfree(ops->cursor_state.mask); |
590 | kfree(ops->cursor_data); | 617 | kfree(ops->cursor_data); |
591 | kfree(oldinfo->fbcon_par); | 618 | kfree(oldinfo->fbcon_par); |
@@ -596,22 +623,6 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo, | |||
596 | return err; | 623 | return err; |
597 | } | 624 | } |
598 | 625 | ||
599 | static void con2fb_init_newinfo(struct fb_info *info) | ||
600 | { | ||
601 | if (!info->queue.func || info->queue.func == fb_flashcursor) { | ||
602 | struct fbcon_ops *ops = info->fbcon_par; | ||
603 | |||
604 | if (!info->queue.func) | ||
605 | INIT_WORK(&info->queue, fb_flashcursor, info); | ||
606 | |||
607 | init_timer(&ops->cursor_timer); | ||
608 | ops->cursor_timer.function = cursor_timer_handler; | ||
609 | ops->cursor_timer.expires = jiffies + HZ / 5; | ||
610 | ops->cursor_timer.data = (unsigned long ) info; | ||
611 | add_timer(&ops->cursor_timer); | ||
612 | } | ||
613 | } | ||
614 | |||
615 | static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, | 626 | static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, |
616 | int unit, int show_logo) | 627 | int unit, int show_logo) |
617 | { | 628 | { |
@@ -695,7 +706,7 @@ static int set_con2fb_map(int unit, int newidx, int user) | |||
695 | logo_shown != FBCON_LOGO_DONTSHOW); | 706 | logo_shown != FBCON_LOGO_DONTSHOW); |
696 | 707 | ||
697 | if (!found) | 708 | if (!found) |
698 | con2fb_init_newinfo(info); | 709 | fbcon_add_cursor_timer(info); |
699 | con2fb_map_boot[unit] = newidx; | 710 | con2fb_map_boot[unit] = newidx; |
700 | con2fb_init_display(vc, info, unit, show_logo); | 711 | con2fb_init_display(vc, info, unit, show_logo); |
701 | } | 712 | } |
@@ -898,18 +909,7 @@ static const char *fbcon_startup(void) | |||
898 | } | 909 | } |
899 | #endif /* CONFIG_MAC */ | 910 | #endif /* CONFIG_MAC */ |
900 | 911 | ||
901 | /* Initialize the work queue. If the driver provides its | 912 | fbcon_add_cursor_timer(info); |
902 | * own work queue this means it will use something besides | ||
903 | * default timer to flash the cursor. */ | ||
904 | if (!info->queue.func) { | ||
905 | INIT_WORK(&info->queue, fb_flashcursor, info); | ||
906 | |||
907 | init_timer(&ops->cursor_timer); | ||
908 | ops->cursor_timer.function = cursor_timer_handler; | ||
909 | ops->cursor_timer.expires = jiffies + HZ / 5; | ||
910 | ops->cursor_timer.data = (unsigned long ) info; | ||
911 | add_timer(&ops->cursor_timer); | ||
912 | } | ||
913 | return display_desc; | 913 | return display_desc; |
914 | } | 914 | } |
915 | 915 | ||
@@ -1923,7 +1923,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, | |||
1923 | 1923 | ||
1924 | static int fbcon_switch(struct vc_data *vc) | 1924 | static int fbcon_switch(struct vc_data *vc) |
1925 | { | 1925 | { |
1926 | struct fb_info *info; | 1926 | struct fb_info *info, *old_info = NULL; |
1927 | struct display *p = &fb_display[vc->vc_num]; | 1927 | struct display *p = &fb_display[vc->vc_num]; |
1928 | struct fb_var_screeninfo var; | 1928 | struct fb_var_screeninfo var; |
1929 | int i, prev_console; | 1929 | int i, prev_console; |
@@ -1956,7 +1956,8 @@ static int fbcon_switch(struct vc_data *vc) | |||
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; | 1958 | prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; |
1959 | 1959 | if (prev_console != -1) | |
1960 | old_info = registered_fb[con2fb_map[prev_console]]; | ||
1960 | /* | 1961 | /* |
1961 | * FIXME: If we have multiple fbdev's loaded, we need to | 1962 | * FIXME: If we have multiple fbdev's loaded, we need to |
1962 | * update all info->currcon. Perhaps, we can place this | 1963 | * update all info->currcon. Perhaps, we can place this |
@@ -1984,10 +1985,12 @@ static int fbcon_switch(struct vc_data *vc) | |||
1984 | info->var.yoffset = info->var.xoffset = p->yscroll = 0; | 1985 | info->var.yoffset = info->var.xoffset = p->yscroll = 0; |
1985 | fb_set_var(info, &var); | 1986 | fb_set_var(info, &var); |
1986 | 1987 | ||
1987 | if (prev_console != -1 && | 1988 | if (old_info != NULL && old_info != info) { |
1988 | registered_fb[con2fb_map[prev_console]] != info && | 1989 | if (info->fbops->fb_set_par) |
1989 | info->fbops->fb_set_par) | 1990 | info->fbops->fb_set_par(info); |
1990 | info->fbops->fb_set_par(info); | 1991 | fbcon_del_cursor_timer(old_info); |
1992 | fbcon_add_cursor_timer(info); | ||
1993 | } | ||
1991 | 1994 | ||
1992 | set_blitting_type(vc, info, p); | 1995 | set_blitting_type(vc, info, p); |
1993 | ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; | 1996 | ((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1; |
@@ -2073,11 +2076,16 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) | |||
2073 | fbcon_generic_blank(vc, info, blank); | 2076 | fbcon_generic_blank(vc, info, blank); |
2074 | } | 2077 | } |
2075 | 2078 | ||
2076 | if (!blank) | 2079 | if (!blank) |
2077 | update_screen(vc); | 2080 | update_screen(vc); |
2078 | } | 2081 | } |
2082 | |||
2083 | if (!blank) | ||
2084 | fbcon_add_cursor_timer(info); | ||
2085 | else | ||
2086 | fbcon_del_cursor_timer(info); | ||
2079 | 2087 | ||
2080 | return 0; | 2088 | return 0; |
2081 | } | 2089 | } |
2082 | 2090 | ||
2083 | static void fbcon_free_font(struct display *p) | 2091 | static void fbcon_free_font(struct display *p) |