Some drivers don't have real ->create_handle callbacks.
- cirrus/ast/mga200: Returns either 0 or -EINVAL.
- udl: Didn't even bother with a callback, leading to a nice
  userspace-triggerable OOPS.
- vmwgfx: This driver bothered with an implementation to return 0 as
  the handle (which is the canonical no-obj gem handle).
All have in common that ->create_handle doesn't really make too much
sense for them - that ioctl is used only for seamless fb takeover in
the radeon/nouveau/i915 ddx drivers. So allow drivers to not implement
this and return a consistent -ENODEV.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
        kfree(fb);
 }
 
-static int ast_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                             struct drm_file *file,
-                                             unsigned int *handle)
-{
-       return -EINVAL;
-}
-
 static const struct drm_framebuffer_funcs ast_fb_funcs = {
        .destroy = ast_user_framebuffer_destroy,
-       .create_handle = ast_user_framebuffer_create_handle,
 };
 
 
 
        kfree(fb);
 }
 
-static int cirrus_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                                struct drm_file *file_priv,
-                                                unsigned int *handle)
-{
-       return 0;
-}
-
 static const struct drm_framebuffer_funcs cirrus_fb_funcs = {
        .destroy = cirrus_user_framebuffer_destroy,
-       .create_handle = cirrus_user_framebuffer_create_handle,
 };
 
 int cirrus_framebuffer_init(struct drm_device *dev,
 
        r->depth = fb->depth;
        r->bpp = fb->bits_per_pixel;
        r->pitch = fb->pitches[0];
-       fb->funcs->create_handle(fb, file_priv, &r->handle);
+       if (fb->funcs->create_handle)
+               ret = fb->funcs->create_handle(fb, file_priv, &r->handle);
+       else
+               ret = -ENODEV;
 
 out:
        mutex_unlock(&dev->mode_config.mutex);
 
        kfree(fb);
 }
 
-static int mga_user_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                                struct drm_file *file_priv,
-                                                unsigned int *handle)
-{
-       return 0;
-}
-
 static const struct drm_framebuffer_funcs mga_fb_funcs = {
        .destroy = mga_user_framebuffer_destroy,
-       .create_handle = mga_user_framebuffer_create_handle,
 };
 
 int mgag200_framebuffer_init(struct drm_device *dev,
 
 static const struct drm_framebuffer_funcs udlfb_funcs = {
        .destroy = udl_user_framebuffer_destroy,
        .dirty = udl_user_framebuffer_dirty,
-       .create_handle = NULL,
 };
 
 
 
  * Generic framebuffer code
  */
 
-int vmw_framebuffer_create_handle(struct drm_framebuffer *fb,
-                                 struct drm_file *file_priv,
-                                 unsigned int *handle)
-{
-       if (handle)
-               *handle = 0;
-
-       return 0;
-}
-
 /*
  * Surface framebuffer code
  */
 static struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
        .destroy = vmw_framebuffer_surface_destroy,
        .dirty = vmw_framebuffer_surface_dirty,
-       .create_handle = vmw_framebuffer_create_handle,
 };
 
 static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
 static struct drm_framebuffer_funcs vmw_framebuffer_dmabuf_funcs = {
        .destroy = vmw_framebuffer_dmabuf_destroy,
        .dirty = vmw_framebuffer_dmabuf_dirty,
-       .create_handle = vmw_framebuffer_create_handle,
 };
 
 /**