summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/core/fbcon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/core/fbcon.c')
-rw-r--r--drivers/video/fbdev/core/fbcon.c76
1 files changed, 33 insertions, 43 deletions
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 1b14c21af2b7..0a2c47df01f4 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -26,7 +26,7 @@
*
* Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
* Smart redraw scrolling, arbitrary font width support, 512char font support
- * and software scrollback added by
+ * and software scrollback added by
* Jakub Jelinek (jj@ultra.linux.cz)
*
* Random hacking by Martin Mares <mj@ucw.cz>
@@ -127,7 +127,7 @@ static int logo_shown = FBCON_LOGO_CANSHOW;
/* console mappings */
static unsigned int first_fb_vc;
static unsigned int last_fb_vc = MAX_NR_CONSOLES - 1;
-static int fbcon_is_default = 1;
+static int fbcon_is_default = 1;
static int primary_device = -1;
static int fbcon_has_console_bind;
@@ -415,12 +415,12 @@ static int __init fb_console_setup(char *this_opt)
strscpy(fontname, options + 5, sizeof(fontname));
continue;
}
-
+
if (!strncmp(options, "scrollback:", 11)) {
pr_warn("Ignoring scrollback size option\n");
continue;
}
-
+
if (!strncmp(options, "map:", 4)) {
options += 4;
if (*options) {
@@ -446,7 +446,7 @@ static int __init fb_console_setup(char *this_opt)
last_fb_vc = simple_strtoul(options, &options, 10) - 1;
if (last_fb_vc < first_fb_vc || last_fb_vc >= MAX_NR_CONSOLES)
last_fb_vc = MAX_NR_CONSOLES - 1;
- fbcon_is_default = 0;
+ fbcon_is_default = 0;
continue;
}
@@ -940,7 +940,7 @@ static const char *fbcon_startup(void)
info = fbcon_registered_fb[info_idx];
if (!info)
return NULL;
-
+
if (fbcon_open(info))
return NULL;
@@ -958,7 +958,7 @@ static const char *fbcon_startup(void)
set_blitting_type(vc, info);
/* Setup default font */
- if (!p->fontdata && !vc->vc_font.data) {
+ if (!p->fontdata) {
if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres,
info->var.yres,
@@ -968,8 +968,6 @@ static const char *fbcon_startup(void)
vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data);
vc->vc_font.charcount = font->charcount;
- } else {
- p->fontdata = vc->vc_font.data;
}
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
@@ -1135,9 +1133,9 @@ static void fbcon_init(struct vc_data *vc, int init)
ops->p = &fb_display[fg_console];
}
-static void fbcon_free_font(struct fbcon_display *p, bool freefont)
+static void fbcon_free_font(struct fbcon_display *p)
{
- if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
+ if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
p->fontdata = NULL;
p->userfont = 0;
@@ -1172,8 +1170,8 @@ static void fbcon_deinit(struct vc_data *vc)
struct fb_info *info;
struct fbcon_ops *ops;
int idx;
- bool free_font = true;
+ fbcon_free_font(p);
idx = con2fb_map[vc->vc_num];
if (idx == -1)
@@ -1184,8 +1182,6 @@ static void fbcon_deinit(struct vc_data *vc)
if (!info)
goto finished;
- if (info->flags & FBINFO_MISC_FIRMWARE)
- free_font = false;
ops = info->fbcon_par;
if (!ops)
@@ -1197,9 +1193,8 @@ static void fbcon_deinit(struct vc_data *vc)
ops->initialized = false;
finished:
- fbcon_free_font(p, free_font);
- if (free_font)
- vc->vc_font.data = NULL;
+ fbcon_free_font(p);
+ vc->vc_font.data = NULL;
if (vc->vc_hi_font_mask && vc->vc_screenbuf)
set_vc_hi_font(vc, false);
@@ -1999,7 +1994,7 @@ static void updatescrollmode(struct fbcon_display *p,
#define PITCH(w) (((w) + 7) >> 3)
#define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */
-static int fbcon_resize(struct vc_data *vc, unsigned int width,
+static int fbcon_resize(struct vc_data *vc, unsigned int width,
unsigned int height, unsigned int user)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
@@ -2174,7 +2169,7 @@ static int fbcon_switch(struct vc_data *vc)
ops->update_start(info);
}
- fbcon_set_palette(vc, color_table);
+ fbcon_set_palette(vc, color_table);
fbcon_clear_margins(vc, 0);
if (logo_shown == FBCON_LOGO_DRAW) {
@@ -2271,7 +2266,7 @@ static int fbcon_debug_leave(struct vc_data *vc)
return 0;
}
-static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
+static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch)
{
u8 *fontdata = vc->vc_font.data;
u8 *data = font->data;
@@ -2279,6 +2274,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
font->width = vc->vc_font.width;
font->height = vc->vc_font.height;
+ if (font->height > vpitch)
+ return -ENOSPC;
font->charcount = vc->vc_hi_font_mask ? 512 : 256;
if (!font->data)
return 0;
@@ -2290,8 +2287,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j);
- memset(data + j, 0, 32 - j);
- data += 32;
+ memset(data + j, 0, vpitch - j);
+ data += vpitch;
fontdata += j;
}
} else if (font->width <= 16) {
@@ -2301,8 +2298,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j);
- memset(data + j, 0, 64 - j);
- data += 64;
+ memset(data + j, 0, 2*vpitch - j);
+ data += 2*vpitch;
fontdata += j;
}
} else if (font->width <= 24) {
@@ -2316,8 +2313,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
*data++ = fontdata[2];
fontdata += sizeof(u32);
}
- memset(data, 0, 3 * (32 - j));
- data += 3 * (32 - j);
+ memset(data, 0, 3 * (vpitch - j));
+ data += 3 * (vpitch - j);
}
} else {
j = vc->vc_font.height * 4;
@@ -2326,8 +2323,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font)
for (i = 0; i < font->charcount; i++) {
memcpy(data, fontdata, j);
- memset(data + j, 0, 128 - j);
- data += 128;
+ memset(data + j, 0, 4 * vpitch - j);
+ data += 4 * vpitch;
fontdata += j;
}
}
@@ -2343,7 +2340,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set)
vc->vc_complement_mask >>= 1;
vc->vc_s_complement_mask >>= 1;
}
-
+
/* ++Edmund: reorder the attribute bits */
if (vc->vc_can_do_color) {
unsigned short *cp =
@@ -2366,7 +2363,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set)
vc->vc_complement_mask <<= 1;
vc->vc_s_complement_mask <<= 1;
}
-
+
/* ++Edmund: reorder the attribute bits */
{
unsigned short *cp =
@@ -2462,19 +2459,12 @@ err_out:
}
/*
- * User asked to set font; we are guaranteed that
- * a) width and height are in range 1..32
- * b) charcount does not exceed 512
- * but lets not assume that, since someone might someday want to use larger
- * fonts. And charcount of 512 is small for unicode support.
- *
- * However, user space gives the font in 32 rows , regardless of
- * actual font height. So a new API is needed if support for larger fonts
- * is ever implemented.
+ * User asked to set font; we are guaranteed that charcount does not exceed 512
+ * but lets not assume that, since charcount of 512 is small for unicode support.
*/
static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
- unsigned int flags)
+ unsigned int vpitch, unsigned int flags)
{
struct fb_info *info = fbcon_info_from_console(vc->vc_num);
unsigned charcount = font->charcount;
@@ -2520,7 +2510,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
FNTSIZE(new_data) = size;
REFCOUNT(new_data) = 0; /* usage counter */
for (i=0; i< charcount; i++) {
- memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch);
+ memcpy(new_data + i*h*pitch, data + i*vpitch*pitch, h*pitch);
}
/* Since linux has a nice crc32 function use it for counting font
@@ -2531,7 +2521,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
/* Check if the same font is on some other console already */
for (i = first_fb_vc; i <= last_fb_vc; i++) {
struct vc_data *tmp = vc_cons[i].d;
-
+
if (fb_display[i].userfont &&
fb_display[i].fontdata &&
FNTSUM(fb_display[i].fontdata) == csum &&
@@ -3439,5 +3429,5 @@ void __exit fb_console_exit(void)
do_unregister_con_driver(&fb_con);
console_unlock();
-}
+}
#endif