drm/gem: Store client buffer mappings as struct dma_buf_map
[linux-2.6-microblaze.git] / drivers / gpu / drm / drm_fb_helper.c
index 1543d9d..a0d8813 100644 (file)
@@ -281,18 +281,12 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
 EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
 
 #ifdef CONFIG_MAGIC_SYSRQ
-/*
- * restore fbcon display for all kms driver's using this helper, used for sysrq
- * and panic handling.
- */
-static bool drm_fb_helper_force_kernel_mode(void)
+/* emergency restore, don't bother with error reporting */
+static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
 {
-       bool ret, error = false;
        struct drm_fb_helper *helper;
 
-       if (list_empty(&kernel_fb_helper_list))
-               return false;
-
+       mutex_lock(&kernel_fb_helper_lock);
        list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
                struct drm_device *dev = helper->dev;
 
@@ -300,22 +294,12 @@ static bool drm_fb_helper_force_kernel_mode(void)
                        continue;
 
                mutex_lock(&helper->lock);
-               ret = drm_client_modeset_commit_locked(&helper->client);
-               if (ret)
-                       error = true;
+               drm_client_modeset_commit_locked(&helper->client);
                mutex_unlock(&helper->lock);
        }
-       return error;
+       mutex_unlock(&kernel_fb_helper_lock);
 }
 
-static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
-{
-       bool ret;
-
-       ret = drm_fb_helper_force_kernel_mode();
-       if (ret == true)
-               DRM_ERROR("Failed to restore crtc configuration\n");
-}
 static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
 
 static void drm_fb_helper_sysrq(int dummy1)
@@ -394,7 +378,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
        unsigned int cpp = fb->format->cpp[0];
        size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
        void *src = fb_helper->fbdev->screen_buffer + offset;
-       void *dst = fb_helper->buffer->vaddr + offset;
+       void *dst = fb_helper->buffer->map.vaddr + offset;
        size_t len = (clip->x2 - clip->x1) * cpp;
        unsigned int y;
 
@@ -416,7 +400,8 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
        struct drm_clip_rect *clip = &helper->dirty_clip;
        struct drm_clip_rect clip_copy;
        unsigned long flags;
-       void *vaddr;
+       struct dma_buf_map map;
+       int ret;
 
        spin_lock_irqsave(&helper->dirty_lock, flags);
        clip_copy = *clip;
@@ -429,8 +414,8 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
 
                /* Generic fbdev uses a shadow buffer */
                if (helper->buffer) {
-                       vaddr = drm_client_buffer_vmap(helper->buffer);
-                       if (IS_ERR(vaddr))
+                       ret = drm_client_buffer_vmap(helper->buffer, &map);
+                       if (ret)
                                return;
                        drm_fb_helper_dirty_blit_real(helper, &clip_copy);
                }
@@ -2076,7 +2061,8 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
        struct drm_framebuffer *fb;
        struct fb_info *fbi;
        u32 format;
-       void *vaddr;
+       struct dma_buf_map map;
+       int ret;
 
        drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",
                    sizes->surface_width, sizes->surface_height,
@@ -2112,14 +2098,22 @@ static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
                fb_deferred_io_init(fbi);
        } else {
                /* buffer is mapped for HW framebuffer */
-               vaddr = drm_client_buffer_vmap(fb_helper->buffer);
-               if (IS_ERR(vaddr))
-                       return PTR_ERR(vaddr);
+               ret = drm_client_buffer_vmap(fb_helper->buffer, &map);
+               if (ret)
+                       return ret;
+               if (map.is_iomem)
+                       fbi->screen_base = map.vaddr_iomem;
+               else
+                       fbi->screen_buffer = map.vaddr;
 
-               fbi->screen_buffer = vaddr;
-               /* Shamelessly leak the physical address to user-space */
+               /*
+                * Shamelessly leak the physical address to user-space. As
+                * page_to_phys() is undefined for I/O memory, warn in this
+                * case.
+                */
 #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
-               if (drm_leak_fbdev_smem && fbi->fix.smem_start == 0)
+               if (drm_leak_fbdev_smem && fbi->fix.smem_start == 0 &&
+                   !drm_WARN_ON_ONCE(dev, map.is_iomem))
                        fbi->fix.smem_start =
                                page_to_phys(virt_to_page(fbi->screen_buffer));
 #endif