This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / video / fbmem.c
index 2a55e5d..65a4021 100644 (file)
@@ -73,8 +73,8 @@ extern int cyber2000fb_init(void);
 extern int cyber2000fb_setup(char*);
 extern int retz3fb_init(void);
 extern int retz3fb_setup(char*);
-extern int cirrusfb_init(void);
-extern int cirrusfb_setup(char*);
+extern int clgenfb_init(void);
+extern int clgenfb_setup(char*);
 extern int hitfb_init(void);
 extern int vfb_init(void);
 extern int vfb_setup(char*);
@@ -204,8 +204,8 @@ static struct {
 #ifdef CONFIG_FB_PM3
        { "pm3fb", pm3fb_init, pm3fb_setup },
 #endif           
-#ifdef CONFIG_FB_CIRRUS
-       { "cirrusfb", cirrusfb_init, cirrusfb_setup },
+#ifdef CONFIG_FB_CLGEN
+       { "clgenfb", clgenfb_init, clgenfb_setup },
 #endif
 #ifdef CONFIG_FB_ATY
        { "atyfb", atyfb_init, atyfb_setup },
@@ -430,37 +430,34 @@ static int ofonly __initdata = 0;
 /*
  * Drawing helpers.
  */
-void fb_iomove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-                          u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-                          u32 height)
+static u8 fb_sys_inbuf(struct fb_info *info, u8 *src)
 {
-       int i;
-
-       for (i = height; i--; ) {
-               buf->outbuf(info, dst, src, s_pitch);
-               src += s_pitch;
-               dst += d_pitch;
-       }
+       return *src;
 }
 
-void fb_sysmove_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
-                           u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
-                           u32 height)
+static void fb_sys_outbuf(struct fb_info *info, u8 *dst,
+                               u8 *src, unsigned int size)
 {
-       int i, j;
+       memcpy(dst, src, size);
+}      
+
+void fb_move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+                       u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+                       u32 height)
+{
+       int i;
 
        for (i = height; i--; ) {
-               for (j = 0; j < s_pitch; j++)
-                       dst[j] = src[j];
+               buf->outbuf(info, dst, src, s_pitch);
                src += s_pitch;
                dst += d_pitch;
        }
 }
 
-void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-                            u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-                            u32 height, u32 shift_high, u32 shift_low,
-                            u32 mod)
+void fb_move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
+                       u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+                       u32 height, u32 shift_high, u32 shift_low,
+                       u32 mod)
 {
        u8 mask = (u8) (0xfff << shift_high), tmp;
        int i, j;
@@ -488,37 +485,6 @@ void fb_iomove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
        }
 }
 
