aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/sh_mobile_lcdcfb.c
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-09-03 03:20:39 -0400
committerPaul Mundt <lethal@linux-sh.org>2010-09-14 04:23:39 -0400
commitafe417c0355154c8b2547619771d6053b3c0aad7 (patch)
tree39c2a88283848450c0a9eee36acd71c09f918ccf /drivers/video/sh_mobile_lcdcfb.c
parent9289c475823b6eee1f68af2a71243d0cff126948 (diff)
fbdev: sh_mobile_hdmi: support hot-plugging of different HDMI / DVI displays
With this patch hot-plugging of an HDMI or a DVI monitor can select a different video mode and reconfigure the LCDC and HDMI controllers accordingly. Due to a lack of a standard API to inform framebuffer users of a changed video mode, the framebuffer configuration is preserved regardless of a specific mode, selected for the monitor. As described in a previous patch, this leads to smaller framebuffers being displayed on larger monitors or a part of a larger framebuffer being displayed on a smaller resolution monitor. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/video/sh_mobile_lcdcfb.c')
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c31
1 files changed, 6 insertions, 25 deletions
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 946a810801af..b4a878624510 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -944,6 +944,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
944 struct sh_mobile_lcdc_chan *ch = info->par; 944 struct sh_mobile_lcdc_chan *ch = info->par;
945 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg; 945 struct sh_mobile_lcdc_board_cfg *board_cfg = &ch->cfg.board_cfg;
946 struct fb_var_screeninfo *var; 946 struct fb_var_screeninfo *var;
947 int ret;
947 948
948 if (&ch->lcdc->notifier != nb) 949 if (&ch->lcdc->notifier != nb)
949 return NOTIFY_DONE; 950 return NOTIFY_DONE;
@@ -958,6 +959,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
958 module_put(board_cfg->owner); 959 module_put(board_cfg->owner);
959 } 960 }
960 pm_runtime_put(info->device); 961 pm_runtime_put(info->device);
962 sh_mobile_lcdc_stop(ch->lcdc);
961 break; 963 break;
962 case FB_EVENT_RESUME: 964 case FB_EVENT_RESUME:
963 var = &info->var; 965 var = &info->var;
@@ -968,31 +970,9 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
968 module_put(board_cfg->owner); 970 module_put(board_cfg->owner);
969 } 971 }
970 972
971 /* Check if the new display is not in our modelist */ 973 ret = sh_mobile_lcdc_start(ch->lcdc);
972 if (ch->info->modelist.next && 974 if (!ret)
973 !fb_match_mode(var, &ch->info->modelist)) { 975 pm_runtime_get_sync(info->device);
974 struct fb_videomode mode;
975 int ret;
976
977 /* Can we handle this display? */
978 if (var->xres > ch->cfg.lcd_cfg[0].xres ||
979 var->yres > ch->cfg.lcd_cfg[0].yres)
980 /*
981 * LCDC resume failed, no need to continue with
982 * the notifier chain
983 */
984 return notifier_from_errno(-ENOMEM);
985
986 /* Add to the modelist */
987 fb_var_to_videomode(&mode, var);
988 ret = fb_add_videomode(&mode, &ch->info->modelist);
989 if (ret < 0)
990 return notifier_from_errno(ret);
991 }
992
993 pm_runtime_get_sync(info->device);
994
995 sh_mobile_lcdc_geometry(ch);
996 } 976 }
997 977
998 return NOTIFY_OK; 978 return NOTIFY_OK;
@@ -1181,6 +1161,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
1181 } 1161 }
1182 } 1162 }
1183 1163
1164 fb_videomode_to_modelist(ch->cfg.lcd_cfg, ch->cfg.num_cfg, &info->modelist);
1184 error = register_framebuffer(info); 1165 error = register_framebuffer(info);
1185 if (error < 0) 1166 if (error < 0)
1186 goto err1; 1167 goto err1;