Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / video / imsttfb.c
index c4a07f2..5715b8a 100644 (file)
  *  more details.
  */
 
-#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/vmalloc.h>
 #include <linux/delay.h>
@@ -228,7 +226,7 @@ struct initvalues {
        __u8 addr, value;
 };
 
-static struct initvalues ibm_initregs[] __initdata = {
+static struct initvalues ibm_initregs[] __devinitdata = {
        { CLKCTL,       0x21 },
        { SYNCCTL,      0x00 },
        { HSYNCPOS,     0x00 },
@@ -275,7 +273,7 @@ static struct initvalues ibm_initregs[] __initdata = {
        { KEYCTL,       0x00 }
 };
 
-static struct initvalues tvp_initregs[] __initdata = {
+static struct initvalues tvp_initregs[] __devinitdata = {
        { TVPIRICC,     0x00 },
        { TVPIRBRC,     0xe4 },
        { TVPIRLAC,     0x06 },
@@ -319,10 +317,11 @@ struct imstt_regvals {
 
 struct imstt_par {
        struct imstt_regvals init;
-       __u32 *dc_regs;
+       __u32 __iomem *dc_regs;
        unsigned long cmap_regs_phys;
        __u8 *cmap_regs;
        __u32 ramdac;
+       __u32 palette[16];
 };
  
 enum {
@@ -338,7 +337,7 @@ enum {
 static int inverse = 0;
 static char fontname[40] __initdata = { 0 };
 #if defined(CONFIG_PPC)
-static signed char init_vmode __initdata = -1, init_cmode __initdata = -1;
+static signed char init_vmode __devinitdata = -1, init_cmode __devinitdata = -1;
 #endif
 
 static struct imstt_regvals tvp_reg_init_2 = {
@@ -406,19 +405,19 @@ static void imsttfb_remove(struct pci_dev *pdev);
 /*
  * Register access
  */
-static inline u32 read_reg_le32(volatile u32 *base, int regindex)
+static inline u32 read_reg_le32(volatile u32 __iomem *base, int regindex)
 {
 #ifdef __powerpc__
-       return in_le32((volatile u32 *) (base + regindex));
+       return in_le32(base + regindex);
 #else
        return readl(base + regindex);
 #endif
 }
 
-static inline void write_reg_le32(volatile u32 *base, int regindex, u32 val)
+static inline void write_reg_le32(volatile u32 __iomem *base, int regindex, u32 val)
 {
 #ifdef __powerpc__
-       out_le32((volatile u32 *) (base + regindex), val);
+       out_le32(base + regindex, val);
 #else
        writel(val, base + regindex);
 #endif
@@ -439,9 +438,9 @@ getclkMHz(struct imstt_par *par)
 static void
 setclkMHz(struct imstt_par *par, __u32 MHz)
 {
-       __u32 clk_m, clk_n, clk_p, x, stage, spilled;
+       __u32 clk_m, clk_n, x, stage, spilled;
 
-       clk_m = clk_n = clk_p = 0;
+       clk_m = clk_n = 0;
        stage = spilled = 0;
        for (;;) {
                switch (stage) {
@@ -452,7 +451,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz)
                                clk_n++;
                                break;
                }
-               x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));
+               x = 20 * (clk_m + 1) / (clk_n + 1);
                if (x == MHz)
                        break;
                if (x > MHz) {
@@ -465,7 +464,7 @@ setclkMHz(struct imstt_par *par, __u32 MHz)
 
        par->init.pclk_m = clk_m;
        par->init.pclk_n = clk_n;
-       par->init.pclk_p = clk_p;
+       par->init.pclk_p = 0;
 }
 
 static struct imstt_regvals *
@@ -657,7 +656,7 @@ set_imstt_regvals_tvp (struct imstt_par *par, u_int bpp)
 static void
 set_imstt_regvals (struct fb_info *info, u_int bpp)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        struct imstt_regvals *init = &par->init;
        __u32 ctl, pitch, byteswap, scr;
 
@@ -749,7 +748,7 @@ set_imstt_regvals (struct fb_info *info, u_int bpp)
 static inline void
 set_offset (struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 off = var->yoffset * (info->fix.line_length >> 3)
                    + ((var->xoffset * (var->bits_per_pixel >> 3)) >> 3);
        write_reg_le32(par->dc_regs, SSR, off);
@@ -863,7 +862,7 @@ imsttfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 static int
 imsttfb_set_par(struct fb_info *info) 
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
                
        if (!compute_imstt_regvals(par, info->var.xres, info->var.yres))
                return -EINVAL;
@@ -881,7 +880,7 @@ static int
 imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
                   u_int transp, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        u_int bpp = info->var.bits_per_pixel;
 
        if (regno > 255)
@@ -905,14 +904,17 @@ imsttfb_setcolreg (u_int regno, u_int red, u_int green, u_int blue,
        if (regno < 16)
                switch (bpp) {
                        case 16:
-                               ((u16 *)info->pseudo_palette)[regno] = (regno << (info->var.green.length == 5 ? 10 : 11)) | (regno << 5) | regno;
+                               par->palette[regno] =
+                                       (regno << (info->var.green.length ==
+                                       5 ? 10 : 11)) | (regno << 5) | regno;
                                break;
                        case 24:
-                               ((u32 *)info->pseudo_palette)[regno] = (regno << 16) | (regno << 8) | regno;
+                               par->palette[regno] =
+                                       (regno << 16) | (regno << 8) | regno;
                                break;
                        case 32: {
                                int i = (regno << 8) | regno;
-                               ((u32 *)info->pseudo_palette)[regno] = (i << 16) | i;
+                               par->palette[regno] = (i << 16) |i;
                                break;
                        }
                }
@@ -935,14 +937,14 @@ imsttfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 static int 
 imsttfb_blank(int blank, struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 ctrl;
 
        ctrl = read_reg_le32(par->dc_regs, STGCTL);
        if (blank > 0) {
-               switch (blank - 1) {
-               case VESA_NO_BLANKING:
-               case VESA_POWERDOWN:
+               switch (blank) {
+               case FB_BLANK_NORMAL:
+               case FB_BLANK_POWERDOWN:
                        ctrl &= ~0x00000380;
                        if (par->ramdac == IBM) {
                                par->cmap_regs[PIDXHI] = 0;             eieio();
@@ -958,10 +960,10 @@ imsttfb_blank(int blank, struct fb_info *info)
                                par->cmap_regs[PIDXDATA] = 0xc0;
                        }
                        break;
-               case VESA_VSYNC_SUSPEND:
+               case FB_BLANK_VSYNC_SUSPEND:
                        ctrl &= ~0x00000020;
                        break;
-               case VESA_HSYNC_SUSPEND:
+               case FB_BLANK_HSYNC_SUSPEND:
                        ctrl &= ~0x00000010;
                        break;
                }
@@ -989,7 +991,7 @@ imsttfb_blank(int blank, struct fb_info *info)
 static void
 imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 { 
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 Bpp, line_pitch, bgc, dx, dy, width, height;
 
        bgc = rect->color;
@@ -1033,7 +1035,7 @@ imsttfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 static void
 imsttfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 Bpp, line_pitch, fb_offset_old, fb_offset_new, sp, dp_octl;
        __u32 cnt, bltctl, sx, sy, dx, dy, height, width;
 
@@ -1195,7 +1197,7 @@ imstt_set_cursor(struct imstt_par *par, struct fb_image *d, int on)
 static int 
 imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
         u32 flags = cursor->set, fg, bg, xx, yy;
 
        if (cursor->dest == NULL && cursor->rop == ROP_XOR)
@@ -1263,10 +1265,9 @@ imsttfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 #define FBIMSTT_GETIDXREG      0x545406
 
 static int
-imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-             u_long arg, struct fb_info *info)
+imsttfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        void __user *argp = (void __user *)arg;
        __u32 reg[2];
        __u8 idx[2];
@@ -1287,12 +1288,12 @@ imsttfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
                case FBIMSTT_SETCMAPREG:
                        if (copy_from_user(reg, argp, 8) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
-                       write_reg_le32(((u_int *)par->cmap_regs), reg[0], reg[1]);
+                       write_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0], reg[1]);
                        return 0;
                case FBIMSTT_GETCMAPREG:
                        if (copy_from_user(reg, argp, 4) || reg[0] > (0x1000 - sizeof(reg[0])) / sizeof(reg[0]))
                                return -EFAULT;
-                       reg[1] = read_reg_le32(((u_int *)par->cmap_regs), reg[0]);
+                       reg[1] = read_reg_le32(((u_int __iomem *)par->cmap_regs), reg[0]);
                        if (copy_to_user((void __user *)(arg + 4), &reg[1], 4))
                                return -EFAULT;
                        return 0;
@@ -1344,14 +1345,13 @@ static struct fb_ops imsttfb_ops = {
        .fb_fillrect    = imsttfb_fillrect,
        .fb_copyarea    = imsttfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = imsttfb_ioctl,
 };
 
-static void __init 
+static void __devinit
 init_imstt(struct fb_info *info)
 {
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        __u32 i, tmp, *ip, *end;
 
        tmp = read_reg_le32(par->dc_regs, PRC);
@@ -1370,18 +1370,24 @@ init_imstt(struct fb_info *info)
        write_reg_le32(par->dc_regs, STGCTL, tmp & ~0x1);
        write_reg_le32(par->dc_regs, SSR, 0);
 
-       /* set default values for DAC registers */ 
+       /* set default values for DAC registers */
        if (par->ramdac == IBM) {
-               par->cmap_regs[PPMASK] = 0xff;  eieio();
-               par->cmap_regs[PIDXHI] = 0;     eieio();
-               for (i = 0; i < sizeof(ibm_initregs) / sizeof(*ibm_initregs); i++) {
-                       par->cmap_regs[PIDXLO] = ibm_initregs[i].addr;  eieio();
-                       par->cmap_regs[PIDXDATA] = ibm_initregs[i].value;       eieio();
+               par->cmap_regs[PPMASK] = 0xff;
+               eieio();
+               par->cmap_regs[PIDXHI] = 0;
+               eieio();
+               for (i = 0; i < ARRAY_SIZE(ibm_initregs); i++) {
+                       par->cmap_regs[PIDXLO] = ibm_initregs[i].addr;
+                       eieio();
+                       par->cmap_regs[PIDXDATA] = ibm_initregs[i].value;
+                       eieio();
                }
        } else {
-               for (i = 0; i < sizeof(tvp_initregs) / sizeof(*tvp_initregs); i++) {
-                       par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;        eieio();
-                       par->cmap_regs[TVPIDATA] = tvp_initregs[i].value;       eieio();
+               for (i = 0; i < ARRAY_SIZE(tvp_initregs); i++) {
+                       par->cmap_regs[TVPADDRW] = tvp_initregs[i].addr;
+                       eieio();
+                       par->cmap_regs[TVPIDATA] = tvp_initregs[i].value;
+                       eieio();
                }
        }
 
@@ -1414,7 +1420,7 @@ init_imstt(struct fb_info *info)
        if ((info->var.xres * info->var.yres) * (info->var.bits_per_pixel >> 3) > info->fix.smem_len
            || !(compute_imstt_regvals(par, info->var.xres, info->var.yres))) {
                printk("imsttfb: %ux%ux%u not supported\n", info->var.xres, info->var.yres, info->var.bits_per_pixel);
-               kfree(info);
+               framebuffer_release(info);
                return;
        }
 
@@ -1450,7 +1456,7 @@ init_imstt(struct fb_info *info)
        fb_alloc_cmap(&info->cmap, 0, 0);
 
        if (register_framebuffer(info) < 0) {
-               kfree(info);
+               framebuffer_release(info);
                return;
        }
 
@@ -1475,26 +1481,21 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_ERR "imsttfb: no OF node for pci device\n");
 #endif /* CONFIG_PPC_OF */
 
-       size = sizeof(struct fb_info) + sizeof(struct imstt_par) +
-               sizeof(u32) * 16;
-
-       info = kmalloc(size, GFP_KERNEL);
+       info = framebuffer_alloc(sizeof(struct imstt_par), &pdev->dev);
 
        if (!info) {
                printk(KERN_ERR "imsttfb: Can't allocate memory\n");
                return -ENOMEM;
        }
 
-       memset(info, 0, size);
-
-       par = (struct imstt_par *) (info + 1);
+       par = info->par;
 
        addr = pci_resource_start (pdev, 0);
        size = pci_resource_len (pdev, 0);
 
        if (!request_mem_region(addr, size, "imsttfb")) {
                printk(KERN_ERR "imsttfb: Can't reserve memory region\n");
-               kfree(info);
+               framebuffer_release(info);
                return -ENODEV;
        }
 
@@ -1513,17 +1514,19 @@ imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                default:
                        printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
                                         "contact maintainer.\n", pdev->device);
+                       release_mem_region(addr, size);
+                       framebuffer_release(info);
                        return -ENODEV;
        }
 
        info->fix.smem_start = addr;
-       info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000);
+       info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ?
+                                           0x400000 : 0x800000);
        info->fix.mmio_start = addr + 0x800000;
-       par->dc_regs = (__u32 *)ioremap(addr + 0x800000, 0x1000);
+       par->dc_regs = ioremap(addr + 0x800000, 0x1000);
        par->cmap_regs_phys = addr + 0x840000;
        par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
-       info->par = par;
-       info->pseudo_palette = (void *) (par + 1);
+       info->pseudo_palette = par->palette;
        init_imstt(info);
 
        pci_set_drvdata(pdev, info);
@@ -1534,7 +1537,7 @@ static void __devexit
 imsttfb_remove(struct pci_dev *pdev)
 {
        struct fb_info *info = pci_get_drvdata(pdev);
-       struct imstt_par *par = (struct imstt_par *) info->par;
+       struct imstt_par *par = info->par;
        int size = pci_resource_len(pdev, 0);
 
        unregister_framebuffer(info);
@@ -1542,11 +1545,11 @@ imsttfb_remove(struct pci_dev *pdev)
        iounmap(par->dc_regs);
        iounmap(info->screen_base);
        release_mem_region(info->fix.smem_start, size);
-       kfree(info);
+       framebuffer_release(info);
 }
 
 #ifndef MODULE
-int __init 
+static int __init
 imsttfb_setup(char *options)
 {
        char *this_opt;
@@ -1600,7 +1603,7 @@ imsttfb_setup(char *options)
 
 #endif /* MODULE */
 
-int __init imsttfb_init(void)
+static int __init imsttfb_init(void)
 {
 #ifndef MODULE
        char *option = NULL;
@@ -1610,7 +1613,7 @@ int __init imsttfb_init(void)
 
        imsttfb_setup(option);
 #endif
-       return pci_module_init(&imsttfb_pci_driver);
+       return pci_register_driver(&imsttfb_pci_driver);
 }
  
 static void __exit imsttfb_exit(void)
@@ -1618,9 +1621,8 @@ static void __exit imsttfb_exit(void)
        pci_unregister_driver(&imsttfb_pci_driver);
 }
 
-#ifdef MODULE
 MODULE_LICENSE("GPL");
-#endif
+
 module_init(imsttfb_init);
 module_exit(imsttfb_exit);