aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/console
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/console')
-rw-r--r--drivers/video/console/fbcon.c54
-rw-r--r--drivers/video/console/fbcon.h2
-rw-r--r--drivers/video/console/fbcon_ccw.c2
-rw-r--r--drivers/video/console/fbcon_cw.c2
-rw-r--r--drivers/video/console/fbcon_ud.c2
-rw-r--r--drivers/video/console/softcursor.c31
6 files changed, 67 insertions, 26 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1b4f75d1f8a94..8c041daa3a15b 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 f244ad066d688..b9386d168c049 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 4481c80b8b2a1..825e6d6972a72 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 7f92c06afea7a..c637e63188037 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 ab91005e64dc6..1473506df5d06 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 557c563e4aed2..7d07d83835690 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;
}