Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / drivers / video / fbmem.c
index 7a41220..be2be97 100644 (file)
@@ -1154,8 +1154,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
                event.data = &con2fb;
                if (!lock_fb_info(info))
                        return -ENODEV;
+               console_lock();
                event.info = info;
                ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
+               console_unlock();
                unlock_fb_info(info);
                break;
        case FBIOBLANK:
@@ -1348,15 +1350,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
        struct fb_info *info = file_fb_info(file);
        struct fb_ops *fb;
-       unsigned long off;
+       unsigned long mmio_pgoff;
        unsigned long start;
        u32 len;
 
        if (!info)
                return -ENODEV;
-       if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-               return -EINVAL;
-       off = vma->vm_pgoff << PAGE_SHIFT;
        fb = info->fbops;
        if (!fb)
                return -ENODEV;
@@ -1368,33 +1367,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
                return res;
        }
 
-       /* frame buffer memory */
+       /*
+        * Ugh. This can be either the frame buffer mapping, or
+        * if pgoff points past it, the mmio mapping.
+        */
        start = info->fix.smem_start;
-       len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
-       if (off >= len) {
-               /* memory mapped io */
-               off -= len;
-               if (info->var.accel_flags) {
-                       mutex_unlock(&info->mm_lock);
-                       return -EINVAL;
-               }
+       len = info->fix.smem_len;
+       mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
+       if (vma->vm_pgoff >= mmio_pgoff) {
+               vma->vm_pgoff -= mmio_pgoff;
                start = info->fix.mmio_start;
-               len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
+               len = info->fix.mmio_len;
        }
        mutex_unlock(&info->mm_lock);
-       start &= PAGE_MASK;
-       if ((vma->vm_end - vma->vm_start + off) > len)
-               return -EINVAL;
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       /* This is an IO map - tell maydump to skip this VMA */
-       vma->vm_flags |= VM_IO | VM_RESERVED;
+
        vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-       fb_pgprotect(file, vma, off);
-       if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-                            vma->vm_end - vma->vm_start, vma->vm_page_prot))
-               return -EAGAIN;
-       return 0;
+       fb_pgprotect(file, vma, start);
+
+       return vm_iomap_memory(vma, start, len);
 }
 
 static int
@@ -1454,7 +1444,7 @@ __releases(&info->lock)
        return 0;
 }
 
-static const struct file_operations fb_fops = {
+const struct file_operations fb_fops = {
        .owner =        THIS_MODULE,
        .read =         fb_read,
        .write =        fb_write,
@@ -1628,7 +1618,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
        event.info = fb_info;
        if (!lock_fb_info(fb_info))
                return -ENODEV;
+       console_lock();
        fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
+       console_unlock();
        unlock_fb_info(fb_info);
        return 0;
 }
@@ -1644,8 +1636,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 
        if (!lock_fb_info(fb_info))
                return -ENODEV;
+       console_lock();
        event.info = fb_info;
        ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+       console_unlock();
        unlock_fb_info(fb_info);
 
        if (ret)
@@ -1660,7 +1654,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
        num_registered_fb--;
        fb_cleanup_device(fb_info);
        event.info = fb_info;
+       console_lock();
        fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
+       console_unlock();
 
        /* this may free fb info */
        put_fb_info(fb_info);
@@ -1831,11 +1827,8 @@ int fb_new_modelist(struct fb_info *info)
        err = 1;
 
        if (!list_empty(&info->modelist)) {
-               if (!lock_fb_info(info))
-                       return -ENODEV;
                event.info = info;
                err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event);
-               unlock_fb_info(info);
        }
 
        return err;