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);
-       struct drm_device *dev = helper->dev;
+       struct drm_fb_helper *helper = container_of(work, struct drm_fb_helper, damage_work);
        struct drm_clip_rect *clip = &helper->damage_clip;
        struct drm_clip_rect clip_copy;
        unsigned long flags;
        int ret;
 
+       if (!helper->funcs->fb_dirty)
+               return;
+
        spin_lock_irqsave(&helper->damage_lock, flags);
        clip_copy = *clip;
        clip->x1 = clip->y1 = ~0;
        clip->x2 = clip->y2 = 0;
        spin_unlock_irqrestore(&helper->damage_lock, flags);
 
-       /* Call damage handlers only if necessary */
-       if (!(clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2))
-               return;
-
-       if (helper->buffer) {
-               ret = drm_fb_helper_damage_blit(helper, &clip_copy);
-               if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret))
-                       goto err;
-       }
-
-       if (helper->fb->funcs->dirty) {
-               ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
-               if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
-                       goto err;
-       }
+       ret = helper->funcs->fb_dirty(helper, &clip_copy);
+       if (ret)
+               goto err;
 
        return;
 
 }
 EXPORT_SYMBOL(drm_fb_helper_fini);
 
-static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
-{
-       struct drm_device *dev = fb_helper->dev;
-       struct drm_framebuffer *fb = fb_helper->fb;
-
-       return dev->mode_config.prefer_shadow_fbdev ||
-              dev->mode_config.prefer_shadow ||
-              fb->funcs->dirty;
-}
-
 static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y,
                                 u32 width, u32 height)
 {
        struct drm_clip_rect *clip = &helper->damage_clip;
        unsigned long flags;
 
-       if (!drm_fbdev_use_shadow_fb(helper))
+       if (!helper->funcs->fb_dirty)
                return;
 
        spin_lock_irqsave(&helper->damage_lock, flags);
 }
 EXPORT_SYMBOL(drm_fb_helper_output_poll_changed);
 
+static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
+{
+       struct drm_device *dev = fb_helper->dev;
+       struct drm_framebuffer *fb = fb_helper->fb;
+
+       return dev->mode_config.prefer_shadow_fbdev ||
+              dev->mode_config.prefer_shadow ||
+              fb->funcs->dirty;
+}
+
 /* @user: 1=userspace, 0=fbcon */
 static int drm_fbdev_fb_open(struct fb_info *info, int user)
 {
        return 0;
 }
 
+static int drm_fbdev_fb_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip)
+{
+       struct drm_device *dev = helper->dev;
+       int ret;
+
+       if (!drm_fbdev_use_shadow_fb(helper))
+               return 0;
+
+       /* Call damage handlers only if necessary */
+       if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+               return 0;
+
+       if (helper->buffer) {
+               ret = drm_fb_helper_damage_blit(helper, clip);
+               if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret))
+                       return ret;
+       }
+
+       if (helper->fb->funcs->dirty) {
+               ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+               if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
+                       return ret;
+       }
+
+       return 0;
+}
+
 static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = {
        .fb_probe = drm_fb_helper_generic_probe,
+       .fb_dirty = drm_fbdev_fb_dirty,
 };
 
 static void drm_fbdev_client_unregister(struct drm_client_dev *client)