aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbcmap.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-05-01 11:59:22 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:59:22 -0400
commit7149437669f79b497830e643a2b13d26a017b038 (patch)
treef5df8234c2e3cca1a335cf64b9f387c98c123fcf /drivers/video/fbcmap.c
parent5b052d8bb3ad9108489e7475868e14372774ca08 (diff)
[PATCH] fbdev: Batch cmap changes at driver level
This patch adds to the fbdev interface a set_cmap callback that allow the driver to "batch" palette changes. This is useful for drivers like radeonfb which might require lenghtly workarounds on palette accesses, thus allowing to factor out those workarounds efficiently. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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 c51f8fb5c1d..4e5ce8f7d65 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) ||