Use the existing generator macros to create deferred-I/O helpers for metronomefb and set them in the fb_ops structure. Functions for damage handling on memory ranges and areas are provided by the driver. Metronomefb's implementation of fb_write writes to system memory, so the generated code can use the respective helper internally. This also fixes a long-standing bug where fb_write returned an errno code instead of the number of written bytes. See the commit message of commit 921b7383f348 ("fbdev: Return number of bytes read or written") for more details. Signed-off-by: Thomas Zimmermann <tzimmermann@xxxxxxx> --- drivers/video/fbdev/metronomefb.c | 74 ++++--------------------------- 1 file changed, 8 insertions(+), 66 deletions(-) diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c index 3e1daca76e11..667bef10738c 100644 --- a/drivers/video/fbdev/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -483,86 +483,28 @@ static void metronomefb_dpy_deferred_io(struct fb_info *info, struct list_head * metronome_display_cmd(par); } -static void metronomefb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) +static void metronomefb_defio_damage_range(struct fb_info *info, off_t off, size_t len) { struct metronomefb_par *par = info->par; - sys_fillrect(info, rect); metronomefb_dpy_update(par); } -static void metronomefb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) +static void metronomefb_defio_damage_area(struct fb_info *info, u32 x, u32 y, + u32 width, u32 height) { struct metronomefb_par *par = info->par; - sys_copyarea(info, area); metronomefb_dpy_update(par); } -static void metronomefb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct metronomefb_par *par = info->par; - - sys_imageblit(info, image); - metronomefb_dpy_update(par); -} - -/* - * this is the slow path from userspace. they can seek and write to - * the fb. it is based on fb_sys_write - */ -static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct metronomefb_par *par = info->par; - unsigned long p = *ppos; - void *dst; - int err = 0; - unsigned long total_size; - - if (!info->screen_buffer) - return -ENODEV; - - total_size = info->fix.smem_len; - - if (p > total_size) - return -EFBIG; - - if (count > total_size) { - err = -EFBIG; - count = total_size; - } - - if (count + p > total_size) { - if (!err) - err = -ENOSPC; - - count = total_size - p; - } - - dst = info->screen_buffer + p; - - if (copy_from_user(dst, buf, count)) - err = -EFAULT; - - if (!err) - *ppos += count; - - metronomefb_dpy_update(par); - - return (err) ? err : count; -} +FB_GEN_DEFAULT_DEFERRED_SYS_OPS(metronomefb, + metronomefb_defio_damage_range, + metronomefb_defio_damage_area) static const struct fb_ops metronomefb_ops = { - .owner = THIS_MODULE, - .fb_write = metronomefb_write, - .fb_fillrect = metronomefb_fillrect, - .fb_copyarea = metronomefb_copyarea, - .fb_imageblit = metronomefb_imageblit, - .fb_mmap = fb_deferred_io_mmap, + .owner = THIS_MODULE, + FB_DEFAULT_DEFERRED_OPS(metronomefb), }; static struct fb_deferred_io metronomefb_defio = { -- 2.41.0