drm/radeon/kms/evergreen: fix LUT setup
[safe/jmp/linux-2.6] / drivers / video / fbmem.c
index f8a09bf..a15b44e 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/compat.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/slab.h>
@@ -872,8 +871,8 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
                err = -EINVAL;
 
        if (err || !info->fbops->fb_pan_display ||
-           var->yoffset + yres > info->var.yres_virtual ||
-           var->xoffset + info->var.xres > info->var.xres_virtual)
+           var->yoffset > info->var.yres_virtual - yres ||
+           var->xoffset > info->var.xres_virtual - info->var.xres)
                return -EINVAL;
 
        if ((err = info->fbops->fb_pan_display(var, info)))
@@ -955,6 +954,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
                        goto done;
 
                if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+                       struct fb_var_screeninfo old_var;
                        struct fb_videomode mode;
 
                        if (info->fbops->fb_get_caps) {
@@ -964,10 +964,20 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
                                        goto done;
                        }
 
+                       old_var = info->var;
                        info->var = *var;
 
-                       if (info->fbops->fb_set_par)
-                               info->fbops->fb_set_par(info);
+                       if (info->fbops->fb_set_par) {
+                               ret = info->fbops->fb_set_par(info);
+
+                               if (ret) {
+                                       info->var = old_var;
+                                       printk(KERN_WARNING "detected "
+                                               "fb_set_par error, "
+                                               "error code: %d\n", ret);
+                                       goto done;
+                               }
+                       }
 
                        fb_pan_display(info, &info->var);
                        fb_set_cmap(&info->cmap, info);
@@ -1310,8 +1320,6 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
 
 static int
 fb_mmap(struct file *file, struct vm_area_struct * vma)
-__acquires(&info->lock)
-__releases(&info->lock)
 {
        int fbidx = iminor(file->f_path.dentry->d_inode);
        struct fb_info *info = registered_fb[fbidx];
@@ -1325,16 +1333,14 @@ __releases(&info->lock)
        off = vma->vm_pgoff << PAGE_SHIFT;
        if (!fb)
                return -ENODEV;
+       mutex_lock(&info->mm_lock);
        if (fb->fb_mmap) {
                int res;
-               mutex_lock(&info->lock);
                res = fb->fb_mmap(info, vma);
-               mutex_unlock(&info->lock);
+               mutex_unlock(&info->mm_lock);
                return res;
        }
 
-       mutex_lock(&info->lock);
-
        /* frame buffer memory */
        start = info->fix.smem_start;
        len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
@@ -1342,13 +1348,13 @@ __releases(&info->lock)
                /* memory mapped io */
                off -= len;
                if (info->var.accel_flags) {
-                       mutex_unlock(&info->lock);
+                       mutex_unlock(&info->mm_lock);
                        return -EINVAL;
                }
                start = info->fix.mmio_start;
                len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
        }
-       mutex_unlock(&info->lock);
+       mutex_unlock(&info->mm_lock);
        start &= PAGE_MASK;
        if ((vma->vm_end - vma->vm_start + off) > len)
                return -EINVAL;
@@ -1507,7 +1513,6 @@ register_framebuffer(struct fb_info *fb_info)
                                       fb_info->fix.id,
                                       registered_fb[i]->fix.id);
                                unregister_framebuffer(registered_fb[i]);
-                               break;
                        }
                }
        }
@@ -1518,6 +1523,7 @@ register_framebuffer(struct fb_info *fb_info)
                        break;
        fb_info->node = i;
        mutex_init(&fb_info->lock);
+       mutex_init(&fb_info->mm_lock);
 
        fb_info->dev = device_create(fb_class, fb_info->device,
                                     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
@@ -1793,7 +1799,7 @@ static int __init video_setup(char *options)
                global = 1;
        }
 
-       if (!global && !strstr(options, "fb:")) {
+       if (!global && !strchr(options, ':')) {
                fb_mode_option = options;
                global = 1;
        }