diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:46:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 19:46:44 -0500 |
commit | fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (patch) | |
tree | 71bc5e597124dbaf7550f1e089d675718b3ed5c0 /drivers/video/console | |
parent | 69086a78bdc973ec0b722be790b146e84ba8a8c4 (diff) | |
parent | be88298b0a3f771a4802f20c5e66af74bfd1dff1 (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.c | 58 | ||||
-rw-r--r-- | drivers/video/console/vgacon.c | 22 |
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 | ||
532 | static 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 | |||
532 | static int fbcon_takeover(int show_logo) | 559 | static 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 | */ |
819 | static int set_con2fb_map(int unit, int newidx, int user) | 848 | static 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 | ||
1162 | static void fbcon_free_font(struct display *p) | 1191 | static 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; |
1197 | finished: | 1228 | finished: |
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 */ | ||
3003 | static int fbcon_fb_unbind(int idx) | 3037 | static 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 */ | ||
3029 | static int fbcon_fb_unregistered(struct fb_info *info) | 3064 | static 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 */ | ||
3066 | static void fbcon_remap_all(int idx) | 3102 | static 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 */ | ||
3110 | static int fbcon_fb_registered(struct fb_info *info) | 3147 | static 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 | ||