Commit 8d5b3b97 authored by Antonino Daplas's avatar Antonino Daplas Committed by Linus Torvalds

[PATCH] fbdev: Introduce FB_BLANK_* constants

The VESA_* constants in fb.h used for power management of the display is
confusing to use.  The constants seems to be meant for userspace, because
within the kernel (vt and fbdev), the constants have to be incremented by
1.  Implementation of fb_blank() varies from driver to driver:

- if-else on blank/!blank

- switch case on hardcoded numbers

- switch case on the constants + 1

- switch -1, case  on constants as is

- switch case on the constants as is (broken)

To make usage clearer, new constants are defined in fb.h:

FB_BLANK_UNBLANK  = VESA_UNBLANKING = 0;
FB_BLANK_NORMAL = VESA_UNBLANKING + 1 = 1;
FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1 = 2;
FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1 = 3;
FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1 = 4;

Other changes:

- generic blanking code in fbcon.c (for drivers without an fb_blank hook)
  which either sets the palette to all black, or clear the screen with
  black.

- make fb_display an unexportable symbol
Signed-off-by: default avatarAntonino Daplas <adaplas@pol.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 89ed4952
......@@ -212,7 +212,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
int depth = fb_get_color_depth(info);
int color = 0;
if (!info->fbops->fb_blank && console_blanked) {
if (console_blanked) {
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
c = vc->vc_video_erase_char & charmask;
......@@ -229,7 +229,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0;
int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1;
if (!info->fbops->fb_blank && console_blanked)
if (console_blanked)
fg = bg;
color = (is_fg) ? fg : bg;
......@@ -1993,17 +1993,52 @@ static int fbcon_switch(struct vc_data *vc)
return 1;
}
static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info,
int blank)
{
if (blank) {
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
struct fb_cmap cmap;
u16 *black;
black = kmalloc(sizeof(u16) * info->cmap.len,
GFP_KERNEL);
if (black) {
memset(black, 0, info->cmap.len * sizeof(u16));
cmap.red = cmap.green = cmap.blue = black;
cmap.transp = info->cmap.transp ? black : NULL;
cmap.start = info->cmap.start;
cmap.len = info->cmap.len;
fb_set_cmap(&cmap, info);
}
kfree(black);
} else {
unsigned short charmask = vc->vc_hi_font_mask ?
0x1ff : 0xff;
unsigned short oldc;
oldc = vc->vc_video_erase_char;
vc->vc_video_erase_char &= charmask;
fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols);
vc->vc_video_erase_char = oldc;
}
} else {
if (info->fix.visual == FB_VISUAL_DIRECTCOLOR ||
info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
fb_set_cmap(&info->cmap, info);
}
}
static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
{
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
struct fbcon_ops *ops = info->fbcon_par;
struct display *p = &fb_display[vc->vc_num];
int retval = 0;
int active = !fbcon_is_inactive(vc, info);
if (mode_switch) {
struct fb_var_screeninfo var = info->var;
/*
* HACK ALERT: Some hardware will require reinitializion at this stage,
* others will require it to be done as late as possible.
......@@ -2020,36 +2055,25 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
fb_set_var(info, &var);
}
return 0;
}
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
ops->cursor_flash = (!blank);
if (active) {
int ret = -1;
if (!info->fbops->fb_blank) {
if (blank) {
unsigned short oldc;
u_int height;
u_int y_break;
fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
ops->cursor_flash = (!blank);
oldc = vc->vc_video_erase_char;
vc->vc_video_erase_char &= charmask;
height = vc->vc_rows;
y_break = p->vrows - p->yscroll;
if (height > y_break) {
fbcon_clear(vc, 0, 0, y_break, vc->vc_cols);
fbcon_clear(vc, y_break, 0, height - y_break,
vc->vc_cols);
} else
fbcon_clear(vc, 0, 0, height, vc->vc_cols);
vc->vc_video_erase_char = oldc;
} else if (!fbcon_is_inactive(vc, info))
update_screen(vc->vc_num);
} else if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT)
retval = info->fbops->fb_blank(blank, info);
if (info->fbops->fb_blank)
ret = info->fbops->fb_blank(blank, info);
return retval;
if (ret)
fbcon_generic_blank(vc, info, blank);
if (!blank)
update_screen(vc->vc_num);
}
return 0;
}
static void fbcon_free_font(struct display *p)
......@@ -2786,7 +2810,6 @@ module_exit(fb_console_exit);
* Visible symbols for modules
*/
EXPORT_SYMBOL(fb_display);
EXPORT_SYMBOL(fb_con);
MODULE_LICENSE("GPL");
......@@ -745,9 +745,8 @@ fb_blank(struct fb_info *info, int blank)
{
int err = -EINVAL;
/* Workaround for broken X servers */
if (blank > VESA_POWERDOWN)
blank = VESA_POWERDOWN;
if (blank > FB_BLANK_POWERDOWN)
blank = FB_BLANK_POWERDOWN;
if (info->fbops->fb_blank)
err = info->fbops->fb_blank(blank, info);
......
......@@ -258,6 +258,24 @@ struct fb_con2fbmap {
#define VESA_HSYNC_SUSPEND 2
#define VESA_POWERDOWN 3
enum {
/* screen: unblanked, hsync: on, vsync: on */
FB_BLANK_UNBLANK = VESA_NO_BLANKING,
/* screen: blanked, hsync: on, vsync: on */
FB_BLANK_NORMAL = VESA_NO_BLANKING + 1,
/* screen: blanked, hsync: on, vsync: off */
FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1,
/* screen: blanked, hsync: off, vsync: on */
FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1,
/* screen: blanked, hsync: off, vsync: off */
FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1
};
#define FB_VBLANK_VBLANKING 0x001 /* currently in a vertical blank */
#define FB_VBLANK_HBLANKING 0x002 /* currently in a horizontal blank */
#define FB_VBLANK_HAVE_VBLANK 0x004 /* vertical blanks can be detected */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment