Merge tag 'drm-vc4-fixes-2016-09-14' of https://github.com/anholt/linux into drm...
[linux-2.6-block.git] / drivers / gpu / drm / udl / udl_fb.c
index fd1eb9d03f0b55751ae04568c53642a683a3e351..9688bfa92ccd33545982dbeedbdc8154c3ca38f1 100644 (file)
@@ -77,68 +77,6 @@ static uint16_t rgb16(uint32_t col)
 }
 #endif
 
-/*
- * NOTE: fb_defio.c is holding info->fbdefio.mutex
- *   Touching ANY framebuffer memory that triggers a page fault
- *   in fb_defio will cause a deadlock, when it also tries to
- *   grab the same mutex.
- */
-static void udlfb_dpy_deferred_io(struct fb_info *info,
-                                 struct list_head *pagelist)
-{
-       struct page *cur;
-       struct fb_deferred_io *fbdefio = info->fbdefio;
-       struct udl_fbdev *ufbdev = info->par;
-       struct drm_device *dev = ufbdev->ufb.base.dev;
-       struct udl_device *udl = dev->dev_private;
-       struct urb *urb;
-       char *cmd;
-       cycles_t start_cycles, end_cycles;
-       int bytes_sent = 0;
-       int bytes_identical = 0;
-       int bytes_rendered = 0;
-
-       if (!fb_defio)
-               return;
-
-       start_cycles = get_cycles();
-
-       urb = udl_get_urb(dev);
-       if (!urb)
-               return;
-
-       cmd = urb->transfer_buffer;
-
-       /* walk the written page list and render each to device */
-       list_for_each_entry(cur, &fbdefio->pagelist, lru) {
-
-               if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
-                                    &urb, (char *) info->fix.smem_start,
-                                    &cmd, cur->index << PAGE_SHIFT,
-                                    cur->index << PAGE_SHIFT,
-                                    PAGE_SIZE, &bytes_identical, &bytes_sent))
-                       goto error;
-               bytes_rendered += PAGE_SIZE;
-       }
-
-       if (cmd > (char *) urb->transfer_buffer) {
-               /* Send partial buffer remaining before exiting */
-               int len = cmd - (char *) urb->transfer_buffer;
-               udl_submit_urb(dev, urb, len);
-               bytes_sent += len;
-       } else
-               udl_urb_completion(urb);
-
-error:
-       atomic_add(bytes_sent, &udl->bytes_sent);
-       atomic_add(bytes_identical, &udl->bytes_identical);
-       atomic_add(bytes_rendered, &udl->bytes_rendered);
-       end_cycles = get_cycles();
-       atomic_add(((unsigned int) ((end_cycles - start_cycles)
-                   >> 10)), /* Kcycles */
-                  &udl->cpu_kcycles_used);
-}
-
 int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
                      int width, int height)
 {
@@ -152,9 +90,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
        struct urb *urb;
        int aligned_x;
        int bpp = (fb->base.bits_per_pixel / 8);
-       int x2, y2;
-       bool store_for_later = false;
-       unsigned long flags;
 
        if (!fb->active_16)
                return 0;
@@ -180,38 +115,6 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
            (y + height > fb->base.height))
                return -EINVAL;
 
-       /* if we are in atomic just store the info
-          can't test inside spin lock */
-       if (in_atomic())
-               store_for_later = true;
-
-       x2 = x + width - 1;
-       y2 = y + height - 1;
-
-       spin_lock_irqsave(&fb->dirty_lock, flags);
-
-       if (fb->y1 < y)
-               y = fb->y1;
-       if (fb->y2 > y2)
-               y2 = fb->y2;
-       if (fb->x1 < x)
-               x = fb->x1;
-       if (fb->x2 > x2)
-               x2 = fb->x2;
-
-       if (store_for_later) {
-               fb->x1 = x;
-               fb->x2 = x2;
-               fb->y1 = y;
-               fb->y2 = y2;
-               spin_unlock_irqrestore(&fb->dirty_lock, flags);
-               return 0;
-       }
-
-       fb->x1 = fb->y1 = INT_MAX;
-       fb->x2 = fb->y2 = 0;
-
-       spin_unlock_irqrestore(&fb->dirty_lock, flags);
        start_cycles = get_cycles();
 
        urb = udl_get_urb(dev);
@@ -219,14 +122,14 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
                return 0;
        cmd = urb->transfer_buffer;
 
-       for (i = y; i <= y2 ; i++) {
+       for (i = y; i < height ; i++) {
                const int line_offset = fb->base.pitches[0] * i;
                const int byte_offset = line_offset + (x * bpp);
                const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
                if (udl_render_hline(dev, bpp, &urb,
                                     (char *) fb->obj->vmapping,
                                     &cmd, byte_offset, dev_byte_offset,
-                                    (x2 - x + 1) * bpp,
+                                    width * bpp,
                                     &bytes_identical, &bytes_sent))
                        goto error;
        }
@@ -283,36 +186,6 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
        return 0;
 }
 
-static void udl_fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
-{
-       struct udl_fbdev *ufbdev = info->par;
-
-       drm_fb_helper_sys_fillrect(info, rect);
-
-       udl_handle_damage(&ufbdev->ufb, rect->dx, rect->dy, rect->width,
-                         rect->height);
-}
-
-static void udl_fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
-{
-       struct udl_fbdev *ufbdev = info->par;
-
-       drm_fb_helper_sys_copyarea(info, region);
-
-       udl_handle_damage(&ufbdev->ufb, region->dx, region->dy, region->width,
-                         region->height);
-}
-
-static void udl_fb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
-       struct udl_fbdev *ufbdev = info->par;
-
-       drm_fb_helper_sys_imageblit(info, image);
-
-       udl_handle_damage(&ufbdev->ufb, image->dx, image->dy, image->width,
-                         image->height);
-}
-
 /*
  * It's common for several clients to have framebuffer open simultaneously.
  * e.g. both fbcon and X. Makes things interesting.
@@ -330,6 +203,7 @@ static int udl_fb_open(struct fb_info *info, int user)
 
        ufbdev->fb_count++;
 
+#ifdef CONFIG_DRM_FBDEV_EMULATION
        if (fb_defio && (info->fbdefio == NULL)) {
                /* enable defio at last moment if not disabled by client */
 
@@ -339,12 +213,13 @@ static int udl_fb_open(struct fb_info *info, int user)
 
                if (fbdefio) {
                        fbdefio->delay = DL_DEFIO_WRITE_DELAY;
-                       fbdefio->deferred_io = udlfb_dpy_deferred_io;
+                       fbdefio->deferred_io = drm_fb_helper_deferred_io;
                }
 
                info->fbdefio = fbdefio;
                fb_deferred_io_init(info);
        }
+#endif
 
        pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
                  info->node, user, info, ufbdev->fb_count);
@@ -362,12 +237,14 @@ static int udl_fb_release(struct fb_info *info, int user)
 
        ufbdev->fb_count--;
 
+#ifdef CONFIG_DRM_FBDEV_EMULATION
        if ((ufbdev->fb_count == 0) && (info->fbdefio)) {
                fb_deferred_io_cleanup(info);
                kfree(info->fbdefio);
                info->fbdefio = NULL;
                info->fbops->fb_mmap = udl_fb_mmap;
        }
+#endif
 
        pr_warn("released /dev/fb%d user=%d count=%d\n",
                info->node, user, ufbdev->fb_count);
@@ -379,9 +256,9 @@ static struct fb_ops udlfb_ops = {
        .owner = THIS_MODULE,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
-       .fb_fillrect = udl_fb_fillrect,
-       .fb_copyarea = udl_fb_copyarea,
-       .fb_imageblit = udl_fb_imageblit,
+       .fb_fillrect = drm_fb_helper_sys_fillrect,
+       .fb_copyarea = drm_fb_helper_sys_copyarea,
+       .fb_imageblit = drm_fb_helper_sys_imageblit,
        .fb_pan_display = drm_fb_helper_pan_display,
        .fb_blank = drm_fb_helper_blank,
        .fb_setcmap = drm_fb_helper_setcmap,
@@ -458,7 +335,6 @@ udl_framebuffer_init(struct drm_device *dev,
 {
        int ret;
 
-       spin_lock_init(&ufb->dirty_lock);
        ufb->obj = obj;
        drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd);
        ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs);
@@ -628,7 +504,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
        int ret;
        uint32_t size;
 
-       obj = drm_gem_object_lookup(dev, file, mode_cmd->handles[0]);
+       obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
        if (obj == NULL)
                return ERR_PTR(-ENOENT);