-void fb_sysmove_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
-                             u8 *dst, u32 d_pitch, u8 *src, u32 idx,
-                             u32 height, u32 shift_high, u32 shift_low,
-                             u32 mod)
-{
-       u8 mask = (u8) (0xfff << shift_high), tmp;
-       int i, j;
-
-       for (i = height; i--; ) {
-               for (j = 0; j < idx; j++) {
-                       tmp = dst[j];
-                       tmp &= mask;
-                       tmp |= *src >> shift_low;
-                       dst[j] = tmp;
-                       tmp = *src << shift_high;
-                       dst[j+1] = tmp;
-                       src++;
-               }
-               tmp = dst[idx];
-               tmp &= mask;
-               tmp |= *src >> shift_low;
-               dst[idx] = tmp;
-               if (shift_high < mod) {
-                       tmp = *src << shift_high;
-                       dst[idx+1] = tmp;
-               }
-               src++;
-               dst += d_pitch;
-       }
-}
-
 /*
  * we need to lock this section since fb_cursor
  * may use fb_imageblit()
@@ -563,7 +529,7 @@ static inline unsigned safe_shift(unsigned d, int n)
        return n < 0 ? d >> -n : d << n;
 }
 
-static void fb_set_logocmap(struct fb_info *info,
+static void __init fb_set_logocmap(struct fb_info *info,
                                   const struct linux_logo *logo)
 {
        struct fb_cmap palette_cmap;
@@ -593,11 +559,11 @@ static void fb_set_logocmap(struct fb_info *info,
                        palette_cmap.blue[j] = clut[2] << 8 | clut[2];
                        clut += 3;
                }
-               fb_set_cmap(&palette_cmap, info);
+               fb_set_cmap(&palette_cmap, 1, info);
        }
 }
 
-static void  fb_set_logo_truepalette(struct fb_info *info,
+static void  __init fb_set_logo_truepalette(struct fb_info *info,
                                            const struct linux_logo *logo,
                                            u32 *palette)
 {
@@ -627,7 +593,7 @@ static void  fb_set_logo_truepalette(struct fb_info *info,
        }
 }
 
-static void fb_set_logo_directpalette(struct fb_info *info,
+static void __init fb_set_logo_directpalette(struct fb_info *info,
                                             const struct linux_logo *logo,
                                             u32 *palette)
 {
@@ -642,7 +608,7 @@ static void fb_set_logo_directpalette(struct fb_info *info,
                palette[i] = i << redshift | i << greenshift | i << blueshift;
 }
 
-static void fb_set_logo(struct fb_info *info,
+static void __init fb_set_logo(struct fb_info *info,
                               const struct linux_logo *logo, u8 *dst,
                               int depth)
 {
@@ -931,100 +897,57 @@ fb_load_cursor_image(struct fb_info *info)
        unsigned int width = (info->cursor.image.width + 7) >> 3;
        u8 *data = (u8 *) info->cursor.image.data;
 
-       if (info->sprite.outbuf)
-           info->sprite.outbuf(info, info->sprite.addr, data, width);
-       else
-           memcpy(info->sprite.addr, data, width);
+       info->sprite.outbuf(info, info->sprite.addr, data, width);
 }
 
 int
-fb_cursor(struct fb_info *info, struct fb_cursor_user __user *sprite)
+fb_cursor(struct fb_info *info, struct fb_cursor *sprite)
 {
-       struct fb_cursor_user cursor_user;
        struct fb_cursor cursor;
-       char *data = NULL, *mask = NULL;
-       u16 *red = NULL, *green = NULL, *blue = NULL, *transp = NULL;
-       int err = -EINVAL;
+       int err;
        
-       if (copy_from_user(&cursor_user, sprite, sizeof(struct fb_cursor_user)))
+       if (copy_from_user(&cursor, sprite, sizeof(struct fb_cursor)))
                return -EFAULT;
 
-       memcpy(&cursor, &cursor_user, sizeof(cursor));
-       cursor.mask = NULL;
-       cursor.image.data = NULL;
-       cursor.image.cmap.red = NULL;
-       cursor.image.cmap.green = NULL;
-       cursor.image.cmap.blue = NULL;
-       cursor.image.cmap.transp = NULL;
-
        if (cursor.set & FB_CUR_SETCUR)
                info->cursor.enable = 1;
        
        if (cursor.set & FB_CUR_SETCMAP) {
-               unsigned len = cursor.image.cmap.len;
-               if ((int)len <= 0)
-                       goto out;
-               len *= 2;
-               err = -ENOMEM;
-               red = kmalloc(len, GFP_USER);
-               green = kmalloc(len, GFP_USER);
-               blue = kmalloc(len, GFP_USER);
-               if (!red || !green || !blue)
-                       goto out;
-               if (cursor_user.image.cmap.transp) {
-                       transp = kmalloc(len, GFP_USER);
-                       if (!transp)
-                               goto out;
-               }
-               err = -EFAULT;
-               if (copy_from_user(red, cursor_user.image.cmap.red, len))
-                       goto out;
-               if (copy_from_user(green, cursor_user.image.cmap.green, len))
-                       goto out;
-               if (copy_from_user(blue, cursor_user.image.cmap.blue, len))
-                       goto out;
-               if (transp) {
-                       if (copy_from_user(transp,
-                                          cursor_user.image.cmap.transp, len))
-                               goto out;
-               }
-               cursor.image.cmap.red = red;
-               cursor.image.cmap.green = green;
-               cursor.image.cmap.blue = blue;
-               cursor.image.cmap.transp = transp;
+               err = fb_copy_cmap(&cursor.image.cmap, &sprite->image.cmap, 1);
+               if (err)
+                       return err;
        }
        
        if (cursor.set & FB_CUR_SETSHAPE) {
                int size = ((cursor.image.width + 7) >> 3) * cursor.image.height;               
+               char *data, *mask;
 
                if ((cursor.image.height != info->cursor.image.height) ||
                    (cursor.image.width != info->cursor.image.width))
                        cursor.set |= FB_CUR_SETSIZE;
                
-               err = -ENOMEM;
-               data = kmalloc(size, GFP_USER);
-               mask = kmalloc(size, GFP_USER);
-               if (!mask || !data)
-                       goto out;
+               data = kmalloc(size, GFP_KERNEL);
+               if (!data)
+                       return -ENOMEM;
                
-               err = -EFAULT;
-               if (copy_from_user(data, cursor_user.image.data, size) ||
-                   copy_from_user(mask, cursor_user.mask, size))
-                       goto out;
+               mask = kmalloc(size, GFP_KERNEL);
+               if (!mask) {
+                       kfree(data);
+                       return -ENOMEM;
+               }
                
+               if (copy_from_user(data, sprite->image.data, size) ||
+                   copy_from_user(mask, sprite->mask, size)) {
+                       kfree(data);
+                       kfree(mask);
+                       return -EFAULT;
+               }
                cursor.image.data = data;
                cursor.mask = mask;
        }
        info->cursor.set = cursor.set;
        info->cursor.rop = cursor.rop;
        err = info->fbops->fb_cursor(info, &cursor);
-out:
-       kfree(data);
-       kfree(mask);
-       kfree(red);
-       kfree(green);
-       kfree(blue);
-       kfree(transp);
        return err;
 }
 
@@ -1073,13 +996,9 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 
                        fb_pan_display(info, &info->var);
 
-                       fb_set_cmap(&info->cmap, info);
+                       fb_set_cmap(&info->cmap, 1, info);
 
-                       if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
-                               info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
-                               notifier_call_chain(&fb_notifier_list,
-                                                   FB_EVENT_MODE_CHANGE, info);
-                       }
+                       notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info);
                }
        }
        return 0;
@@ -1102,7 +1021,7 @@ fb_blank(struct fb_info *info, int blank)
                cmap.len = info->cmap.len;
        } else
                cmap = info->cmap;
-       return fb_set_cmap(&cmap, info);
+       return fb_set_cmap(&cmap, 1, info);
 }
 
 static int 
@@ -1117,66 +1036,63 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
        struct fb_con2fbmap con2fb;
 #endif
-       struct fb_cmap_user cmap;
-       void __user *argp = (void __user *)arg;
+       struct fb_cmap cmap;
        int i;
        
        if (!fb)
                return -ENODEV;
        switch (cmd) {
        case FBIOGET_VSCREENINFO:
-               return copy_to_user(argp, &info->var,
+               return copy_to_user((void *) arg, &info->var,
                                    sizeof(var)) ? -EFAULT : 0;
        case FBIOPUT_VSCREENINFO:
-               if (copy_from_user(&var, argp, sizeof(var)))
+               if (copy_from_user(&var, (void *) arg, sizeof(var)))
                        return -EFAULT;
                acquire_console_sem();
-               info->flags |= FBINFO_MISC_MODECHANGEUSER;
                i = fb_set_var(info, &var);
-               info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
                release_console_sem();
                if (i) return i;
-               if (copy_to_user(argp, &var, sizeof(var)))
+               if (copy_to_user((void *) arg, &var, sizeof(var)))
                        return -EFAULT;
                return 0;
        case FBIOGET_FSCREENINFO:
-               return copy_to_user(argp, &info->fix,
+               return copy_to_user((void *) arg, &info->fix,
                                    sizeof(fix)) ? -EFAULT : 0;
        case FBIOPUTCMAP:
-               if (copy_from_user(&cmap, argp, sizeof(cmap)))
+               if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
                        return -EFAULT;
-               return (fb_set_user_cmap(&cmap, info));
+               return (fb_set_cmap(&cmap, 0, info));
        case FBIOGETCMAP:
-               if (copy_from_user(&cmap, argp, sizeof(cmap)))
+               if (copy_from_user(&cmap, (void *) arg, sizeof(cmap)))
                        return -EFAULT;
-               return fb_cmap_to_user(&info->cmap, &cmap);
+               return (fb_copy_cmap(&info->cmap, &cmap, 2));
        case FBIOPAN_DISPLAY:
-               if (copy_from_user(&var, argp, sizeof(var)))
+               if (copy_from_user(&var, (void *) arg, sizeof(var)))
                        return -EFAULT;
                acquire_console_sem();
                i = fb_pan_display(info, &var);
                release_console_sem();
                if (i)
                        return i;
-               if (copy_to_user(argp, &var, sizeof(var)))
+               if (copy_to_user((void *) arg, &var, sizeof(var)))
                        return -EFAULT;
                return 0;
        case FBIO_CURSOR:
                acquire_console_sem();
-               i = fb_cursor(info, argp);
+               i = fb_cursor(info, (struct fb_cursor *) arg);
                release_console_sem();
                return i;
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
        case FBIOGET_CON2FBMAP:
-               if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
+               if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
                        return -EFAULT;
                if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
                    return -EINVAL;
                con2fb.framebuffer = con2fb_map[con2fb.console-1];
-               return copy_to_user(argp, &con2fb,
+               return copy_to_user((void *)arg, &con2fb,
                                    sizeof(con2fb)) ? -EFAULT : 0;
        case FBIOPUT_CON2FBMAP:
-               if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
+               if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
                        return - EFAULT;
                if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
                    return -EINVAL;
@@ -1188,10 +1104,11 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #endif /* CONFIG_KMOD */
                if (!registered_fb[con2fb.framebuffer])
                    return -EINVAL;
