drm: Propagate error from drm_fb_helper_init().
[safe/jmp/linux-2.6] / drivers / video / asiliantfb.c
index 1fd22f4..8cdf88e 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
-#include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -140,7 +139,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc
 
                /* 3 <= m <= 257 */
                if (m >= 3 && m <= 257) {
-                       unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
+                       unsigned new_error = Ftarget * n >= Fref * m ?
                                               ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
                        if (new_error < best_error) {
                                best_n = n;
@@ -152,7 +151,7 @@ static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dc
                else if (m <= 1028) {
                        /* remember there are still only 8-bits of precision in m, so
                         * avoid over-optimistic error calculations */
-                       unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
+                       unsigned new_error = Ftarget * n >= Fref * (m & ~3) ?
                                               ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
                        if (new_error < best_error) {
                                best_n = n;
@@ -505,19 +504,27 @@ static struct fb_var_screeninfo asiliantfb_var __devinitdata = {
        .vsync_len      = 2,
 };
 
-static void __devinit init_asiliant(struct fb_info *p, unsigned long addr)
+static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
 {
+       int err;
+
        p->fix                  = asiliantfb_fix;
        p->fix.smem_start       = addr;
        p->var                  = asiliantfb_var;
        p->fbops                = &asiliantfb_ops;
        p->flags                = FBINFO_DEFAULT;
 
-       fb_alloc_cmap(&p->cmap, 256, 0);
+       err = fb_alloc_cmap(&p->cmap, 256, 0);
+       if (err) {
+               printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n");
+               return err;
+       }
 
-       if (register_framebuffer(p) < 0) {
+       err = register_framebuffer(p);
+       if (err < 0) {
                printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
-               return;
+               fb_dealloc_cmap(&p->cmap);
+               return err;
        }
 
        printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
@@ -525,6 +532,7 @@ static void __devinit init_asiliant(struct fb_info *p, unsigned long addr)
 
        writeb(0xff, mmio_base + 0x78c);
        chips_hw_init(p);
+       return 0;
 }
 
 static int __devinit
@@ -532,6 +540,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
 {
        unsigned long addr, size;
        struct fb_info *p;
+       int err;
 
        if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
                return -ENODEV;
@@ -560,7 +569,13 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
        pci_write_config_dword(dp, 4, 0x02800083);
        writeb(3, p->screen_base + 0x400784);
 
-       init_asiliant(p, addr);
+       err = init_asiliant(p, addr);
+       if (err) {
+               iounmap(p->screen_base);
+               release_mem_region(addr, size);
+               framebuffer_release(p);
+               return err;
+       }
 
        pci_set_drvdata(dp, p);
        return 0;
@@ -571,6 +586,7 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp)
        struct fb_info *p = pci_get_drvdata(dp);
 
        unregister_framebuffer(p);
+       fb_dealloc_cmap(&p->cmap);
        iounmap(p->screen_base);
        release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
        pci_set_drvdata(dp, NULL);