This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / video / fbmem.c
index 5e28466..148cb0b 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 clgenfb_init(void);
-extern int clgenfb_setup(char*);
+extern int cirrusfb_init(void);
+extern int cirrusfb_setup(char*);
 extern int hitfb_init(void);
 extern int vfb_init(void);
 extern int vfb_setup(char*);
@@ -114,6 +114,8 @@ extern int valkyriefb_setup(char*);
 extern int chips_init(void);
 extern int g364fb_init(void);
 extern int sa1100fb_init(void);
+extern int pxafb_init(void);
+extern int pxafb_setup(char*);
 extern int fm2fb_init(void);
 extern int fm2fb_setup(char*);
 extern int q40fb_init(void);
@@ -121,6 +123,8 @@ extern int sun3fb_init(void);
 extern int sun3fb_setup(char *);
 extern int sgivwfb_init(void);
 extern int sgivwfb_setup(char*);
+extern int gbefb_init(void);
+extern int gbefb_setup(char*);
 extern int rivafb_init(void);
 extern int rivafb_setup(char*);
 extern int tdfxfb_init(void);
@@ -166,6 +170,9 @@ extern int leo_init(void);
 extern int leo_setup(char*);
 extern int kyrofb_init(void);
 extern int kyrofb_setup(char*);
+extern int mc68x328fb_init(void);
+extern int mc68x328fb_setup(char *);
+extern int asiliantfb_init(void);
 
 static struct {
        const char *name;
@@ -197,8 +204,8 @@ static struct {
 #ifdef CONFIG_FB_PM3
        { "pm3fb", pm3fb_init, pm3fb_setup },
 #endif           
-#ifdef CONFIG_FB_CLGEN
-       { "clgenfb", clgenfb_init, clgenfb_setup },
+#ifdef CONFIG_FB_CIRRUS
+       { "cirrusfb", cirrusfb_init, cirrusfb_setup },
 #endif
 #ifdef CONFIG_FB_ATY
        { "atyfb", atyfb_init, atyfb_setup },
@@ -307,6 +314,9 @@ static struct {
 #ifdef CONFIG_FB_SGIVW
        { "sgivwfb", sgivwfb_init, sgivwfb_setup },
 #endif
+#ifdef CONFIG_FB_GBE
+       { "gbefb", gbefb_init, gbefb_setup },
+#endif
 #ifdef CONFIG_FB_ACORN
        { "acornfb", acornfb_init, acornfb_setup },
 #endif
@@ -340,6 +350,9 @@ static struct {
 #ifdef CONFIG_FB_SA1100
        { "sa1100fb", sa1100fb_init, NULL },
 #endif
+#ifdef CONFIG_FB_PXA
+       { "pxafb", pxafb_init, pxafb_setup },
+#endif
 #ifdef CONFIG_FB_SUN3
        { "sun3fb", sun3fb_init, sun3fb_setup },
 #endif
@@ -370,6 +383,12 @@ static struct {
 #ifdef CONFIG_FB_KYRO
        { "kyrofb", kyrofb_init, kyrofb_setup },
 #endif
+#ifdef CONFIG_FB_68328
+       { "68328fb", mc68x328fb_init, mc68x328fb_setup },
+#endif
+#ifdef CONFIG_FB_ASILIANT
+       { "asiliantfb", asiliantfb_init, NULL },
+#endif
 
        /*
         * Generic drivers that don't use resource management (yet)
@@ -411,19 +430,9 @@ static int ofonly __initdata = 0;
 /*
  * Drawing helpers.
  */
-u8 sys_inbuf(struct fb_info *info, u8 *src)
-{      
-       return *src;
-}
-
-void sys_outbuf(struct fb_info *info, u8 *dst, u8 *src, unsigned int size)
-{
-       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)
+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)
 {
        int i;
 
@@ -434,10 +443,24 @@ void fb_move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
        }
 }
 
-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)
+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)
+{
+       int i, j;
+
+       for (i = height; i--; ) {
+               for (j = 0; j < s_pitch; j++)
+                       dst[j] = src[j];
+               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)
 {
        u8 mask = (u8) (0xfff << shift_high), tmp;
        int i, j;
@@ -465,6 +488,37 @@ void fb_move_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()
@@ -786,7 +840,7 @@ static int fbmem_read_proc(char *buf, char **start, off_t offset,
 }
 
 static ssize_t
-fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned long p = *ppos;
        struct inode *inode = file->f_dentry->d_inode;
@@ -823,7 +877,7 @@ fb_read(struct file *file, char *buf, size_t count, loff_t *ppos)
 }
 
 static ssize_t
-fb_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
        unsigned long p = *ppos;
        struct inode *inode = file->f_dentry->d_inode;
@@ -877,7 +931,10 @@ fb_load_cursor_image(struct fb_info *info)
        unsigned int width = (info->cursor.image.width + 7) >> 3;
        u8 *data = (u8 *) info->cursor.image.data;
 
-       info->sprite.outbuf(info, info->sprite.addr, data, width);
+       if (info->sprite.outbuf)
+           info->sprite.outbuf(info, info->sprite.addr, data, width);
+       else
+           memcpy(info->sprite.addr, data, width);
 }
 
 int
@@ -900,26 +957,30 @@ fb_cursor(struct fb_info *info, struct fb_cursor *sprite)
        
        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;
                
-               cursor.image.data = kmalloc(size, GFP_KERNEL);
-               if (!cursor.image.data)
+               data = kmalloc(size, GFP_KERNEL);
+               if (!data)
                        return -ENOMEM;
                
-               cursor.mask = kmalloc(size, GFP_KERNEL);
-               if (!cursor.mask) {
-                       kfree(cursor.image.data);
+               mask = kmalloc(size, GFP_KERNEL);
+               if (!mask) {
+                       kfree(data);
                        return -ENOMEM;
                }
                
-               if (copy_from_user(cursor.image.data, sprite->image.data, size) ||
-                   copy_from_user(cursor.mask, sprite->mask, size)) { 
-                       kfree(cursor.image.data);
-                       kfree(cursor.mask);
+               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;
@@ -974,7 +1035,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
 
                        fb_set_cmap(&info->cmap, 1, info);
 
-                       notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info);
+                       if (info->flags & FBINFO_MISC_MODECHANGEUSER) {
+                               info->flags &= ~FBINFO_MISC_MODECHANGEUSER;
+                               notifier_call_chain(&fb_notifier_list,
+                                                   FB_EVENT_MODE_CHANGE, info);
+                       }
                }
        }
        return 0;
