intelfb: support 945GME (as used in ASUS Eee 901)
[safe/jmp/linux-2.6] / drivers / video / ffb.c
index 1d4e835..9dbb964 100644 (file)
 #include <linux/fb.h>
 #include <linux/mm.h>
 #include <linux/timer.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/upa.h>
-#include <asm/prom.h>
-#include <asm/of_device.h>
 #include <asm/fbio.h>
 
 #include "sbuslib.h"
@@ -32,7 +31,6 @@
 static int ffb_setcolreg(unsigned, unsigned, unsigned, unsigned,
                         unsigned, struct fb_info *);
 static int ffb_blank(int, struct fb_info *);
-static void ffb_init_fix(struct fb_info *);
 
 static void ffb_imageblit(struct fb_info *, const struct fb_image *);
 static void ffb_fillrect(struct fb_info *, const struct fb_fillrect *);
@@ -171,17 +169,17 @@ static struct fb_ops ffb_ops = {
 #define FFB_PPC_CS_VAR         0x000002
 #define FFB_PPC_CS_CONST       0x000003
 
-#define FFB_ROP_NEW                  0x83
-#define FFB_ROP_OLD                  0x85
-#define FFB_ROP_NEW_XOR_OLD          0x86
+#define FFB_ROP_NEW            0x83
+#define FFB_ROP_OLD            0x85
+#define FFB_ROP_NEW_XOR_OLD    0x86
 
-#define FFB_UCSR_FIFO_MASK     0x00000fff
-#define FFB_UCSR_FB_BUSY       0x01000000
-#define FFB_UCSR_RP_BUSY       0x02000000
-#define FFB_UCSR_ALL_BUSY      (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
-#define FFB_UCSR_READ_ERR      0x40000000
-#define FFB_UCSR_FIFO_OVFL     0x80000000
-#define FFB_UCSR_ALL_ERRORS    (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
+#define FFB_UCSR_FIFO_MASK     0x00000fff
+#define FFB_UCSR_FB_BUSY       0x01000000
+#define FFB_UCSR_RP_BUSY       0x02000000
+#define FFB_UCSR_ALL_BUSY      (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
+#define FFB_UCSR_READ_ERR      0x40000000
+#define FFB_UCSR_FIFO_OVFL     0x80000000
+#define FFB_UCSR_ALL_ERRORS    (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
 
 struct ffb_fbc {
        /* Next vertex registers */
@@ -197,7 +195,7 @@ struct ffb_fbc {
        u32     ryf;
        u32     rxf;
        u32     xxx3[2];
-       
+
        u32     dmyf;
        u32     dmxf;
        u32     xxx4[2];
@@ -211,13 +209,13 @@ struct ffb_fbc {
        u32     bh;
        u32     bw;
        u32     xxx6[2];
-       
+
        u32     xxx7[32];
-       
+
        /* Setup unit vertex state register */
        u32     suvtx;
        u32     xxx8[63];
-       
+
        /* Control registers */
        u32     ppc;
        u32     wid;
@@ -235,7 +233,7 @@ struct ffb_fbc {
        u32     dcsb;
        u32     dczf;
        u32     dczb;
-       
+
        u32     xxx9;
        u32     blendc;
        u32     blendc1;
@@ -252,7 +250,7 @@ struct ffb_fbc {
        u32     fbcfg1;
        u32     fbcfg2;
        u32     fbcfg3;
-       
+
        u32     ppcfg;
        u32     pick;
        u32     fillmode;
@@ -269,7 +267,7 @@ struct ffb_fbc {
        u32     clip2max;
        u32     clip3min;
        u32     clip3max;
-       
+
        /* New 3dRAM III support regs */
        u32     rawblend2;
        u32     rawpreblend;
@@ -287,7 +285,7 @@ struct ffb_fbc {
        u32     rawcmp;
        u32     rawwac;
        u32     fbramid;
-       
+
        u32     drawop;
        u32     xxx10[2];
        u32     fontlpat;
@@ -302,7 +300,7 @@ struct ffb_fbc {
        u32     stencil;
        u32     stencilctl;
 
-       u32     xxx13[4];       
+       u32     xxx13[4];
        u32     dcss1;
        u32     dcss2;
        u32     dcss3;
@@ -315,17 +313,17 @@ struct ffb_fbc {
        u32     dcd3;
        u32     dcd4;
        u32     xxx15;
-       
+
        u32     pattern[32];
-       
+
        u32     xxx16[256];
-       
+
        u32     devid;
        u32     xxx17[63];
-       
+
        u32     ucsr;
        u32     xxx18[31];
-       
+
        u32     mer;
 };
 
@@ -336,20 +334,20 @@ struct ffb_dac {
        u32     value2;
 };
 
-#define FFB_DAC_UCTRL  0x1001 /* User Control */
-#define  FFB_DAC_UCTRL_MANREV  0x00000f00 /* 4-bit Manufacturing Revision */
-#define  FFB_DAC_UCTRL_MANREV_SHIFT 8
-#define FFB_DAC_TGEN   0x6000 /* Timing Generator */
-#define  FFB_DAC_TGEN_VIDE     0x00000001 /* Video Enable */
-#define FFB_DAC_DID    0x8000 /* Device Identification */
-#define  FFB_DAC_DID_PNUM      0x0ffff000 /* Device Part Number */
-#define  FFB_DAC_DID_PNUM_SHIFT 12
-#define  FFB_DAC_DID_REV       0xf0000000 /* Device Revision */
-#define  FFB_DAC_DID_REV_SHIFT 28
+#define FFB_DAC_UCTRL          0x1001 /* User Control */
+#define FFB_DAC_UCTRL_MANREV   0x00000f00 /* 4-bit Manufacturing Revision */
+#define FFB_DAC_UCTRL_MANREV_SHIFT 8
+#define FFB_DAC_TGEN           0x6000 /* Timing Generator */
+#define FFB_DAC_TGEN_VIDE      0x00000001 /* Video Enable */
+#define FFB_DAC_DID            0x8000 /* Device Identification */
+#define FFB_DAC_DID_PNUM       0x0ffff000 /* Device Part Number */
+#define FFB_DAC_DID_PNUM_SHIFT 12
+#define FFB_DAC_DID_REV                0xf0000000 /* Device Revision */
+#define FFB_DAC_DID_REV_SHIFT  28
 
 #define FFB_DAC_CUR_CTRL       0x100
-#define  FFB_DAC_CUR_CTRL_P0   0x00000001
-#define  FFB_DAC_CUR_CTRL_P1   0x00000002
+#define FFB_DAC_CUR_CTRL_P0    0x00000001
+#define FFB_DAC_CUR_CTRL_P1    0x00000002
 
 struct ffb_par {
        spinlock_t              lock;
@@ -371,6 +369,8 @@ struct ffb_par {
        unsigned long           fbsize;
 
        int                     board_type;
+
+       u32                     pseudo_palette[16];
 };
 
 static void FFBFifo(struct ffb_par *par, int n)
@@ -380,7 +380,9 @@ static void FFBFifo(struct ffb_par *par, int n)
 
        if (cache - n < 0) {
                fbc = par->fbc;
-               do {    cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK) - 8;
+               do {
+                       cache = (upa_readl(&fbc->ucsr) & FFB_UCSR_FIFO_MASK);
+                       cache -= 8;
                } while (cache - n < 0);
        }
        par->fifo_cache = cache - n;
@@ -399,12 +401,12 @@ static void FFBWait(struct ffb_par *par)
                        upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
                }
                udelay(10);
-       } while(--limit > 0);
+       } while (--limit > 0);
 }
 
 static int ffb_sync(struct fb_info *p)
 {
-       struct ffb_par *par = (struct ffb_par *) p->par;
+       struct ffb_par *par = (struct ffb_par *)p->par;
 
        FFBWait(par);
        return 0;
@@ -429,8 +431,8 @@ static void ffb_switch_from_graph(struct ffb_par *par)
        FFBWait(par);
        par->fifo_cache = 0;
        FFBFifo(par, 7);
-       upa_writel(FFB_PPC_VCE_DISABLE|FFB_PPC_TBE_OPAQUE|
-                  FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST,
+       upa_writel(FFB_PPC_VCE_DISABLE | FFB_PPC_TBE_OPAQUE |
+                  FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
                   &fbc->ppc);
        upa_writel(0x2000707f, &fbc->fbc);
        upa_writel(par->rop_cache, &fbc->rop);
@@ -453,7 +455,7 @@ static void ffb_switch_from_graph(struct ffb_par *par)
 
 static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
 
        /* We just use this to catch switches out of
         * graphics mode.
@@ -466,16 +468,14 @@ static int ffb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 }
 
 /**
- *      ffb_fillrect - REQUIRED function. Can use generic routines if 
- *                     non acclerated hardware and packed pixel based.
- *                     Draws a rectangle on the screen.               
+ *     ffb_fillrect - Draws a rectangle on the screen.
  *
- *      @info: frame buffer structure that represents a single frame buffer
- *      @rect: structure defining the rectagle and operation.
+ *     @info: frame buffer structure that represents a single frame buffer
+ *     @rect: structure defining the rectagle and operation.
  */
 static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
        struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
        u32 fg;
@@ -492,9 +492,9 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
                par->fg_cache = fg;
        }
 
-       ffb_rop(par, (rect->rop == ROP_COPY ?
-                     FFB_ROP_NEW :
-                     FFB_ROP_NEW_XOR_OLD));
+       ffb_rop(par, rect->rop == ROP_COPY ?
+                    FFB_ROP_NEW :
+                    FFB_ROP_NEW_XOR_OLD);
 
        FFBFifo(par, 5);
        upa_writel(FFB_DRAWOP_RECTANGLE, &fbc->drawop);
@@ -507,18 +507,15 @@ static void ffb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 }
 
 /**
- *      ffb_copyarea - REQUIRED function. Can use generic routines if
- *                     non acclerated hardware and packed pixel based.
- *                     Copies on area of the screen to another area.
+ *     ffb_copyarea - Copies on area of the screen to another area.
  *
- *      @info: frame buffer structure that represents a single frame buffer
- *      @area: structure defining the source and destination.
+ *     @info: frame buffer structure that represents a single frame buffer
+ *     @area: structure defining the source and destination.
  */
 
-static void
-ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 
+static void ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
        struct ffb_fbc __iomem *fbc = par->fbc;
        unsigned long flags;
 
@@ -545,16 +542,14 @@ ffb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 }
 
 /**
- *      ffb_imageblit - REQUIRED function. Can use generic routines if
- *                      non acclerated hardware and packed pixel based.
- *                      Copies a image from system memory to the screen. 
+ *     ffb_imageblit - Copies a image from system memory to the screen.
  *
- *      @info: frame buffer structure that represents a single frame buffer
- *      @image: structure defining the image.
+ *     @info: frame buffer structure that represents a single frame buffer
+ *     @image: structure defining the image.
  */
 static void ffb_imageblit(struct fb_info *info, const struct fb_image *image)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
        struct ffb_fbc __iomem *fbc = par->fbc;
        const u8 *data = image->data;
        unsigned long flags;
@@ -642,13 +637,14 @@ static void ffb_fixup_var_rgb(struct fb_var_screeninfo *var)
 }
 
 /**
- *      ffb_setcolreg - Optional function. Sets a color register.
- *      @regno: boolean, 0 copy local, 1 get_user() function
- *      @red: frame buffer colormap structure
- *      @green: The green value which can be up to 16 bits wide
- *      @blue:  The blue value which can be up to 16 bits wide.
- *      @transp: If supported the alpha value which can be up to 16 bits wide.
- *      @info: frame buffer info structure
+ *     ffb_setcolreg - Sets a color register.
+ *
+ *     @regno: boolean, 0 copy local, 1 get_user() function
+ *     @red: frame buffer colormap structure
+ *     @green: The green value which can be up to 16 bits wide
+ *     @blue:  The blue value which can be up to 16 bits wide.
+ *     @transp: If supported the alpha value which can be up to 16 bits wide.
+ *     @info: frame buffer info structure
  */
 static int ffb_setcolreg(unsigned regno,
                         unsigned red, unsigned green, unsigned blue,
@@ -656,7 +652,7 @@ static int ffb_setcolreg(unsigned regno,
 {
        u32 value;
 
-       if (regno >= 256)
+       if (regno >= 16)
                return 1;
 
        red >>= 8;
@@ -670,14 +666,13 @@ static int ffb_setcolreg(unsigned regno,
 }
 
 /**
- *      ffb_blank - Optional function.  Blanks the display.
- *      @blank_mode: the blank mode we want.
- *      @info: frame buffer structure that represents a single frame buffer
+ *     ffb_blank - Optional function.  Blanks the display.
+ *     @blank_mode: the blank mode we want.
+ *     @info: frame buffer structure that represents a single frame buffer
  */
-static int
-ffb_blank(int blank, struct fb_info *info)
+static int ffb_blank(int blank, struct fb_info *info)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
        struct ffb_dac __iomem *dac = par->dac;
        unsigned long flags;
        u32 val;
@@ -865,7 +860,7 @@ static int ffb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
 {
-       struct ffb_par *par = (struct ffb_par *) info->par;
+       struct ffb_par *par = (struct ffb_par *)info->par;
 
        return sbusfb_ioctl_helper(cmd, arg, info,
                                   FBTYPE_CREATOR, 24, par->fbsize);
@@ -875,8 +870,7 @@ static int ffb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
  *  Initialisation
  */
 
-static void
-ffb_init_fix(struct fb_info *info)
+static void ffb_init_fix(struct fb_info *info)
 {
        struct ffb_par *par = (struct ffb_par *)info->par;
        const char *ffb_type_name;
@@ -900,75 +894,68 @@ ffb_init_fix(struct fb_info *info)
        info->fix.accel = FB_ACCEL_SUN_CREATOR;
 }
 
-struct all_info {
-       struct fb_info info;
-       struct ffb_par par;
-       u32 pseudo_palette[256];
-};
-
-static int ffb_init_one(struct of_device *op)
+static int __devinit ffb_probe(struct of_device *op,
+                              const struct of_device_id *match)
 {
        struct device_node *dp = op->node;
        struct ffb_fbc __iomem *fbc;
        struct ffb_dac __iomem *dac;
-       struct all_info *all;
-       int err;
+       struct fb_info *info;
+       struct ffb_par *par;
        u32 dac_pnum, dac_rev, dac_mrev;
+       int err;
 
-       all = kzalloc(sizeof(*all), GFP_KERNEL);
-       if (!all)
-               return -ENOMEM;
+       info = framebuffer_alloc(sizeof(struct ffb_par), &op->dev);
 
-       spin_lock_init(&all->par.lock);
-       all->par.fbc = of_ioremap(&op->resource[2], 0,
-                                 sizeof(struct ffb_fbc), "ffb fbc");
-       if (!all->par.fbc) {
-               kfree(all);
-               return -ENOMEM;
-       }
+       err = -ENOMEM;
+       if (!info)
+               goto out_err;
 
-       all->par.dac = of_ioremap(&op->resource[1], 0,
-                                 sizeof(struct ffb_dac), "ffb dac");
-       if (!all->par.dac) {
-               of_iounmap(&op->resource[2],
-                          all->par.fbc, sizeof(struct ffb_fbc));
-               kfree(all);
-               return -ENOMEM;
-       }
+       par = info->par;
+
+       spin_lock_init(&par->lock);
+       par->fbc = of_ioremap(&op->resource[2], 0,
+                             sizeof(struct ffb_fbc), "ffb fbc");
+       if (!par->fbc)
+               goto out_release_fb;
 
-       all->par.rop_cache = FFB_ROP_NEW;
-       all->par.physbase = op->resource[0].start;
+       par->dac = of_ioremap(&op->resource[1], 0,
+                             sizeof(struct ffb_dac), "ffb dac");
+       if (!par->dac)
+               goto out_unmap_fbc;
+
+       par->rop_cache = FFB_ROP_NEW;
+       par->physbase = op->resource[0].start;
 
        /* Don't mention copyarea, so SCROLL_REDRAW is always
         * used.  It is the fastest on this chip.
         */
-       all->info.flags = (FBINFO_DEFAULT |
-                          /* FBINFO_HWACCEL_COPYAREA | */
-                          FBINFO_HWACCEL_FILLRECT |
-                          FBINFO_HWACCEL_IMAGEBLIT);
-       all->info.fbops = &ffb_ops;
-       all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF;
-       all->info.par = &all->par;
-       all->info.pseudo_palette = all->pseudo_palette;
-
-       sbusfb_fill_var(&all->info.var, dp->node, 32);
-       all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
-                                    all->info.var.yres *
-                                    4);
-       ffb_fixup_var_rgb(&all->info.var);
-
-       all->info.var.accel_flags = FB_ACCELF_TEXT;
+       info->flags = (FBINFO_DEFAULT |
+                      /* FBINFO_HWACCEL_COPYAREA | */
+                      FBINFO_HWACCEL_FILLRECT |
+                      FBINFO_HWACCEL_IMAGEBLIT);
+
+       info->fbops = &ffb_ops;
+
+       info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
+       info->pseudo_palette = par->pseudo_palette;
+
+       sbusfb_fill_var(&info->var, dp, 32);
+       par->fbsize = PAGE_ALIGN(info->var.xres * info->var.yres * 4);
+       ffb_fixup_var_rgb(&info->var);
+
+       info->var.accel_flags = FB_ACCELF_TEXT;
 
        if (!strcmp(dp->name, "SUNW,afb"))
-               all->par.flags |= FFB_FLAG_AFB;
+               par->flags |= FFB_FLAG_AFB;
 
-       all->par.board_type = of_getintprop_default(dp, "board_type", 0);
+       par->board_type = of_getintprop_default(dp, "board_type", 0);
 
-       fbc = all->par.fbc;
+       fbc = par->fbc;
        if ((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
                upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
-       dac = all->par.dac;
+       dac = par->dac;
        upa_writel(FFB_DAC_DID, &dac->type);
        dac_pnum = upa_readl(&dac->value);
        dac_rev = (dac_pnum & FFB_DAC_DID_REV) >> FFB_DAC_DID_REV_SHIFT;
@@ -985,83 +972,77 @@ static int ffb_init_one(struct of_device *op)
         * cursor logic.  We identify Pacifica 1 as not Pacifica 2, the
         * latter having a part number value of 0x236e.
         */
-       if ((all->par.flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
-               all->par.flags &= ~FFB_FLAG_INVCURSOR;
+       if ((par->flags & FFB_FLAG_AFB) || dac_pnum == 0x236e) {
+               par->flags &= ~FFB_FLAG_INVCURSOR;
        } else {
                if (dac_mrev < 3)
-                       all->par.flags |= FFB_FLAG_INVCURSOR;
+                       par->flags |= FFB_FLAG_INVCURSOR;
        }
 
-       ffb_switch_from_graph(&all->par);
+       ffb_switch_from_graph(par);
 
        /* Unblank it just to be sure.  When there are multiple
         * FFB/AFB cards in the system, or it is not the OBP
         * chosen console, it will have video outputs off in
         * the DAC.
         */
-       ffb_blank(0, &all->info);
-
-       if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
-               printk(KERN_ERR "ffb: Could not allocate color map.\n");
-               of_iounmap(&op->resource[2],
-                          all->par.fbc, sizeof(struct ffb_fbc));
-               of_iounmap(&op->resource[1],
-                          all->par.dac, sizeof(struct ffb_dac));
-               kfree(all);
-               return -ENOMEM;
-       }
+       ffb_blank(FB_BLANK_UNBLANK, info);
 
-       ffb_init_fix(&all->info);
-
-       err = register_framebuffer(&all->info);
-       if (err < 0) {
-               printk(KERN_ERR "ffb: Could not register framebuffer.\n");
-               fb_dealloc_cmap(&all->info.cmap);
-               of_iounmap(&op->resource[2],
-                          all->par.fbc, sizeof(struct ffb_fbc));
-               of_iounmap(&op->resource[1],
-                          all->par.dac, sizeof(struct ffb_dac));
-               kfree(all);
-               return err;
-       }
+       if (fb_alloc_cmap(&info->cmap, 256, 0))
+               goto out_unmap_dac;
+
+       ffb_init_fix(info);
+
+       err = register_framebuffer(info);
+       if (err < 0)
+               goto out_dealloc_cmap;
 
-       dev_set_drvdata(&op->dev, all);
+       dev_set_drvdata(&op->dev, info);
 
-       printk("%s: %s at %016lx, type %d, "
+       printk(KERN_INFO "%s: %s at %016lx, type %d, "
               "DAC pnum[%x] rev[%d] manuf_rev[%d]\n",
               dp->full_name,
-              ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
-              all->par.physbase, all->par.board_type,
+              ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
+              par->physbase, par->board_type,
               dac_pnum, dac_rev, dac_mrev);
 
        return 0;
-}
 
-static int __devinit ffb_probe(struct of_device *dev, const struct of_device_id *match)
-{
-       struct of_device *op = to_of_device(&dev->dev);
+out_dealloc_cmap:
+       fb_dealloc_cmap(&info->cmap);
+
+out_unmap_dac:
+       of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
+
+out_unmap_fbc:
+       of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
+
+out_release_fb:
+       framebuffer_release(info);
 
-       return ffb_init_one(op);
+out_err:
+       return err;
 }
 
 static int __devexit ffb_remove(struct of_device *op)
 {
-       struct all_info *all = dev_get_drvdata(&op->dev);
+       struct fb_info *info = dev_get_drvdata(&op->dev);
+       struct ffb_par *par = info->par;
 
-       unregister_framebuffer(&all->info);
-       fb_dealloc_cmap(&all->info.cmap);
+       unregister_framebuffer(info);
+       fb_dealloc_cmap(&info->cmap);
 
-       of_iounmap(&op->resource[2], all->par.fbc, sizeof(struct ffb_fbc));
-       of_iounmap(&op->resource[1], all->par.dac, sizeof(struct ffb_dac));
+       of_iounmap(&op->resource[2], par->fbc, sizeof(struct ffb_fbc));
+       of_iounmap(&op->resource[1], par->dac, sizeof(struct ffb_dac));
 
-       kfree(all);
+       framebuffer_release(info);
 
        dev_set_drvdata(&op->dev, NULL);
 
        return 0;
 }
 
-static struct of_device_id ffb_match[] = {
+static const struct of_device_id ffb_match[] = {
        {
                .name = "SUNW,ffb",
        },
@@ -1079,7 +1060,7 @@ static struct of_platform_driver ffb_driver = {
        .remove         = __devexit_p(ffb_remove),
 };
 
-int __init ffb_init(void)
+static int __init ffb_init(void)
 {
        if (fb_get_options("ffb", NULL))
                return -ENODEV;
@@ -1087,7 +1068,7 @@ int __init ffb_init(void)
        return of_register_driver(&ffb_driver, &of_bus_type);
 }
 
-void __exit ffb_exit(void)
+static void __exit ffb_exit(void)
 {
        of_unregister_driver(&ffb_driver);
 }