aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbcmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbcmap.c')
-rw-r--r--drivers/video/fbcmap.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index c51f8fb5c1de..4e5ce8f7d65e 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -222,8 +222,11 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
222 transp = cmap->transp; 222 transp = cmap->transp;
223 start = cmap->start; 223 start = cmap->start;
224 224
225 if (start < 0 || !info->fbops->fb_setcolreg) 225 if (start < 0 || (!info->fbops->fb_setcolreg &&
226 !info->fbops->fb_setcmap))
226 return -EINVAL; 227 return -EINVAL;
228 if (info->fbops->fb_setcmap)
229 return info->fbops->fb_setcmap(cmap, info);
227 for (i = 0; i < cmap->len; i++) { 230 for (i = 0; i < cmap->len; i++) {
228 hred = *red++; 231 hred = *red++;
229 hgreen = *green++; 232 hgreen = *green++;
@@ -250,8 +253,33 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
250 transp = cmap->transp; 253 transp = cmap->transp;
251 start = cmap->start; 254 start = cmap->start;
252 255
253 if (start < 0 || !info->fbops->fb_setcolreg) 256 if (start < 0 || (!info->fbops->fb_setcolreg &&
257 !info->fbops->fb_setcmap))
254 return -EINVAL; 258 return -EINVAL;
259
260 /* If we can batch, do it */
261 if (info->fbops->fb_setcmap && cmap->len > 1) {
262 struct fb_cmap umap;
263 int size = cmap->len * sizeof(u16);
264 int rc;
265
266 memset(&umap, 0, sizeof(struct fb_cmap));
267 rc = fb_alloc_cmap(&umap, cmap->len, transp != NULL);
268 if (rc)
269 return rc;
270 if (copy_from_user(umap.red, red, size) ||
271 copy_from_user(umap.green, green, size) ||
272 copy_from_user(umap.blue, blue, size) ||
273 (transp && copy_from_user(umap.transp, transp, size))) {
274 rc = -EFAULT;
275 }
276 umap.start = start;
277 if (rc == 0)
278 rc = info->fbops->fb_setcmap(&umap, info);
279 fb_dealloc_cmap(&umap);
280 return rc;
281 }
282
255 for (i = 0; i < cmap->len; i++, red++, blue++, green++) { 283 for (i = 0; i < cmap->len; i++, red++, blue++, green++) {
256 if (get_user(hred, red) || 284 if (get_user(hred, red) ||
257 get_user(hgreen, green) || 285 get_user(hgreen, green) ||