fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / video / cirrusfb.c
index 617f63e..2c4bc62 100644 (file)
 
 #define CIRRUSFB_VERSION "2.0-pre2"
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
@@ -60,8 +58,8 @@
 #include <asm/amigahw.h>
 #endif
 #ifdef CONFIG_PPC_PREP
-#include <asm/processor.h>
-#define isPReP (_machine == _MACH_prep)
+#include <asm/machdep.h>
+#define isPReP (machine_is(prep))
 #else
 #define isPReP 0
 #endif
@@ -275,20 +273,20 @@ static const struct cirrusfb_board_info_rec {
 
 #ifdef CONFIG_PCI
 #define CHIP(id, btype) \
-       { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
+       { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
 
 static struct pci_device_id cirrusfb_pci_table[] = {
-       CHIP( CIRRUS_5436,      BT_ALPINE ),
-       CHIP( CIRRUS_5434_8,    BT_ALPINE ),
-       CHIP( CIRRUS_5434_4,    BT_ALPINE ),
-       CHIP( CIRRUS_5430,      BT_ALPINE ), /* GD-5440 has identical id */
-       CHIP( CIRRUS_7543,      BT_ALPINE ),
-       CHIP( CIRRUS_7548,      BT_ALPINE ),
-       CHIP( CIRRUS_5480,      BT_GD5480 ), /* MacPicasso probably */
-       CHIP( CIRRUS_5446,      BT_PICASSO4 ), /* Picasso 4 is a GD5446 */
-       CHIP( CIRRUS_5462,      BT_LAGUNA ), /* CL Laguna */
-       CHIP( CIRRUS_5464,      BT_LAGUNA ), /* CL Laguna 3D */
-       CHIP( CIRRUS_5465,      BT_LAGUNA ), /* CL Laguna 3DA*/
+       CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */
+       CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ),
+       CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */
+       CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/
        { 0, }
 };
 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -404,7 +402,7 @@ struct cirrusfb_info {
        struct cirrusfb_regs currentmode;
        int blank_mode;
 
-       u32     pseudo_palette[17];
+       u32     pseudo_palette[16];
        struct { u8 red, green, blue, pad; } palette[256];
 
 #ifdef CONFIG_ZORRO
@@ -515,23 +513,25 @@ static const struct {
 
 
 /*--- Interface used by the world ------------------------------------------*/
-int cirrusfb_init (void);
-int cirrusfb_setup (char *options);
-
-int cirrusfb_open (struct fb_info *info, int user);
-int cirrusfb_release (struct fb_info *info, int user);
-int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                       unsigned blue, unsigned transp,
-                       struct fb_info *info);
-int cirrusfb_check_var (struct fb_var_screeninfo *var,
-                       struct fb_info *info);
-int cirrusfb_set_par (struct fb_info *info);
-int cirrusfb_pan_display (struct fb_var_screeninfo *var,
-                         struct fb_info *info);
-int cirrusfb_blank (int blank_mode, struct fb_info *info);
-void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
-void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
-void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
+static int cirrusfb_init (void);
+#ifndef MODULE
+static int cirrusfb_setup (char *options);
+#endif
+
+static int cirrusfb_open (struct fb_info *info, int user);
+static int cirrusfb_release (struct fb_info *info, int user);
+static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+                              unsigned blue, unsigned transp,
+                              struct fb_info *info);
+static int cirrusfb_check_var (struct fb_var_screeninfo *var,
+                              struct fb_info *info);
+static int cirrusfb_set_par (struct fb_info *info);
+static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
+                                struct fb_info *info);
+static int cirrusfb_blank (int blank_mode, struct fb_info *info);
+static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
+static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
+static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
 
 /* function table of the above functions */
 static struct fb_ops cirrusfb_ops = {
@@ -546,7 +546,6 @@ static struct fb_ops cirrusfb_ops = {
        .fb_fillrect    = cirrusfb_fillrect,
        .fb_copyarea    = cirrusfb_copyarea,
        .fb_imageblit   = cirrusfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*--- Hardware Specific Routines -------------------------------------------*/
@@ -600,7 +599,7 @@ static void cirrusfb_dbg_print_byte (const char *name, unsigned char val);
 static int opencount = 0;
 
 /*--- Open /dev/fbx ---------------------------------------------------------*/
-int cirrusfb_open (struct fb_info *info, int user)
+static int cirrusfb_open (struct fb_info *info, int user)
 {
        if (opencount++ == 0)
                switch_monitor (info->par, 1);
@@ -608,7 +607,7 @@ int cirrusfb_open (struct fb_info *info, int user)
 }
 
 /*--- Close /dev/fbx --------------------------------------------------------*/
-int cirrusfb_release (struct fb_info *info, int user)
+static int cirrusfb_release (struct fb_info *info, int user)
 {
        if (--opencount == 0)
                switch_monitor (info->par, 0);
@@ -660,8 +659,8 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
        return mclk;
 }
 
-int cirrusfb_check_var(struct fb_var_screeninfo *var,
-                      struct fb_info *info)
+static int cirrusfb_check_var(struct fb_var_screeninfo *var,
+                             struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
        int nom, den;           /* translyting from pixels->bytes */
@@ -1573,15 +1572,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
 
 /* for some reason incomprehensible to me, cirrusfb requires that you write
  * the registers twice for the settings to take..grr. -dte */
-int cirrusfb_set_par (struct fb_info *info)
+static int cirrusfb_set_par (struct fb_info *info)
 {
        cirrusfb_set_par_foo (info);
        return cirrusfb_set_par_foo (info);
 }
 
-int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
-                       unsigned blue, unsigned transp,
-                       struct fb_info *info)
+static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+                              unsigned blue, unsigned transp,
+                              struct fb_info *info)
 {
        struct cirrusfb_info *cinfo = info->par;
 
@@ -1602,14 +1601,14 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
 
                switch (info->var.bits_per_pixel) {
                        case 8:
-                               ((u8*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                        case 16:
-                               ((u16*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                        case 24:
                        case 32:
-                               ((u32*)(info->pseudo_palette))[regno] = v;
+                               cinfo->pseudo_palette[regno] = v;
                                break;
                }
                return 0;
@@ -1632,8 +1631,8 @@ int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
 
        performs display panning - provided hardware permits this
 **************************************************************************/
-int cirrusfb_pan_display (struct fb_var_screeninfo *var,
-                         struct fb_info *info)
+static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
+                                struct fb_info *info)
 {
        int xoffset = 0;
        int yoffset = 0;
@@ -1702,7 +1701,7 @@ int cirrusfb_pan_display (struct fb_var_screeninfo *var,
 }
 
 
-int cirrusfb_blank (int blank_mode, struct fb_info *info)
+static int cirrusfb_blank (int blank_mode, struct fb_info *info)
 {
        /*
         *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL
@@ -2019,24 +2018,27 @@ static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo,
                                   const struct fb_fillrect *region)
 {
        int m; /* bytes per pixel */
+       u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
+               cinfo->pseudo_palette[region->color] : region->color;
+
        if(cinfo->info->var.bits_per_pixel == 1) {
                cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
                                  region->dx / 8, region->dy,
                                  region->width / 8, region->height,
-                                 region->color,
+                                 color,
                                  cinfo->currentmode.line_length);
        } else {
                m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
                cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
                                  region->dx * m, region->dy,
                                  region->width * m, region->height,
-                                 region->color,
+                                 color,
                                  cinfo->currentmode.line_length);
        }
        return;
 }
 
-void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
+static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
 {
        struct cirrusfb_info *cinfo = info->par;
        struct fb_fillrect modded;
@@ -2086,7 +2088,7 @@ static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo,
 }
 
 
-void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
+static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
        struct cirrusfb_info *cinfo = info->par;
        struct fb_copyarea modded;
@@ -2121,7 +2123,7 @@ void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
        cirrusfb_prim_copyarea(cinfo, &modded);
 }
 
-void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
+static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
        struct cirrusfb_info *cinfo = info->par;
 
@@ -2223,7 +2225,6 @@ static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
                release_region(0x3C0, 32);
        pci_release_regions(pdev);
        framebuffer_release(cinfo->info);
-       pci_disable_device(pdev);
 }
 #endif /* CONFIG_PCI */
 
@@ -2441,7 +2442,10 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
        printk ("Cirrus Logic chipset on PCI bus\n");
        pci_set_drvdata(pdev, info);
 
-       return cirrusfb_register(cinfo);
+       ret = cirrusfb_register(cinfo);
+       if (ret)
+               iounmap(cinfo->fbmem);
+       return ret;
 
 err_release_legacy:
        if (release_io_ports)
@@ -2454,12 +2458,11 @@ err_release_regions:
 err_release_fb:
        framebuffer_release(info);
 err_disable:
-       pci_disable_device(pdev);
 err_out:
        return ret;
 }
 
-void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
+static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
        DPRINTK ("ENTER\n");
@@ -2574,7 +2577,15 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
        zorro_set_drvdata(z, info);
 
-       return cirrusfb_register(cinfo);
+       ret = cirrusfb_register(cinfo);
+       if (ret) {
+               if (btype == BT_PICASSO4) {
+                       iounmap(cinfo->fbmem);
+                       iounmap(cinfo->regbase - 0x600000);
+               } else if (board_addr > 0x01000000)
+                       iounmap(cinfo->fbmem);
+       }
+       return ret;
 
 err_unmap_regbase:
        /* Parental advisory: explicit hack */
@@ -2605,7 +2616,7 @@ static struct zorro_driver cirrusfb_zorro_driver = {
 };
 #endif /* CONFIG_ZORRO */
 
-int __init cirrusfb_init(void)
+static int __init cirrusfb_init(void)
 {
        int error = 0;
 
@@ -2618,10 +2629,10 @@ int __init cirrusfb_init(void)
 #endif
 
 #ifdef CONFIG_ZORRO
-       error |= zorro_module_init(&cirrusfb_zorro_driver);
+       error |= zorro_register_driver(&cirrusfb_zorro_driver);
 #endif
 #ifdef CONFIG_PCI
-       error |= pci_module_init(&cirrusfb_pci_driver);
+       error |= pci_register_driver(&cirrusfb_pci_driver);
 #endif
        return error;
 }
@@ -2629,7 +2640,7 @@ int __init cirrusfb_init(void)
 
 
 #ifndef MODULE
-int __init cirrusfb_setup(char *options) {
+static int __init cirrusfb_setup(char *options) {
        char *this_opt, s[32];
        int i;
 
@@ -2664,7 +2675,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
 MODULE_LICENSE("GPL");
 
-void __exit cirrusfb_exit (void)
+static void __exit cirrusfb_exit (void)
 {
 #ifdef CONFIG_PCI
        pci_unregister_driver(&cirrusfb_pci_driver);