Commit 28f57d03 authored by Thomas Zimmermann's avatar Thomas Zimmermann

fbdev/arcfb: Use generator macros for deferred I/O

Implement the driver's fops with the generator macros for deferred
I/O. Only requires per-driver code for the on-scren scanout buffer.
The generated helpers implement reading, writing and drawing on top
of that. Also update the selected Kconfig tokens accordingly.

Actual support for deferred I/O is missing from the driver. So
writing to memory-mapped pages does not automatically update the
scanout buffer.
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Cc: Jaya Kumar <jayalk@intworks.biz>
Acked-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231127131655.4020-7-tzimmermann@suse.de
parent 30b72c0b
...@@ -272,10 +272,7 @@ config FB_FM2 ...@@ -272,10 +272,7 @@ config FB_FM2
config FB_ARC config FB_ARC
tristate "Arc Monochrome LCD board support" tristate "Arc Monochrome LCD board support"
depends on FB && (X86 || COMPILE_TEST) depends on FB && (X86 || COMPILE_TEST)
select FB_SYS_FILLRECT select FB_SYSMEM_HELPERS_DEFERRED
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
help help
This enables support for the Arc Monochrome LCD board. The board This enables support for the Arc Monochrome LCD board. The board
is based on the KS-108 lcd controller and is typically a matrix is based on the KS-108 lcd controller and is typically a matrix
......
...@@ -363,39 +363,6 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx, ...@@ -363,39 +363,6 @@ static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx,
} }
} }
static void arcfb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
struct arcfb_par *par = info->par;
sys_fillrect(info, rect);
/* update the physical lcd */
arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
}
static void arcfb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
struct arcfb_par *par = info->par;
sys_copyarea(info, area);
/* update the physical lcd */
arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
}
static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct arcfb_par *par = info->par;
sys_imageblit(info, image);
/* update the physical lcd */
arcfb_lcd_update(par, image->dx, image->dy, image->width,
image->height);
}
static int arcfb_ioctl(struct fb_info *info, static int arcfb_ioctl(struct fb_info *info,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -436,76 +403,48 @@ static int arcfb_ioctl(struct fb_info *info, ...@@ -436,76 +403,48 @@ static int arcfb_ioctl(struct fb_info *info,
} }
} }
/* static void arcfb_damage_range(struct fb_info *info, off_t off, size_t len)
* this is the access path from userspace. they can seek and write to
* the fb. it's inefficient for them to do anything less than 64*8
* writes since we update the lcd in each write() anyway.
*/
static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{ {
/* modded from epson 1355 */ struct arcfb_par *par = info->par;
unsigned int xres = info->var.xres;
unsigned long p; unsigned int bitppos, startpos, endpos, bitcount;
int err; unsigned int x, y, width, height;
unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;
struct arcfb_par *par;
unsigned int xres;
if (!info->screen_buffer)
return -ENODEV;
p = *ppos;
par = info->par;
xres = info->var.xres;
fbmemlength = (xres * info->var.yres)/8;
if (p > fbmemlength)
return -ENOSPC;
err = 0;
if ((count + p) > fbmemlength) {
count = fbmemlength - p;
err = -ENOSPC;
}
if (count) {
char *base_addr;
base_addr = info->screen_buffer;
count -= copy_from_user(base_addr + p, buf, count);
*ppos += count;
err = -EFAULT;
}
bitppos = p*8; bitppos = off * 8;
startpos = floorXres(bitppos, xres); startpos = floorXres(bitppos, xres);
endpos = ceilXres((bitppos + (count*8)), xres); endpos = ceilXres((bitppos + (len * 8)), xres);
bitcount = endpos - startpos; bitcount = endpos - startpos;
x = startpos % xres; x = startpos % xres;
y = startpos / xres; y = startpos / xres;
w = xres; width = xres;
h = bitcount / xres; height = bitcount / xres;
arcfb_lcd_update(par, x, y, w, h);
arcfb_lcd_update(par, x, y, width, height);
}
if (count) static void arcfb_damage_area(struct fb_info *info, u32 x, u32 y,
return count; u32 width, u32 height)
return err; {
struct arcfb_par *par = info->par;
/* update the physical lcd */
arcfb_lcd_update(par, x, y, width, height);
} }
FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(arcfb,
arcfb_damage_range,
arcfb_damage_area)
static const struct fb_ops arcfb_ops = { static const struct fb_ops arcfb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_open = arcfb_open, .fb_open = arcfb_open,
.fb_read = fb_sys_read, __FB_DEFAULT_DEFERRED_OPS_RDWR(arcfb),
.fb_write = arcfb_write,
.fb_release = arcfb_release, .fb_release = arcfb_release,
.fb_pan_display = arcfb_pan_display, .fb_pan_display = arcfb_pan_display,
.fb_fillrect = arcfb_fillrect, __FB_DEFAULT_DEFERRED_OPS_DRAW(arcfb),
.fb_copyarea = arcfb_copyarea,
.fb_imageblit = arcfb_imageblit,
.fb_ioctl = arcfb_ioctl, .fb_ioctl = arcfb_ioctl,
// .fb_mmap reqires deferred I/O
}; };
static int arcfb_probe(struct platform_device *dev) static int arcfb_probe(struct platform_device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment