aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_lcdcfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/sh_mobile_lcdcfb.c')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 757665bc500f..9bcc61b4ef14 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -643,7 +643,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
643 continue; 643 continue;
644 644
645 board_cfg = &ch->cfg.board_cfg; 645 board_cfg = &ch->cfg.board_cfg;
646 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 646 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
647 board_cfg->display_on(board_cfg->board_data, ch->info); 647 board_cfg->display_on(board_cfg->board_data, ch->info);
648 module_put(board_cfg->owner); 648 module_put(board_cfg->owner);
649 } 649 }
@@ -688,7 +688,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
688 } 688 }
689 689
690 board_cfg = &ch->cfg.board_cfg; 690 board_cfg = &ch->cfg.board_cfg;
691 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 691 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
692 board_cfg->display_off(board_cfg->board_data); 692 board_cfg->display_off(board_cfg->board_data);
693 module_put(board_cfg->owner); 693 module_put(board_cfg->owner);
694 } 694 }
@@ -1032,6 +1032,49 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
1032 return 0; 1032 return 0;
1033} 1033}
1034 1034
1035/*
1036 * Screen blanking. Behavior is as follows:
1037 * FB_BLANK_UNBLANK: screen unblanked, clocks enabled
1038 * FB_BLANK_NORMAL: screen blanked, clocks enabled
1039 * FB_BLANK_VSYNC,
1040 * FB_BLANK_HSYNC,
1041 * FB_BLANK_POWEROFF: screen blanked, clocks disabled
1042 */
1043static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
1044{
1045 struct sh_mobile_lcdc_chan *ch = info->par;
1046 struct sh_mobile_lcdc_priv *p = ch->lcdc;
1047
1048 /* blank the screen? */
1049 if (blank > FB_BLANK_UNBLANK && ch->blank_status == FB_BLANK_UNBLANK) {
1050 struct fb_fillrect rect = {
1051 .width = info->var.xres,
1052 .height = info->var.yres,
1053 };
1054 sh_mobile_lcdc_fillrect(info, &rect);
1055 }
1056 /* turn clocks on? */
1057 if (blank <= FB_BLANK_NORMAL && ch->blank_status > FB_BLANK_NORMAL) {
1058 sh_mobile_lcdc_clk_on(p);
1059 }
1060 /* turn clocks off? */
1061 if (blank > FB_BLANK_NORMAL && ch->blank_status <= FB_BLANK_NORMAL) {
1062 /* make sure the screen is updated with the black fill before
1063 * switching the clocks off. one vsync is not enough since
1064 * blanking may occur in the middle of a refresh. deferred io
1065 * mode will reenable the clocks and update the screen in time,
1066 * so it does not need this. */
1067 if (!info->fbdefio) {
1068 sh_mobile_wait_for_vsync(info);
1069 sh_mobile_wait_for_vsync(info);
1070 }
1071 sh_mobile_lcdc_clk_off(p);
1072 }
1073
1074 ch->blank_status = blank;
1075 return 0;
1076}
1077
1035static struct fb_ops sh_mobile_lcdc_ops = { 1078static struct fb_ops sh_mobile_lcdc_ops = {
1036 .owner = THIS_MODULE, 1079 .owner = THIS_MODULE,
1037 .fb_setcolreg = sh_mobile_lcdc_setcolreg, 1080 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -1040,6 +1083,7 @@ static struct fb_ops sh_mobile_lcdc_ops = {
1040 .fb_fillrect = sh_mobile_lcdc_fillrect, 1083 .fb_fillrect = sh_mobile_lcdc_fillrect,
1041 .fb_copyarea = sh_mobile_lcdc_copyarea, 1084 .fb_copyarea = sh_mobile_lcdc_copyarea,
1042 .fb_imageblit = sh_mobile_lcdc_imageblit, 1085 .fb_imageblit = sh_mobile_lcdc_imageblit,
1086 .fb_blank = sh_mobile_lcdc_blank,
1043 .fb_pan_display = sh_mobile_fb_pan_display, 1087 .fb_pan_display = sh_mobile_fb_pan_display,
1044 .fb_ioctl = sh_mobile_ioctl, 1088 .fb_ioctl = sh_mobile_ioctl,
1045 .fb_open = sh_mobile_open, 1089 .fb_open = sh_mobile_open,
@@ -1254,7 +1298,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1254 1298
1255 switch(action) { 1299 switch(action) {
1256 case FB_EVENT_SUSPEND: 1300 case FB_EVENT_SUSPEND:
1257 if (try_module_get(board_cfg->owner) && board_cfg->display_off) { 1301 if (board_cfg->display_off && try_module_get(board_cfg->owner)) {
1258 board_cfg->display_off(board_cfg->board_data); 1302 board_cfg->display_off(board_cfg->board_data);
1259 module_put(board_cfg->owner); 1303 module_put(board_cfg->owner);
1260 } 1304 }
@@ -1267,7 +1311,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
1267 mutex_unlock(&ch->open_lock); 1311 mutex_unlock(&ch->open_lock);
1268 1312
1269 /* HDMI must be enabled before LCDC configuration */ 1313 /* HDMI must be enabled before LCDC configuration */
1270 if (try_module_get(board_cfg->owner) && board_cfg->display_on) { 1314 if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
1271 board_cfg->display_on(board_cfg->board_data, info); 1315 board_cfg->display_on(board_cfg->board_data, info);
1272 module_put(board_cfg->owner); 1316 module_put(board_cfg->owner);
1273 } 1317 }