diff options
author | Guennadi Liakhovetski <g.liakhovetski@gmx.de> | 2010-09-03 03:20:39 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-09-14 04:23:39 -0400 |
commit | afe417c0355154c8b2547619771d6053b3c0aad7 (patch) | |
tree | 39c2a88283848450c0a9eee36acd71c09f918ccf /drivers/video/sh_mobile_lcdcfb.c | |
parent | 9289c475823b6eee1f68af2a71243d0cff126948 (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.c | 31 |
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; |