@@ -1013,7 +1078,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
        struct fb_con2fbmap con2fb;
 #endif
        struct fb_cmap cmap;
-       int i, rc;
+       int i;
        
        if (!fb)
                return -ENODEV;
@@ -1025,7 +1090,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                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((void *) arg, &var, sizeof(var)))
@@ -1055,9 +1122,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                return 0;
        case FBIO_CURSOR:
                acquire_console_sem();
-               rc = fb_cursor(info, (struct fb_cursor *) arg);
+               i = fb_cursor(info, (struct fb_cursor *) arg);
                release_console_sem();
-               return rc;
+               return i;
 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
        case FBIOGET_CON2FBMAP:
                if (copy_from_user(&con2fb, (void *)arg, sizeof(con2fb)))
@@ -1080,11 +1147,10 @@ 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)
-                       set_con2fb_map(con2fb.console-1, con2fb.framebuffer);
-               else
-                       fb_console_init();              
-               return 0;
+               if (con2fb.console > 0 && con2fb.console < MAX_NR_CONSOLES)
+                       return set_con2fb_map(con2fb.console-1,
+                                             con2fb.framebuffer);
+               return -EINVAL;
 #endif /* CONFIG_FRAMEBUFFER_CONSOLE */
        case FBIOBLANK:
                acquire_console_sem();
@@ -1178,8 +1244,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
        if (boot_cpu_data.x86 > 3)
                pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 #elif defined(__mips__)
-       pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
-       pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 #elif defined(__hppa__)
        pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
 #elif defined(__ia64__) || defined(__arm__) || defined(__sh__)
@@ -1286,14 +1351,11 @@ register_framebuffer(struct fb_info *fb_info)
                        fb_info->pixmap.size = FBPIXMAPSIZE;
                        fb_info->pixmap.buf_align = 1;
                        fb_info->pixmap.scan_align = 1;
+                       fb_info->pixmap.access_align = 4;
                        fb_info->pixmap.flags = FB_PIXMAP_DEFAULT;
                }
        }       
        fb_info->pixmap.offset = 0;
-       if (fb_info->pixmap.outbuf == NULL)
-               fb_info->pixmap.outbuf = sys_outbuf;
-       if (fb_info->pixmap.inbuf == NULL)
-               fb_info->pixmap.inbuf = sys_inbuf;
 
        if (fb_info->sprite.addr == NULL) {
                fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
@@ -1301,14 +1363,11 @@ register_framebuffer(struct fb_info *fb_info)
                        fb_info->sprite.size = FBPIXMAPSIZE;
                        fb_info->sprite.buf_align = 1;
                        fb_info->sprite.scan_align = 1;
+                       fb_info->sprite.access_align = 4;
                        fb_info->sprite.flags = FB_PIXMAP_DEFAULT;
                }
        }
        fb_info->sprite.offset = 0;
-       if (fb_info->sprite.outbuf == NULL)
-               fb_info->sprite.outbuf = sys_outbuf;
-       if (fb_info->sprite.inbuf == NULL)
-               fb_info->sprite.inbuf = sys_inbuf;
 
        registered_fb[i] = fb_info;
 
@@ -1400,7 +1459,7 @@ fbmem_init(void)
 {
        int i;
 
-       create_proc_read_entry("fb", 0, 0, fbmem_read_proc, NULL);
+       create_proc_read_entry("fb", 0, NULL, fbmem_read_proc, NULL);
 
        devfs_mk_dir("fb");
        if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
@@ -1503,8 +1562,10 @@ EXPORT_SYMBOL(fb_set_var);
 EXPORT_SYMBOL(fb_blank);
 EXPORT_SYMBOL(fb_pan_display);
 EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_move_buf_unaligned);
-EXPORT_SYMBOL(fb_move_buf_aligned);
+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_load_cursor_image);
 EXPORT_SYMBOL(fb_set_suspend);
 EXPORT_SYMBOL(fb_register_client);