mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
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: Thomas Zimmermann <tzimmermann@suse.de> Cc: Jaya Kumar <jayalk@intworks.biz> Acked-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231127131655.4020-7-tzimmermann@suse.de
This commit is contained in:
parent
30b72c0bde
commit
28f57d03f5
@ -272,10 +272,7 @@ config FB_FM2
|
||||
config FB_ARC
|
||||
tristate "Arc Monochrome LCD board support"
|
||||
depends on FB && (X86 || COMPILE_TEST)
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select FB_SYS_FOPS
|
||||
select FB_SYSMEM_HELPERS_DEFERRED
|
||||
help
|
||||
This enables support for the Arc Monochrome LCD board. The board
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
@ -436,76 +403,48 @@ static int arcfb_ioctl(struct fb_info *info,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
static void arcfb_damage_range(struct fb_info *info, off_t off, size_t len)
|
||||
{
|
||||
/* modded from epson 1355 */
|
||||
struct arcfb_par *par = info->par;
|
||||
unsigned int xres = info->var.xres;
|
||||
unsigned int bitppos, startpos, endpos, bitcount;
|
||||
unsigned int x, y, width, height;
|
||||
|
||||
unsigned long p;
|
||||
int err;
|
||||
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);
|
||||
endpos = ceilXres((bitppos + (count*8)), xres);
|
||||
endpos = ceilXres((bitppos + (len * 8)), xres);
|
||||
bitcount = endpos - startpos;
|
||||
|
||||
x = startpos % xres;
|
||||
y = startpos / xres;
|
||||
w = xres;
|
||||
h = bitcount / xres;
|
||||
arcfb_lcd_update(par, x, y, w, h);
|
||||
width = xres;
|
||||
height = bitcount / xres;
|
||||
|
||||
if (count)
|
||||
return count;
|
||||
return err;
|
||||
arcfb_lcd_update(par, x, y, width, height);
|
||||
}
|
||||
|
||||
static void arcfb_damage_area(struct fb_info *info, u32 x, u32 y,
|
||||
u32 width, u32 height)
|
||||
{
|
||||
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 = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_open = arcfb_open,
|
||||
.fb_read = fb_sys_read,
|
||||
.fb_write = arcfb_write,
|
||||
__FB_DEFAULT_DEFERRED_OPS_RDWR(arcfb),
|
||||
.fb_release = arcfb_release,
|
||||
.fb_pan_display = arcfb_pan_display,
|
||||
.fb_fillrect = arcfb_fillrect,
|
||||
.fb_copyarea = arcfb_copyarea,
|
||||
.fb_imageblit = arcfb_imageblit,
|
||||
__FB_DEFAULT_DEFERRED_OPS_DRAW(arcfb),
|
||||
.fb_ioctl = arcfb_ioctl,
|
||||
// .fb_mmap reqires deferred I/O
|
||||
};
|
||||
|
||||
static int arcfb_probe(struct platform_device *dev)
|
||||
|
Loading…
Reference in New Issue
Block a user