aboutsummaryrefslogtreecommitdiff
path: root/drivers/video/fbmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r--drivers/video/fbmem.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cd1407921af..354711c84aa 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -773,6 +773,29 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
return 0;
}
+static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
+ u32 activate)
+{
+ struct fb_event event;
+ struct fb_blit_caps caps, fbcaps;
+ int err = 0;
+
+ memset(&caps, 0, sizeof(caps));
+ memset(&fbcaps, 0, sizeof(fbcaps));
+ caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;
+ event.info = info;
+ event.data = ∩︀
+ fb_notifier_call_chain(FB_EVENT_GET_REQ, &event);
+ info->fbops->fb_get_caps(info, &fbcaps, var);
+
+ if (((fbcaps.x ^ caps.x) & caps.x) ||
+ ((fbcaps.y ^ caps.y) & caps.y) ||
+ (fbcaps.len < caps.len))
+ err = -EINVAL;
+
+ return err;
+}
+
int
fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
{
@@ -817,7 +840,15 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
struct fb_videomode mode;
int err = 0;
+ if (info->fbops->fb_get_caps) {
+ err = fb_check_caps(info, var, activate);
+
+ if (err)
+ goto done;
+ }
+
info->var = *var;
+
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
@@ -843,6 +874,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
}
}
}
+
+ done:
return 0;
}