diff options
Diffstat (limited to 'drivers/video/fbcmap.c')
-rw-r--r-- | drivers/video/fbcmap.c | 32 |
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) || |