FROMLIST: drm/rockchip: fix fbdev crash when not use DRM_FBDEV_EMULATION
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / rockchip / rockchip_drm_fbdev.c
index bab4cd18b6b08199955bf8fd921d9f46df4233f7..6b50dfae4ad4ee14fabf16ee23b859e00ea3ba88 100644 (file)
 #include "rockchip_drm_fb.h"
 
 #define PREFERRED_BPP          32
-#define to_drm_private(x) \
-               container_of(x, struct rockchip_drm_private, fbdev_helper)
 
 static int rockchip_fbdev_mmap(struct fb_info *info,
                               struct vm_area_struct *vma)
 {
        struct drm_fb_helper *helper = info->par;
-       struct rockchip_drm_private *private = to_drm_private(helper);
+       struct rockchip_drm_private *private = helper->dev->dev_private;
 
        return rockchip_gem_mmap_buf(private->fbdev_bo, vma);
 }
@@ -50,7 +48,7 @@ static struct fb_ops rockchip_drm_fbdev_ops = {
 static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
                                     struct drm_fb_helper_surface_size *sizes)
 {
-       struct rockchip_drm_private *private = to_drm_private(helper);
+       struct rockchip_drm_private *private = helper->dev->dev_private;
        struct drm_mode_fb_cmd2 mode_cmd = { 0 };
        struct drm_device *dev = helper->dev;
        struct rockchip_gem_object *rk_obj;
@@ -139,7 +137,11 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
 
        num_crtc = dev->mode_config.num_crtc;
 
-       helper = &private->fbdev_helper;
+       helper = devm_kzalloc(dev->dev, sizeof(*helper), GFP_KERNEL);
+       if (!helper)
+               return -ENOMEM;
+
+       private->fbdev_helper = helper;
 
        drm_fb_helper_prepare(dev, helper, &rockchip_drm_fb_helper_funcs);
 
@@ -156,9 +158,6 @@ int rockchip_drm_fbdev_init(struct drm_device *dev)
                goto err_drm_fb_helper_fini;
        }
 
-       /* disable all the possible outputs/crtcs before entering KMS mode */
-       drm_helper_disable_unused_functions(dev);
-
        ret = drm_fb_helper_initial_config(helper, PREFERRED_BPP);
        if (ret < 0) {
                dev_err(dev->dev, "Failed to set initial hw config - %d.\n",
@@ -176,9 +175,10 @@ err_drm_fb_helper_fini:
 void rockchip_drm_fbdev_fini(struct drm_device *dev)
 {
        struct rockchip_drm_private *private = dev->dev_private;
-       struct drm_fb_helper *helper;
+       struct drm_fb_helper *helper = private->fbdev_helper;
 
-       helper = &private->fbdev_helper;
+       if (!helper)
+               return;
 
        drm_fb_helper_unregister_fbi(helper);
        drm_fb_helper_release_fbi(helper);