diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a1f86e436ae8..b3a731b9170a 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -403,6 +403,13 @@ err: spin_unlock_irqrestore(&helper->damage_lock, flags); } +static void drm_fb_helper_damage_work(struct work_struct *work) +{ + struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work); + + drm_fb_helper_fb_dirty(helper); +} + /** * drm_fb_helper_prepare - setup a drm_fb_helper structure * @dev: DRM device @@ -418,6 +425,7 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, INIT_LIST_HEAD(&helper->kernel_fb_list); spin_lock_init(&helper->damage_lock); INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker); + INIT_WORK(&helper->damage_work, drm_fb_helper_damage_work); helper->damage_clip.x1 = helper->damage_clip.y1 = ~0; mutex_init(&helper->lock); helper->funcs = funcs; @@ -549,6 +557,7 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) return; cancel_work_sync(&fb_helper->resume_work); + cancel_work_sync(&fb_helper->damage_work); info = fb_helper->info; if (info) { @@ -590,16 +599,9 @@ static void drm_fb_helper_add_damage_clip(struct drm_fb_helper *helper, u32 x, u static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y, u32 width, u32 height) { - struct fb_info *info = helper->info; - drm_fb_helper_add_damage_clip(helper, x, y, width, height); - /* - * The current fbdev emulation only flushes buffers if a damage - * update is necessary. And we can assume that deferred I/O has - * been enabled as damage updates require deferred I/O for mmap. - */ - fb_deferred_io_schedule_flush(info); + schedule_work(&helper->damage_work); } /* @@ -664,16 +666,10 @@ void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head *pagerefli if (min_off < max_off) { drm_fb_helper_memory_range_to_clip(info, min_off, max_off - min_off, &damage_area); - drm_fb_helper_add_damage_clip(helper, damage_area.x1, damage_area.y1, - drm_rect_width(&damage_area), - drm_rect_height(&damage_area)); + drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1, + drm_rect_width(&damage_area), + drm_rect_height(&damage_area)); } - - /* - * Flushes all dirty pages from mmap's pageref list and the - * areas that have been written by struct fb_ops callbacks. - */ - drm_fb_helper_fb_dirty(helper); } EXPORT_SYMBOL(drm_fb_helper_deferred_io); diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index dec678f72a42..c730253ab85c 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -332,19 +332,3 @@ void fb_deferred_io_cleanup(struct fb_info *info) mutex_destroy(&fbdefio->lock); } EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); - -void fb_deferred_io_schedule_flush(struct fb_info *info) -{ - struct fb_deferred_io *fbdefio = info->fbdefio; - - if (WARN_ON_ONCE(!fbdefio)) - return; /* bug in driver logic */ - - /* - * There's no requirement from callers to schedule the - * flush immediately. Rather schedule the worker with a - * delay and let a few more writes pile up. - */ - schedule_delayed_work(&info->deferred_work, fbdefio->delay); -} -EXPORT_SYMBOL_GPL(fb_deferred_io_schedule_flush); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 455f6c2b8117..b111dc7ada78 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -116,6 +116,7 @@ struct drm_fb_helper_funcs { * @damage_clip: clip rectangle used with deferred_io to accumulate damage to * the screen buffer * @damage_lock: spinlock protecting @damage_clip + * @damage_work: worker used to flush the framebuffer * @resume_work: worker used during resume if the console lock is already taken * * This is the main structure used by the fbdev helpers. Drivers supporting @@ -145,6 +146,7 @@ struct drm_fb_helper { u32 pseudo_palette[17]; struct drm_clip_rect damage_clip; spinlock_t damage_lock; + struct work_struct damage_work; struct work_struct resume_work; /** diff --git a/include/linux/fb.h b/include/linux/fb.h index 3a822e4357b1..96b96323e9cb 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -663,7 +663,6 @@ extern void fb_deferred_io_open(struct fb_info *info, struct inode *inode, struct file *file); extern void fb_deferred_io_cleanup(struct fb_info *info); -extern void fb_deferred_io_schedule_flush(struct fb_info *info); extern int fb_deferred_io_fsync(struct file *file, loff_t start, loff_t end, int datasync); @@ -807,7 +806,7 @@ extern int fb_find_mode(struct fb_var_screeninfo *var, #if defined(CONFIG_VIDEO_NOMODESET) bool fb_modesetting_disabled(const char *drvname); #else -bool fb_modesetting_disabled(const char *drvname) +static inline bool fb_modesetting_disabled(const char *drvname) { return false; }