drm: Propagate error from drm_fb_helper_init().
[safe/jmp/linux-2.6] / drivers / gpu / drm / nouveau / nouveau_fbcon.c
index bc81ec7..c9a4a0d 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/tty.h>
-#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
@@ -98,7 +97,6 @@ static struct fb_ops nouveau_fbcon_ops = {
        .owner = THIS_MODULE,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
-       .fb_setcolreg = drm_fb_helper_setcolreg,
        .fb_fillrect = cfb_fillrect,
        .fb_copyarea = cfb_copyarea,
        .fb_imageblit = cfb_imageblit,
@@ -112,7 +110,6 @@ static struct fb_ops nv04_fbcon_ops = {
        .owner = THIS_MODULE,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
-       .fb_setcolreg = drm_fb_helper_setcolreg,
        .fb_fillrect = nv04_fbcon_fillrect,
        .fb_copyarea = nv04_fbcon_copyarea,
        .fb_imageblit = nv04_fbcon_imageblit,
@@ -126,7 +123,6 @@ static struct fb_ops nv50_fbcon_ops = {
        .owner = THIS_MODULE,
        .fb_check_var = drm_fb_helper_check_var,
        .fb_set_par = drm_fb_helper_set_par,
-       .fb_setcolreg = drm_fb_helper_setcolreg,
        .fb_fillrect = nv50_fbcon_fillrect,
        .fb_copyarea = nv50_fbcon_copyarea,
        .fb_imageblit = nv50_fbcon_imageblit,
@@ -156,44 +152,6 @@ static void nouveau_fbcon_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
        *blue = nv_crtc->lut.b[regno];
 }
 
-#if defined(__i386__) || defined(__x86_64__)
-static bool
-nouveau_fbcon_has_vesafb_or_efifb(struct drm_device *dev)
-{
-       struct pci_dev *pdev = dev->pdev;
-       int ramin;
-
-       if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB &&
-           screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
-               return false;
-
-       if (screen_info.lfb_base < pci_resource_start(pdev, 1))
-               goto not_fb;
-
-       if (screen_info.lfb_base + screen_info.lfb_size >=
-           pci_resource_start(pdev, 1) + pci_resource_len(pdev, 1))
-               goto not_fb;
-
-       return true;
-not_fb:
-       ramin = 2;
-       if (pci_resource_len(pdev, ramin) == 0) {
-               ramin = 3;
-               if (pci_resource_len(pdev, ramin) == 0)
-                       return false;
-       }
-
-       if (screen_info.lfb_base < pci_resource_start(pdev, ramin))
-               return false;
-
-       if (screen_info.lfb_base + screen_info.lfb_size >=
-           pci_resource_start(pdev, ramin) + pci_resource_len(pdev, ramin))
-               return false;
-
-       return true;
-}
-#endif
-
 static void
 nouveau_fbcon_zfill(struct drm_device *dev, struct nouveau_fbdev *nfbdev)
 {
@@ -223,7 +181,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
        struct nouveau_framebuffer *nouveau_fb;
        struct nouveau_bo *nvbo;
        struct drm_mode_fb_cmd mode_cmd;
-       struct device *device = &dev->pdev->dev;
+       struct pci_dev *pdev = dev->pdev;
+       struct device *device = &pdev->dev;
        int size, ret;
 
        mode_cmd.width = sizes->surface_width;
@@ -303,28 +262,14 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
        drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height);
 
        /* FIXME: we really shouldn't expose mmio space at all */
-       info->fix.mmio_start = pci_resource_start(dev->pdev, 1);
-       info->fix.mmio_len = pci_resource_len(dev->pdev, 1);
+       info->fix.mmio_start = pci_resource_start(pdev, 1);
+       info->fix.mmio_len = pci_resource_len(pdev, 1);
 
        /* Set aperture base/size for vesafb takeover */
-#if defined(__i386__) || defined(__x86_64__)
-       if (nouveau_fbcon_has_vesafb_or_efifb(dev)) {
-               /* Some NVIDIA VBIOS' are stupid and decide to put the
-                * framebuffer in the middle of the PRAMIN BAR for
-                * whatever reason.  We need to know the exact lfb_base
-                * to get vesafb kicked off, and the only reliable way
-                * we have left is to find out lfb_base the same way
-                * vesafb did.
-                */
-               info->aperture_base = screen_info.lfb_base;
-               info->aperture_size = screen_info.lfb_size;
-               if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
-                       info->aperture_size *= 65536;
-       } else
-#endif
-       {
-               info->aperture_base = info->fix.mmio_start;
-               info->aperture_size = info->fix.mmio_len;
+       info->apertures = dev_priv->apertures;
+       if (!info->apertures) {
+               ret = -ENOMEM;
+               goto out_unref;
        }
 
        info->pixmap.size = 64*1024;
@@ -381,15 +326,11 @@ nouveau_fbcon_find_or_create_single(struct drm_fb_helper *helper,
        return new_fb;
 }
 
-void nouveau_fbcon_hotplug(struct drm_device *dev)
+void
+nouveau_fbcon_output_poll_changed(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       drm_helper_fb_hpd_irq_event(&dev_priv->nfbdev->helper);
-}
-
-static void nouveau_fbcon_output_status_changed(struct drm_fb_helper *fb_helper)
-{
-       drm_helper_fb_hotplug_event(fb_helper, true);
+       drm_fb_helper_hotplug_event(&dev_priv->nfbdev->helper);
 }
 
 int
@@ -429,7 +370,6 @@ static struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = {
        .gamma_set = nouveau_fbcon_gamma_set,
        .gamma_get = nouveau_fbcon_gamma_get,
        .fb_probe = nouveau_fbcon_find_or_create_single,
-       .fb_output_status_changed = nouveau_fbcon_output_status_changed,
 };
 
 
@@ -437,6 +377,7 @@ int nouveau_fbcon_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_fbdev *nfbdev;
+       int ret;
 
        nfbdev = kzalloc(sizeof(struct nouveau_fbdev), GFP_KERNEL);
        if (!nfbdev)
@@ -446,8 +387,12 @@ int nouveau_fbcon_init(struct drm_device *dev)
        dev_priv->nfbdev = nfbdev;
        nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs;
 
-       drm_fb_helper_init(dev, &nfbdev->helper,
-                          2, 4, true);
+       ret = drm_fb_helper_init(dev, &nfbdev->helper, 2, 4);
+       if (ret) {
+               kfree(nfbdev);
+               return ret;
+       }
+
        drm_fb_helper_single_add_all_connectors(&nfbdev->helper);
        drm_fb_helper_initial_config(&nfbdev->helper, 32);
        return 0;