summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev/pm2fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/pm2fb.c')
-rw-r--r--drivers/video/fbdev/pm2fb.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index 1a4070f719c2..f34429829b7d 100644
--- a/drivers/video/fbdev/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
@@ -27,6 +27,7 @@
*
*/
+#include <linux/aperture.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
@@ -54,7 +55,7 @@
#define DPRINTK(a, b...) \
printk(KERN_DEBUG "pm2fb: %s: " a, __func__ , ## b)
#else
-#define DPRINTK(a, b...)
+#define DPRINTK(a, b...) no_printk(a, ##b)
#endif
#define PM2_PIXMAP_SIZE (1600 * 4)
@@ -233,10 +234,13 @@ static u32 to3264(u32 timing, int bpp, int is64)
switch (bpp) {
case 24:
timing *= 3;
+ fallthrough;
case 8:
timing >>= 1;
+ fallthrough;
case 16:
timing >>= 1;
+ fallthrough;
case 32:
break;
}
@@ -614,6 +618,11 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
return -EINVAL;
}
+ if (!var->pixclock) {
+ DPRINTK("pixclock is zero\n");
+ return -EINVAL;
+ }
+
if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
DPRINTK("pixclock too high (%ldKHz)\n",
PICOS2KHZ(var->pixclock));
@@ -1481,8 +1490,9 @@ static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
* Frame buffer operations
*/
-static struct fb_ops pm2fb_ops = {
+static const struct fb_ops pm2fb_ops = {
.owner = THIS_MODULE,
+ __FB_DEFAULT_IOMEM_OPS_RDWR,
.fb_check_var = pm2fb_check_var,
.fb_set_par = pm2fb_set_par,
.fb_setcolreg = pm2fb_setcolreg,
@@ -1493,6 +1503,7 @@ static struct fb_ops pm2fb_ops = {
.fb_imageblit = pm2fb_imageblit,
.fb_sync = pm2fb_sync,
.fb_cursor = pm2fb_cursor,
+ __FB_DEFAULT_IOMEM_OPS_MMAP,
};
/*
@@ -1501,12 +1512,10 @@ static struct fb_ops pm2fb_ops = {
/**
- * Device initialisation
- *
- * Initialise and allocate resource for PCI device.
+ * pm2fb_probe - Initialise and allocate resource for PCI device.
*
- * @param pdev PCI device.
- * @param id PCI device ID.
+ * @pdev: PCI device.
+ * @id: PCI device ID.
*/
static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -1515,6 +1524,10 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
int err;
int retval = -ENXIO;
+ err = aperture_remove_conflicting_pci_devices(pdev, "pm2fb");
+ if (err)
+ return err;
+
err = pci_enable_device(pdev);
if (err) {
printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
@@ -1522,8 +1535,10 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
- if (!info)
- return -ENOMEM;
+ if (!info) {
+ err = -ENOMEM;
+ goto err_exit_disable;
+ }
default_par = info->par;
switch (pdev->device) {
@@ -1561,7 +1576,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_exit_neither;
}
default_par->v_regs =
- ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+ ioremap(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
if (!default_par->v_regs) {
printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
pm2fb_fix.id);
@@ -1644,8 +1659,7 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
info->fbops = &pm2fb_ops;
info->fix = pm2fb_fix;
info->pseudo_palette = default_par->palette;
- info->flags = FBINFO_DEFAULT |
- FBINFO_HWACCEL_YPAN |
+ info->flags = FBINFO_HWACCEL_YPAN |
FBINFO_HWACCEL_COPYAREA |
FBINFO_HWACCEL_IMAGEBLIT |
FBINFO_HWACCEL_FILLRECT;
@@ -1704,15 +1718,15 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
err_exit_neither:
framebuffer_release(info);
+ err_exit_disable:
+ pci_disable_device(pdev);
return retval;
}
/**
- * Device removal.
+ * pm2fb_remove - Release all device resources.
*
- * Release all device resources.
- *
- * @param pdev PCI device to clean up.
+ * @pdev: PCI device to clean up.
*/
static void pm2fb_remove(struct pci_dev *pdev)
{
@@ -1730,9 +1744,10 @@ static void pm2fb_remove(struct pci_dev *pdev)
fb_dealloc_cmap(&info->cmap);
kfree(info->pixmap.addr);
framebuffer_release(info);
+ pci_disable_device(pdev);
}
-static struct pci_device_id pm2fb_id_table[] = {
+static const struct pci_device_id pm2fb_id_table[] = {
{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
@@ -1753,7 +1768,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
#ifndef MODULE
-/**
+/*
* Parse user specified options.
*
* This is, comma-separated options following `video=pm2fb:'.
@@ -1790,7 +1805,12 @@ static int __init pm2fb_init(void)
{
#ifndef MODULE
char *option = NULL;
+#endif
+ if (fb_modesetting_disabled("pm2fb"))
+ return -ENODEV;
+
+#ifndef MODULE
if (fb_get_options("pm2fb", &option))
return -ENODEV;
pm2fb_setup(option);