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;
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)
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;
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;
/* 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);
}
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,
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