-               if (con2fb.console > 0 && con2fb.console < MAX_NR_CONSOLES)
-                       return set_con2fb_map(con2fb.console-1,
-                                             con2fb.framebuffer);
-               return -EINVAL;
+               if (con2fb.console != 0)
+                       set_con2fb_map(con2fb.console-1, con2fb.framebuffer);
+               else
+                       fb_console_init();              
+               return 0;
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE */
        case FBIOBLANK:
                acquire_console_sem();
@@ -1397,6 +1314,10 @@ register_framebuffer(struct fb_info *fb_info)
                }
        }       
        fb_info->pixmap.offset = 0;
+       if (fb_info->pixmap.outbuf == NULL)
+               fb_info->pixmap.outbuf = fb_sys_outbuf;
+       if (fb_info->pixmap.inbuf == NULL)
+               fb_info->pixmap.inbuf = fb_sys_inbuf;
 
        if (fb_info->sprite.addr == NULL) {
                fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
@@ -1409,6 +1330,10 @@ register_framebuffer(struct fb_info *fb_info)
                }
        }
        fb_info->sprite.offset = 0;
+       if (fb_info->sprite.outbuf == NULL)
+               fb_info->sprite.outbuf = fb_sys_outbuf;
+       if (fb_info->sprite.inbuf == NULL)
+               fb_info->sprite.inbuf = fb_sys_inbuf;
 
        registered_fb[i] = fb_info;
 
@@ -1500,7 +1425,7 @@ fbmem_init(void)
 {
        int i;
 
-       create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
+       create_proc_read_entry("fb", 0, 0, fbmem_read_proc, NULL);
 
        devfs_mk_dir("fb");
        if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
@@ -1603,10 +1528,8 @@ EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
 EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_iomove_buf_unaligned);
-EXPORT_SYMBOL(fb_iomove_buf_aligned);
-EXPORT_SYMBOL(fb_sysmove_buf_unaligned);
-EXPORT_SYMBOL(fb_sysmove_buf_aligned);
+EXPORT_SYMBOL(fb_move_buf_unaligned);
+EXPORT_SYMBOL(fb_move_buf_aligned);
 EXPORT_SYMBOL(fb_load_cursor_image);
 EXPORT_SYMBOL(fb_set_suspend);
 EXPORT_SYMBOL(fb_register_client);