diff options
Diffstat (limited to 'drivers/video/fbdev/amifb.c')
| -rw-r--r-- | drivers/video/fbdev/amifb.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c index 758457026694..1116a0789ca4 100644 --- a/drivers/video/fbdev/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -575,6 +575,12 @@ static u_short maxfmode, chipset; #define downx(x, v) ((v) & -(x)) #define modx(x, v) ((v) & ((x) - 1)) +/* + * FIXME: Use C variants of the code marked with #ifdef __mc68000__ + * in the driver. It shouldn't negatively affect the performance and + * is required for APUS support (once it is re-added to the kernel). + * Needs to be tested on the hardware though.. + */ /* if x1 is not a constant, this macro won't make real sense :-) */ #ifdef __mc68000__ #define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \ @@ -681,7 +687,7 @@ struct fb_var_cursorinfo { __u16 height; __u16 xspot; __u16 yspot; - __u8 data[1]; /* field with [height][width] */ + DECLARE_FLEX_ARRAY(__u8, data); /* field with [height][width] */ }; struct fb_cursorstate { @@ -1855,8 +1861,6 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, var->yspot = par->crsr.spot_y; if (size > var->height * var->width) return -ENAMETOOLONG; - if (!access_ok(data, size)) - return -EFAULT; delta = 1 << par->crsr.fmode; lspr = lofsprite + (delta << 1); if (par->bplcon0 & BPC0_LACE) @@ -1886,6 +1890,7 @@ static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, | ((datawords >> 15) & 1)); datawords <<= 1; #endif + /* FIXME: check the return value + test the change */ put_user(color, data++); } if (bits > 0) { @@ -1935,8 +1940,6 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, return -EINVAL; if (!var->height) return -EINVAL; - if (!access_ok(data, var->width * var->height)) - return -EFAULT; delta = 1 << fmode; lofsprite = shfsprite = (u_short *)spritememory; lspr = lofsprite + (delta << 1); @@ -1956,6 +1959,7 @@ static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, bits = 16; words = delta; datawords = 0; for (width = (short)var->width - 1; width >= 0; width--) { unsigned long tdata = 0; + /* FIXME: check the return value + test the change */ get_user(tdata, data); data++; #ifdef __mc68000__ @@ -2423,7 +2427,7 @@ static int amifb_set_par(struct fb_info *info) info->fix.ywrapstep = 1; info->fix.xpanstep = 0; info->fix.ypanstep = 0; - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YWRAP | + info->flags = FBINFO_HWACCEL_YWRAP | FBINFO_READS_FAST; /* override SCROLL_REDRAW */ } else { info->fix.ywrapstep = 0; @@ -2432,7 +2436,7 @@ static int amifb_set_par(struct fb_info *info) else info->fix.xpanstep = 16 << maxfmode; info->fix.ypanstep = 1; - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; + info->flags = FBINFO_HWACCEL_YPAN; } return 0; } @@ -2536,27 +2540,16 @@ static int amifb_blank(int blank, struct fb_info *info) static int amifb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset < 0 || - var->yoffset >= info->var.yres_virtual || var->xoffset) - return -EINVAL; - } else { + if (!(var->vmode & FB_VMODE_YWRAP)) { /* * TODO: There will be problems when xpan!=1, so some columns * on the right side will never be seen */ if (var->xoffset + info->var.xres > - upx(16 << maxfmode, info->var.xres_virtual) || - var->yoffset + info->var.yres > info->var.yres_virtual) + upx(16 << maxfmode, info->var.xres_virtual)) return -EINVAL; } ami_pan_var(var, info); - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; return 0; } @@ -3493,8 +3486,9 @@ static irqreturn_t amifb_interrupt(int irq, void *dev_id) } -static struct fb_ops amifb_ops = { +static const struct fb_ops amifb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = amifb_check_var, .fb_set_par = amifb_set_par, .fb_setcolreg = amifb_setcolreg, @@ -3504,6 +3498,7 @@ static struct fb_ops amifb_ops = { .fb_copyarea = amifb_copyarea, .fb_imageblit = amifb_imageblit, .fb_ioctl = amifb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; @@ -3554,10 +3549,8 @@ static int __init amifb_probe(struct platform_device *pdev) custom.dmacon = DMAF_ALL | DMAF_MASTER; info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev); - if (!info) { - dev_err(&pdev->dev, "framebuffer_alloc failed\n"); + if (!info) return -ENOMEM; - } strcpy(info->fix.id, "Amiga "); info->fix.visual = FB_VISUAL_PSEUDOCOLOR; @@ -3669,7 +3662,6 @@ default_chipset: } info->fbops = &amifb_ops; - info->flags = FBINFO_DEFAULT; info->device = &pdev->dev; if (!fb_find_mode(&info->var, info, mode_option, ami_modedb, @@ -3734,7 +3726,7 @@ default_chipset: if (err) goto free_irq; - dev_set_drvdata(&pdev->dev, info); + platform_set_drvdata(pdev, info); err = register_framebuffer(info); if (err) @@ -3760,9 +3752,9 @@ release: } -static int __exit amifb_remove(struct platform_device *pdev) +static void __exit amifb_remove(struct platform_device *pdev) { - struct fb_info *info = dev_get_drvdata(&pdev->dev); + struct fb_info *info = platform_get_drvdata(pdev); unregister_framebuffer(info); fb_dealloc_cmap(&info->cmap); @@ -3773,17 +3765,23 @@ static int __exit amifb_remove(struct platform_device *pdev) chipfree(); framebuffer_release(info); amifb_video_off(); - return 0; } -static struct platform_driver amifb_driver = { +/* + * amifb_remove() lives in .exit.text. For drivers registered via + * module_platform_driver_probe() this ok because they cannot get unboud at + * runtime. The driver needs to be marked with __refdata, otherwise modpost + * triggers a section mismatch warning. + */ +static struct platform_driver amifb_driver __refdata = { .remove = __exit_p(amifb_remove), - .driver = { + .driver = { .name = "amiga-video", }, }; module_platform_driver_probe(amifb_driver, amifb_probe); +MODULE_DESCRIPTION("Amiga builtin chipset frame buffer driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:amiga-video"); |
