X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fimsttfb.c;h=5715b8ad0ddc87ae0c301c3b432df4d268541446;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=c4a07f27c18c4852e94bdba0305b0914b9dfb303;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index c4a07f27c..5715b8ad0 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -16,13 +16,11 @@ * more details. */ -#include #include #include #include #include #include -#include #include #include #include @@ -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), ®[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);