aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:46:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:46:44 -0500
commitfffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (patch)
tree71bc5e597124dbaf7550f1e089d675718b3ed5c0 /drivers/video/console
parent69086a78bdc973ec0b722be790b146e84ba8a8c4 (diff)
parentbe88298b0a3f771a4802f20c5e66af74bfd1dff1 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm merge from Dave Airlie: "Highlights: - TI LCD controller KMS driver - TI OMAP KMS driver merged from staging - drop gma500 stub driver - the fbcon locking fixes - the vgacon dirty like zebra fix. - open firmware videomode and hdmi common code helpers - major locking rework for kms object handling - pageflip/cursor won't block on polling anymore! - fbcon helper and prime helper cleanups - i915: all over the map, haswell power well enhancements, valleyview macro horrors cleaned up, killing lots of legacy GTT code, - radeon: CS ioctl unification, deprecated UMS support, gpu reset rework, VM fixes - nouveau: reworked thermal code, external dp/tmds encoder support (anx9805), fences sleep instead of polling, - exynos: all over the driver fixes." Lovely conflict in radeon/evergreen_cs.c between commit de0babd60d8d ("drm/radeon: enforce use of radeon_get_ib_value when reading user cmd") and the new changes that modified that evergreen_dma_cs_parse() function. * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (508 commits) drm/tilcdc: only build on arm drm/i915: Revert hdmi HDP pin checks drm/tegra: Add list of framebuffers to debugfs drm/tegra: Fix color expansion drm/tegra: Split DC_CMD_STATE_CONTROL register write drm/tegra: Implement page-flipping support drm/tegra: Implement VBLANK support drm/tegra: Implement .mode_set_base() drm/tegra: Add plane support drm/tegra: Remove bogus tegra_framebuffer structure drm: Add consistency check for page-flipping drm/radeon: Use generic HDMI infoframe helpers drm/tegra: Use generic HDMI infoframe helpers drm: Add EDID helper documentation drm: Add HDMI infoframe helpers video: Add generic HDMI infoframe helpers drm: Add some missing forward declarations drm: Move mode tables to drm_edid.c drm: Remove duplicate drm_mode_cea_vic() gma500: Fix n, m1 and m2 clock limits for sdvo and lvds ...
Diffstat (limited to 'drivers/video/console')
-rw-r--r--drivers/video/console/fbcon.c58
-rw-r--r--drivers/video/console/vgacon.c22
2 files changed, 63 insertions, 17 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index f8a61e210d2e..3cd675927826 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -529,6 +529,33 @@ static int search_for_mapped_con(void)
529 return retval; 529 return retval;
530} 530}
531 531
532static int do_fbcon_takeover(int show_logo)
533{
534 int err, i;
535
536 if (!num_registered_fb)
537 return -ENODEV;
538
539 if (!show_logo)
540 logo_shown = FBCON_LOGO_DONTSHOW;
541
542 for (i = first_fb_vc; i <= last_fb_vc; i++)
543 con2fb_map[i] = info_idx;
544
545 err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc,
546 fbcon_is_default);
547
548 if (err) {
549 for (i = first_fb_vc; i <= last_fb_vc; i++)
550 con2fb_map[i] = -1;
551 info_idx = -1;
552 } else {
553 fbcon_has_console_bind = 1;
554 }
555
556 return err;
557}
558
532static int fbcon_takeover(int show_logo) 559static int fbcon_takeover(int show_logo)
533{ 560{
534 int err, i; 561 int err, i;
@@ -815,6 +842,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
815 * 842 *
816 * Maps a virtual console @unit to a frame buffer device 843 * Maps a virtual console @unit to a frame buffer device
817 * @newidx. 844 * @newidx.
845 *
846 * This should be called with the console lock held.
818 */ 847 */
819static int set_con2fb_map(int unit, int newidx, int user) 848static int set_con2fb_map(int unit, int newidx, int user)
820{ 849{
@@ -832,7 +861,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
832 861
833 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { 862 if (!search_for_mapped_con() || !con_is_bound(&fb_con)) {
834 info_idx = newidx; 863 info_idx = newidx;
835 return fbcon_takeover(0); 864 return do_fbcon_takeover(0);
836 } 865 }
837 866
838 if (oldidx != -1) 867 if (oldidx != -1)
@@ -840,7 +869,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
840 869
841 found = search_fb_in_map(newidx); 870 found = search_fb_in_map(newidx);
842 871
843 console_lock();
844 con2fb_map[unit] = newidx; 872 con2fb_map[unit] = newidx;
845 if (!err && !found) 873 if (!err && !found)
846 err = con2fb_acquire_newinfo(vc, info, unit, oldidx); 874 err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -867,7 +895,6 @@ static int set_con2fb_map(int unit, int newidx, int user)
867 if (!search_fb_in_map(info_idx)) 895 if (!search_fb_in_map(info_idx))
868 info_idx = newidx; 896 info_idx = newidx;
869 897
870 console_unlock();
871 return err; 898 return err;
872} 899}
873 900
@@ -990,7 +1017,7 @@ static const char *fbcon_startup(void)
990 } 1017 }
991 1018
992 /* Setup default font */ 1019 /* Setup default font */
993 if (!p->fontdata) { 1020 if (!p->fontdata && !vc->vc_font.data) {
994 if (!fontname[0] || !(font = find_font(fontname))) 1021 if (!fontname[0] || !(font = find_font(fontname)))
995 font = get_default_font(info->var.xres, 1022 font = get_default_font(info->var.xres,
996 info->var.yres, 1023 info->var.yres,
@@ -1000,6 +1027,8 @@ static const char *fbcon_startup(void)
1000 vc->vc_font.height = font->height; 1027 vc->vc_font.height = font->height;
1001 vc->vc_font.data = (void *)(p->fontdata = font->data); 1028 vc->vc_font.data = (void *)(p->fontdata = font->data);
1002 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ 1029 vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
1030 } else {
1031 p->fontdata = vc->vc_font.data;
1003 } 1032 }
1004 1033
1005 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); 1034 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
@@ -1159,9 +1188,9 @@ static void fbcon_init(struct vc_data *vc, int init)
1159 ops->p = &fb_display[fg_console]; 1188 ops->p = &fb_display[fg_console];
1160} 1189}
1161 1190
1162static void fbcon_free_font(struct display *p) 1191static void fbcon_free_font(struct display *p, bool freefont)
1163{ 1192{
1164 if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) 1193 if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
1165 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); 1194 kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
1166 p->fontdata = NULL; 1195 p->fontdata = NULL;
1167 p->userfont = 0; 1196 p->userfont = 0;
@@ -1173,8 +1202,8 @@ static void fbcon_deinit(struct vc_data *vc)
1173 struct fb_info *info; 1202 struct fb_info *info;
1174 struct fbcon_ops *ops; 1203 struct fbcon_ops *ops;
1175 int idx; 1204 int idx;
1205 bool free_font = true;
1176 1206
1177 fbcon_free_font(p);
1178 idx = con2fb_map[vc->vc_num]; 1207 idx = con2fb_map[vc->vc_num];
1179 1208
1180 if (idx == -1) 1209 if (idx == -1)
@@ -1185,6 +1214,8 @@ static void fbcon_deinit(struct vc_data *vc)
1185 if (!info) 1214 if (!info)
1186 goto finished; 1215 goto finished;
1187 1216
1217 if (info->flags & FBINFO_MISC_FIRMWARE)
1218 free_font = false;
1188 ops = info->fbcon_par; 1219 ops = info->fbcon_par;
1189 1220
1190 if (!ops) 1221 if (!ops)
@@ -1196,6 +1227,8 @@ static void fbcon_deinit(struct vc_data *vc)
1196 ops->flags &= ~FBCON_FLAGS_INIT; 1227 ops->flags &= ~FBCON_FLAGS_INIT;
1197finished: 1228finished:
1198 1229
1230 fbcon_free_font(p, free_font);
1231
1199 if (!con_is_bound(&fb_con)) 1232 if (!con_is_bound(&fb_con))
1200 fbcon_exit(); 1233 fbcon_exit();
1201 1234
@@ -2985,7 +3018,7 @@ static int fbcon_unbind(void)
2985{ 3018{
2986 int ret; 3019 int ret;
2987 3020
2988 ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, 3021 ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
2989 fbcon_is_default); 3022 fbcon_is_default);
2990 3023
2991 if (!ret) 3024 if (!ret)
@@ -3000,6 +3033,7 @@ static inline int fbcon_unbind(void)
3000} 3033}
3001#endif /* CONFIG_VT_HW_CONSOLE_BINDING */ 3034#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
3002 3035
3036/* called with console_lock held */
3003static int fbcon_fb_unbind(int idx) 3037static int fbcon_fb_unbind(int idx)
3004{ 3038{
3005 int i, new_idx = -1, ret = 0; 3039 int i, new_idx = -1, ret = 0;
@@ -3026,6 +3060,7 @@ static int fbcon_fb_unbind(int idx)
3026 return ret; 3060 return ret;
3027} 3061}
3028 3062
3063/* called with console_lock held */
3029static int fbcon_fb_unregistered(struct fb_info *info) 3064static int fbcon_fb_unregistered(struct fb_info *info)
3030{ 3065{
3031 int i, idx; 3066 int i, idx;
@@ -3058,11 +3093,12 @@ static int fbcon_fb_unregistered(struct fb_info *info)
3058 primary_device = -1; 3093 primary_device = -1;
3059 3094
3060 if (!num_registered_fb) 3095 if (!num_registered_fb)
3061 unregister_con_driver(&fb_con); 3096 do_unregister_con_driver(&fb_con);
3062 3097
3063 return 0; 3098 return 0;
3064} 3099}
3065 3100
3101/* called with console_lock held */
3066static void fbcon_remap_all(int idx) 3102static void fbcon_remap_all(int idx)
3067{ 3103{
3068 int i; 3104 int i;
@@ -3107,6 +3143,7 @@ static inline void fbcon_select_primary(struct fb_info *info)
3107} 3143}
3108#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ 3144#endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */
3109 3145
3146/* called with console_lock held */
3110static int fbcon_fb_registered(struct fb_info *info) 3147static int fbcon_fb_registered(struct fb_info *info)
3111{ 3148{
3112 int ret = 0, i, idx; 3149 int ret = 0, i, idx;
@@ -3123,7 +3160,7 @@ static int fbcon_fb_registered(struct fb_info *info)
3123 } 3160 }
3124 3161
3125 if (info_idx != -1) 3162 if (info_idx != -1)
3126 ret = fbcon_takeover(1); 3163 ret = do_fbcon_takeover(1);
3127 } else { 3164 } else {
3128 for (i = first_fb_vc; i <= last_fb_vc; i++) { 3165 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3129 if (con2fb_map_boot[i] == idx) 3166 if (con2fb_map_boot[i] == idx)
@@ -3259,6 +3296,7 @@ static int fbcon_event_notify(struct notifier_block *self,
3259 ret = fbcon_fb_unregistered(info); 3296 ret = fbcon_fb_unregistered(info);
3260 break; 3297 break;
3261 case FB_EVENT_SET_CONSOLE_MAP: 3298 case FB_EVENT_SET_CONSOLE_MAP:
3299 /* called with console lock held */
3262 con2fb = event->data; 3300 con2fb = event->data;
3263 ret = set_con2fb_map(con2fb->console - 1, 3301 ret = set_con2fb_map(con2fb->console - 1,
3264 con2fb->framebuffer, 1); 3302 con2fb->framebuffer, 1);
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d449a74d4a31..5855d17d19ac 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1064 unsigned short video_port_status = vga_video_port_reg + 6; 1064 unsigned short video_port_status = vga_video_port_reg + 6;
1065 int font_select = 0x00, beg, i; 1065 int font_select = 0x00, beg, i;
1066 char *charmap; 1066 char *charmap;
1067 1067 bool clear_attribs = false;
1068 if (vga_video_type != VIDEO_TYPE_EGAM) { 1068 if (vga_video_type != VIDEO_TYPE_EGAM) {
1069 charmap = (char *) VGA_MAP_MEM(colourmap, 0); 1069 charmap = (char *) VGA_MAP_MEM(colourmap, 0);
1070 beg = 0x0e; 1070 beg = 0x0e;
@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1169 1169
1170 /* if 512 char mode is already enabled don't re-enable it. */ 1170 /* if 512 char mode is already enabled don't re-enable it. */
1171 if ((set) && (ch512 != vga_512_chars)) { 1171 if ((set) && (ch512 != vga_512_chars)) {
1172 /* attribute controller */
1173 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1174 struct vc_data *c = vc_cons[i].d;
1175 if (c && c->vc_sw == &vga_con)
1176 c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
1177 }
1178 vga_512_chars = ch512; 1172 vga_512_chars = ch512;
1179 /* 256-char: enable intensity bit 1173 /* 256-char: enable intensity bit
1180 512-char: disable intensity bit */ 1174 512-char: disable intensity bit */
@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
1185 it means, but it works, and it appears necessary */ 1179 it means, but it works, and it appears necessary */
1186 inb_p(video_port_status); 1180 inb_p(video_port_status);
1187 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); 1181 vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
1182 clear_attribs = true;
1188 } 1183 }
1189 raw_spin_unlock_irq(&vga_lock); 1184 raw_spin_unlock_irq(&vga_lock);
1185
1186 if (clear_attribs) {
1187 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1188 struct vc_data *c = vc_cons[i].d;
1189 if (c && c->vc_sw == &vga_con) {
1190 /* force hi font mask to 0, so we always clear
1191 the bit on either transition */
1192 c->vc_hi_font_mask = 0x00;
1193 clear_buffer_attributes(c);
1194 c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
1195 }
1196 }
1197 }
1190 return 0; 1198 return 0;
1191} 1199}
1192 1200