summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/kyro/fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/kyro/fbdev.c')
-rw-r--r--drivers/video/fbdev/kyro/fbdev.c56
1 files changed, 37 insertions, 19 deletions
diff --git a/drivers/video/fbdev/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index f77478fb3d14..c8b1dfa456a3 100644
--- a/drivers/video/fbdev/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
@@ -9,6 +9,7 @@
* for more details.
*/
+#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -372,6 +373,11 @@ static int kyro_dev_overlay_viewport_set(u32 x, u32 y, u32 ulWidth, u32 ulHeight
/* probably haven't called CreateOverlay yet */
return -EINVAL;
+ if (ulWidth == 0 || ulWidth == 0xffffffff ||
+ ulHeight == 0 || ulHeight == 0xffffffff ||
+ (x < 2 && ulWidth + 2 == 0))
+ return -EINVAL;
+
/* Stop Ramdac Output */
DisableRamdacOutput(deviceInfo.pSTGReg);
@@ -394,6 +400,9 @@ static int kyrofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
struct kyrofb_info *par = info->par;
+ if (!var->pixclock)
+ return -EINVAL;
+
if (var->bits_per_pixel != 16 && var->bits_per_pixel != 32) {
printk(KERN_WARNING "kyrofb: depth not supported: %u\n", var->bits_per_pixel);
return -EINVAL;
@@ -486,6 +495,8 @@ static int kyrofb_set_par(struct fb_info *info)
info->var.hsync_len +
info->var.left_margin)) / 1000;
+ if (!lineclock)
+ return -EINVAL;
/* time for a frame in ns (precision in 32bpp) */
frameclock = lineclock * (info->var.yres +
@@ -633,7 +644,7 @@ static int kyrofb_ioctl(struct fb_info *info,
return 0;
}
-static struct pci_device_id kyrofb_pci_tbl[] = {
+static const struct pci_device_id kyrofb_pci_tbl[] = {
{ PCI_VENDOR_ID_ST, PCI_DEVICE_ID_STG4000,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
@@ -648,15 +659,13 @@ static struct pci_driver kyrofb_pci_driver = {
.remove = kyrofb_remove,
};
-static struct fb_ops kyrofb_ops = {
+static const struct fb_ops kyrofb_ops = {
.owner = THIS_MODULE,
+ FB_DEFAULT_IOMEM_OPS,
.fb_check_var = kyrofb_check_var,
.fb_set_par = kyrofb_set_par,
.fb_setcolreg = kyrofb_setcolreg,
.fb_ioctl = kyrofb_ioctl,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
};
static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -666,7 +675,12 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
unsigned long size;
int err;
- if ((err = pci_enable_device(pdev))) {
+ err = aperture_remove_conflicting_pci_devices(pdev, "kyrofb");
+ if (err)
+ return err;
+
+ err = pcim_enable_device(pdev);
+ if (err) {
printk(KERN_WARNING "kyrofb: Can't enable pdev: %d\n", err);
return err;
}
@@ -675,6 +689,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (!info)
return -ENOMEM;
+ err = pcim_request_all_regions(pdev, "kyrofb");
+ if (err)
+ goto out_free_fb;
+
currentpar = info->par;
kyro_fix.smem_start = pci_resource_start(pdev, 0);
@@ -683,13 +701,15 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
kyro_fix.mmio_len = pci_resource_len(pdev, 1);
currentpar->regbase = deviceInfo.pSTGReg =
- ioremap_nocache(kyro_fix.mmio_start, kyro_fix.mmio_len);
+ devm_ioremap(&pdev->dev, kyro_fix.mmio_start,
+ kyro_fix.mmio_len);
if (!currentpar->regbase)
goto out_free_fb;
- info->screen_base = pci_ioremap_wc_bar(pdev, 0);
+ info->screen_base = devm_ioremap_wc(&pdev->dev, kyro_fix.smem_start,
+ kyro_fix.smem_len);
if (!info->screen_base)
- goto out_unmap_regs;
+ goto out_free_fb;
if (!nomtrr)
currentpar->wc_cookie = arch_phys_wc_add(kyro_fix.smem_start,
@@ -701,7 +721,6 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info->fbops = &kyrofb_ops;
info->fix = kyro_fix;
info->pseudo_palette = currentpar->palette;
- info->flags = FBINFO_DEFAULT;
SetCoreClockPLL(deviceInfo.pSTGReg, pdev);
@@ -722,10 +741,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
info->var.bits_per_pixel);
size *= info->var.yres_virtual;
- fb_memset(info->screen_base, 0, size);
+ fb_memset_io(info->screen_base, 0, size);
if (register_framebuffer(info) < 0)
- goto out_unmap;
+ goto out_free_fb;
fb_info(info, "%s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n",
info->fix.id,
@@ -736,10 +755,6 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
-out_unmap:
- iounmap(info->screen_base);
-out_unmap_regs:
- iounmap(currentpar->regbase);
out_free_fb:
framebuffer_release(info);
@@ -761,9 +776,6 @@ static void kyrofb_remove(struct pci_dev *pdev)
deviceInfo.ulNextFreeVidMem = 0;
deviceInfo.ulOverlayOffset = 0;
- iounmap(info->screen_base);
- iounmap(par->regbase);
-
arch_phys_wc_del(par->wc_cookie);
unregister_framebuffer(info);
@@ -774,7 +786,12 @@ static int __init kyrofb_init(void)
{
#ifndef MODULE
char *option = NULL;
+#endif
+
+ if (fb_modesetting_disabled("kyrofb"))
+ return -ENODEV;
+#ifndef MODULE
if (fb_get_options("kyrofb", &option))
return -ENODEV;
kyrofb_setup(option);
@@ -794,4 +811,5 @@ module_exit(kyrofb_exit);
#endif
MODULE_AUTHOR("STMicroelectronics; Paul Mundt <lethal@linux-sh.org>");
+MODULE_DESCRIPTION("STG4000/Kyro/PowerVR 3 driver");
MODULE_LICENSE("GPL");