diff options
Diffstat (limited to 'drivers/video/console')
-rw-r--r-- | drivers/video/console/fbcon.c | 54 | ||||
-rw-r--r-- | drivers/video/console/fbcon.h | 2 | ||||
-rw-r--r-- | drivers/video/console/fbcon_ccw.c | 2 | ||||
-rw-r--r-- | drivers/video/console/fbcon_cw.c | 2 | ||||
-rw-r--r-- | drivers/video/console/fbcon_ud.c | 2 | ||||
-rw-r--r-- | drivers/video/console/softcursor.c | 31 |
6 files changed, 67 insertions, 26 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 1b4f75d1f8a9..8c041daa3a15 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -133,6 +133,7 @@ static int info_idx = -1; /* console rotation */ static int rotate; +static int fbcon_has_sysfs; static const struct consw fb_con; @@ -396,9 +397,8 @@ static void fb_flashcursor(void *private) vc = vc_cons[ops->currcon].d; if (!vc || !CON_IS_VISIBLE(vc) || - fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info || - vc_cons[ops->currcon].d->vc_deccm != 1) { + vc->vc_deccm != 1) { release_console_sem(); return; } @@ -2166,7 +2166,12 @@ static int fbcon_switch(struct vc_data *vc) fbcon_del_cursor_timer(old_info); } - fbcon_add_cursor_timer(info); + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) + fbcon_del_cursor_timer(info); + else + fbcon_add_cursor_timer(info); + set_blitting_type(vc, info); ops->cursor_reset = 1; @@ -2276,10 +2281,11 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) update_screen(vc); } - if (!blank) - fbcon_add_cursor_timer(info); - else + if (fbcon_is_inactive(vc, info) || + ops->blank_state != FB_BLANK_UNBLANK) fbcon_del_cursor_timer(info); + else + fbcon_add_cursor_timer(info); return 0; } @@ -3161,11 +3167,26 @@ static struct class_device_attribute class_device_attrs[] = { static int fbcon_init_class_device(void) { - int i; + int i, error = 0; + + fbcon_has_sysfs = 1; + + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) { + error = class_device_create_file(fbcon_class_device, + &class_device_attrs[i]); + + if (error) + break; + } + + if (error) { + while (--i >= 0) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); + + fbcon_has_sysfs = 0; + } - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_create_file(fbcon_class_device, - &class_device_attrs[i]); return 0; } @@ -3225,7 +3246,10 @@ static void fbcon_exit(void) module_put(info->fbops->owner); if (info->fbcon_par) { + struct fbcon_ops *ops = info->fbcon_par; + fbcon_del_cursor_timer(info); + kfree(ops->cursor_src); kfree(info->fbcon_par); info->fbcon_par = NULL; } @@ -3271,9 +3295,13 @@ static void __exit fbcon_deinit_class_device(void) { int i; - for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) - class_device_remove_file(fbcon_class_device, - &class_device_attrs[i]); + if (fbcon_has_sysfs) { + for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) + class_device_remove_file(fbcon_class_device, + &class_device_attrs[i]); + + fbcon_has_sysfs = 0; + } } static void __exit fb_console_exit(void) diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index f244ad066d68..b9386d168c04 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -80,6 +80,8 @@ struct fbcon_ops { char *cursor_data; u8 *fontbuffer; u8 *fontdata; + u8 *cursor_src; + u32 cursor_size; u32 fd_size; }; /* diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 4481c80b8b2a..825e6d6972a7 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -391,7 +391,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int ccw_update_start(struct fb_info *info) +static int ccw_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; u32 yoffset; diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index 7f92c06afea7..c637e6318803 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c @@ -375,7 +375,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int cw_update_start(struct fb_info *info) +static int cw_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; u32 vxres = GETVXRES(ops->p->scrollmode, info); diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index ab91005e64dc..1473506df5d0 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c @@ -415,7 +415,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode, ops->cursor_reset = 0; } -int ud_update_start(struct fb_info *info) +static int ud_update_start(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; int xoffset, yoffset; diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c index 557c563e4aed..7d07d8383569 100644 --- a/drivers/video/console/softcursor.c +++ b/drivers/video/console/softcursor.c @@ -20,11 +20,12 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) { + struct fbcon_ops *ops = info->fbcon_par; unsigned int scan_align = info->pixmap.scan_align - 1; unsigned int buf_align = info->pixmap.buf_align - 1; unsigned int i, size, dsize, s_pitch, d_pitch; struct fb_image *image; - u8 *dst, *src; + u8 *dst; if (info->state != FBINFO_STATE_RUNNING) return 0; @@ -32,11 +33,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) s_pitch = (cursor->image.width + 7) >> 3; dsize = s_pitch * cursor->image.height; - src = kmalloc(dsize + sizeof(struct fb_image), GFP_ATOMIC); - if (!src) - return -ENOMEM; + if (dsize + sizeof(struct fb_image) != ops->cursor_size) { + if (ops->cursor_src != NULL) + kfree(ops->cursor_src); + ops->cursor_size = dsize + sizeof(struct fb_image); - image = (struct fb_image *) (src + dsize); + ops->cursor_src = kmalloc(ops->cursor_size, GFP_ATOMIC); + if (!ops->cursor_src) { + ops->cursor_size = 0; + return -ENOMEM; + } + } + + image = (struct fb_image *) (ops->cursor_src + dsize); *image = cursor->image; d_pitch = (s_pitch + scan_align) & ~scan_align; @@ -48,21 +57,23 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) switch (cursor->rop) { case ROP_XOR: for (i = 0; i < dsize; i++) - src[i] = image->data[i] ^ cursor->mask[i]; + ops->cursor_src[i] = image->data[i] ^ + cursor->mask[i]; break; case ROP_COPY: default: for (i = 0; i < dsize; i++) - src[i] = image->data[i] & cursor->mask[i]; + ops->cursor_src[i] = image->data[i] & + cursor->mask[i]; break; } } else - memcpy(src, image->data, dsize); + memcpy(ops->cursor_src, image->data, dsize); - fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height); + fb_pad_aligned_buffer(dst, d_pitch, ops->cursor_src, s_pitch, + image->height); image->data = dst; info->fbops->fb_imageblit(info, image); - kfree(src); return 0; } |