Merge drm/drm-next into drm-intel-next-queued
[linux-2.6-microblaze.git] / drivers / gpu / drm / drm_fb_helper.c
index 06e0b00..57f5106 100644 (file)
@@ -95,10 +95,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
  * It will automatically set up deferred I/O if the driver requires a shadow
  * buffer.
  *
- * For other drivers, setup fbdev emulation by calling
- * drm_fb_helper_fbdev_setup() and tear it down by calling
- * drm_fb_helper_fbdev_teardown().
- *
  * At runtime drivers should restore the fbdev console by using
  * drm_fb_helper_lastclose() as their &drm_driver.lastclose callback.
  * They should also notify the fb helper code from updates to the output
@@ -195,6 +191,7 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
 {
        struct drm_fb_helper *helper = info->par;
        struct drm_client_dev *client = &helper->client;
+       struct drm_device *dev = helper->dev;
        struct drm_crtc *crtc;
        const struct drm_crtc_helper_funcs *funcs;
        struct drm_mode_set *mode_set;
@@ -213,7 +210,7 @@ int drm_fb_helper_debug_leave(struct fb_info *info)
                        continue;
 
                if (!fb) {
-                       DRM_ERROR("no fb to restore??\n");
+                       drm_err(dev, "no fb to restore?\n");
                        continue;
                }
 
@@ -567,8 +564,7 @@ EXPORT_SYMBOL(drm_fb_helper_unregister_fbi);
  * drm_fb_helper_fini - finialize a &struct drm_fb_helper
  * @fb_helper: driver-allocated fbdev helper, can be NULL
  *
- * This cleans up all remaining resources associated with @fb_helper. Must be
- * called after drm_fb_helper_unlink_fbi() was called.
+ * This cleans up all remaining resources associated with @fb_helper.
  */
 void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 {
@@ -608,19 +604,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper)
 }
 EXPORT_SYMBOL(drm_fb_helper_fini);
 
-/**
- * drm_fb_helper_unlink_fbi - wrapper around unlink_framebuffer
- * @fb_helper: driver-allocated fbdev helper, can be NULL
- *
- * A wrapper around unlink_framebuffer implemented by fbdev core
- */
-void drm_fb_helper_unlink_fbi(struct drm_fb_helper *fb_helper)
-{
-       if (fb_helper && fb_helper->fbdev)
-               unlink_framebuffer(fb_helper->fbdev);
-}
-EXPORT_SYMBOL(drm_fb_helper_unlink_fbi);
-
 static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
 {
        struct drm_device *dev = fb_helper->dev;
@@ -1266,12 +1249,13 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 {
        struct drm_fb_helper *fb_helper = info->par;
        struct drm_framebuffer *fb = fb_helper->fb;
+       struct drm_device *dev = fb_helper->dev;
 
        if (in_dbg_master())
                return -EINVAL;
 
        if (var->pixclock != 0) {
-               DRM_DEBUG("fbdev emulation doesn't support changing the pixel clock, value of pixclock is ignored\n");
+               drm_dbg_kms(dev, "fbdev emulation doesn't support changing the pixel clock, value of pixclock is ignored\n");
                var->pixclock = 0;
        }
 
@@ -1286,7 +1270,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
        if (var->bits_per_pixel != fb->format->cpp[0] * 8 ||
            var->xres > fb->width || var->yres > fb->height ||
            var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
-               DRM_DEBUG("fb requested width/height/bpp can't fit in current fb "
+               drm_dbg_kms(dev, "fb requested width/height/bpp can't fit in current fb "
                          "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
                          var->xres, var->yres, var->bits_per_pixel,
                          var->xres_virtual, var->yres_virtual,
@@ -1313,7 +1297,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
         * so reject all pixel format changing requests.
         */
        if (!drm_fb_pixel_format_equal(var, &info->var)) {
-               DRM_DEBUG("fbdev emulation doesn't support changing the pixel format\n");
+               drm_dbg_kms(dev, "fbdev emulation doesn't support changing the pixel format\n");
                return -EINVAL;
        }
 
@@ -1338,7 +1322,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
                return -EBUSY;
 
        if (var->pixclock != 0) {
-               DRM_ERROR("PIXEL CLOCK SET\n");
+               drm_err(fb_helper->dev, "PIXEL CLOCK SET\n");
                return -EINVAL;
        }
 
@@ -1448,6 +1432,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
                                         int preferred_bpp)
 {
        struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
        int ret = 0;
        int crtc_count = 0;
        struct drm_connector_list_iter conn_iter;
@@ -1511,7 +1496,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
                struct drm_plane *plane = crtc->primary;
                int j;
 
-               DRM_DEBUG("test CRTC %u primary plane\n", drm_crtc_index(crtc));
+               drm_dbg_kms(dev, "test CRTC %u primary plane\n", drm_crtc_index(crtc));
 
                for (j = 0; j < plane->format_count; j++) {
                        const struct drm_format_info *fmt;
@@ -1544,7 +1529,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
                }
        }
        if (sizes.surface_depth != best_depth && best_depth) {
-               DRM_INFO("requested bpp %d, scaled depth down to %d",
+               drm_info(dev, "requested bpp %d, scaled depth down to %d",
                         sizes.surface_bpp, best_depth);
                sizes.surface_depth = best_depth;
        }
@@ -1594,7 +1579,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
        mutex_unlock(&client->modeset_mutex);
 
        if (crtc_count == 0 || sizes.fb_width == -1 || sizes.fb_height == -1) {
-               DRM_INFO("Cannot find any crtc or sizes\n");
+               drm_info(dev, "Cannot find any crtc or sizes\n");
 
                /* First time: disable all crtc's.. */
                if (!fb_helper->deferred_setup)
@@ -1909,7 +1894,7 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 
        drm_master_internal_release(fb_helper->dev);
 
-       DRM_DEBUG_KMS("\n");
+       drm_dbg_kms(fb_helper->dev, "\n");
 
        drm_client_modeset_probe(&fb_helper->client, fb_helper->fb->width, fb_helper->fb->height);
        drm_setup_crtcs_fb(fb_helper);
@@ -1921,108 +1906,6 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
 }
 EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
 
-/**
- * drm_fb_helper_fbdev_setup() - Setup fbdev emulation
- * @dev: DRM device
- * @fb_helper: fbdev helper structure to set up
- * @funcs: fbdev helper functions
- * @preferred_bpp: Preferred bits per pixel for the device.
- *                 @dev->mode_config.preferred_depth is used if this is zero.
- * @max_conn_count: Maximum number of connectors (not used)
- *
- * This function sets up fbdev emulation and registers fbdev for access by
- * userspace. If all connectors are disconnected, setup is deferred to the next
- * time drm_fb_helper_hotplug_event() is called.
- * The caller must to provide a &drm_fb_helper_funcs->fb_probe callback
- * function.
- *
- * Use drm_fb_helper_fbdev_teardown() to destroy the fbdev.
- *
- * See also: drm_fb_helper_initial_config(), drm_fbdev_generic_setup().
- *
- * Returns:
- * Zero on success or negative error code on failure.
- */
-int drm_fb_helper_fbdev_setup(struct drm_device *dev,
-                             struct drm_fb_helper *fb_helper,
-                             const struct drm_fb_helper_funcs *funcs,
-                             unsigned int preferred_bpp,
-                             unsigned int max_conn_count)
-{
-       int ret;
-
-       if (!preferred_bpp)
-               preferred_bpp = dev->mode_config.preferred_depth;
-       if (!preferred_bpp)
-               preferred_bpp = 32;
-
-       drm_fb_helper_prepare(dev, fb_helper, funcs);
-
-       ret = drm_fb_helper_init(dev, fb_helper, 0);
-       if (ret < 0) {
-               DRM_DEV_ERROR(dev->dev, "fbdev: Failed to initialize (ret=%d)\n", ret);
-               return ret;
-       }
-
-       if (!drm_drv_uses_atomic_modeset(dev))
-               drm_helper_disable_unused_functions(dev);
-
-       ret = drm_fb_helper_initial_config(fb_helper, preferred_bpp);
-       if (ret < 0) {
-               DRM_DEV_ERROR(dev->dev, "fbdev: Failed to set configuration (ret=%d)\n", ret);
-               goto err_drm_fb_helper_fini;
-       }
-
-       return 0;
-
-err_drm_fb_helper_fini:
-       drm_fb_helper_fbdev_teardown(dev);
-
-       return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_fbdev_setup);
-
-/**
- * drm_fb_helper_fbdev_teardown - Tear down fbdev emulation
- * @dev: DRM device
- *
- * This function unregisters fbdev if not already done and cleans up the
- * associated resources including the &drm_framebuffer.
- * The driver is responsible for freeing the &drm_fb_helper structure which is
- * stored in &drm_device->fb_helper. Do note that this pointer has been cleared
- * when this function returns.
- *
- * In order to support device removal/unplug while file handles are still open,
- * drm_fb_helper_unregister_fbi() should be called on device removal and
- * drm_fb_helper_fbdev_teardown() in the &drm_driver->release callback when
- * file handles are closed.
- */
-void drm_fb_helper_fbdev_teardown(struct drm_device *dev)
-{
-       struct drm_fb_helper *fb_helper = dev->fb_helper;
-       struct fb_ops *fbops = NULL;
-
-       if (!fb_helper)
-               return;
-
-       /* Unregister if it hasn't been done already */
-       if (fb_helper->fbdev && fb_helper->fbdev->dev)
-               drm_fb_helper_unregister_fbi(fb_helper);
-
-       if (fb_helper->fbdev && fb_helper->fbdev->fbdefio) {
-               fb_deferred_io_cleanup(fb_helper->fbdev);
-               kfree(fb_helper->fbdev->fbdefio);
-               fbops = fb_helper->fbdev->fbops;
-       }
-
-       drm_fb_helper_fini(fb_helper);
-       kfree(fbops);
-
-       if (fb_helper->fb)
-               drm_framebuffer_remove(fb_helper->fb);
-}
-EXPORT_SYMBOL(drm_fb_helper_fbdev_teardown);
-
 /**
  * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation
  * @dev: DRM device
@@ -2076,7 +1959,6 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user)
 static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
 {
        struct fb_info *fbi = fb_helper->fbdev;
-       struct fb_ops *fbops = NULL;
        void *shadow = NULL;
 
        if (!fb_helper->dev)
@@ -2085,15 +1967,11 @@ static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper)
        if (fbi && fbi->fbdefio) {
                fb_deferred_io_cleanup(fbi);
                shadow = fbi->screen_buffer;
-               fbops = fbi->fbops;
        }
 
        drm_fb_helper_fini(fb_helper);
 
-       if (shadow) {
-               vfree(shadow);
-               kfree(fbops);
-       }
+       vfree(shadow);
 
        drm_client_framebuffer_delete(fb_helper->buffer);
 }
@@ -2124,7 +2002,7 @@ static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
                return -ENODEV;
 }
 
-static struct fb_ops drm_fbdev_fb_ops = {
+static const struct fb_ops drm_fbdev_fb_ops = {
        .owner          = THIS_MODULE,
        DRM_FB_HELPER_DEFAULT_OPS,
        .fb_open        = drm_fbdev_fb_open,
@@ -2143,32 +2021,26 @@ static struct fb_deferred_io drm_fbdev_defio = {
        .deferred_io    = drm_fb_helper_deferred_io,
 };
 
-/**
- * drm_fb_helper_generic_probe - Generic fbdev emulation probe helper
- * @fb_helper: fbdev helper structure
- * @sizes: describes fbdev size and scanout surface size
- *
+/*
  * This function uses the client API to create a framebuffer backed by a dumb buffer.
  *
  * The _sys_ versions are used for &fb_ops.fb_read, fb_write, fb_fillrect,
  * fb_copyarea, fb_imageblit.
- *
- * Returns:
- * Zero on success or negative error code on failure.
  */
-int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
-                               struct drm_fb_helper_surface_size *sizes)
+static int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
+                                      struct drm_fb_helper_surface_size *sizes)
 {
        struct drm_client_dev *client = &fb_helper->client;
+       struct drm_device *dev = fb_helper->dev;
        struct drm_client_buffer *buffer;
        struct drm_framebuffer *fb;
        struct fb_info *fbi;
        u32 format;
        void *vaddr;
 
-       DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
-                     sizes->surface_width, sizes->surface_height,
-                     sizes->surface_bpp);
+       drm_dbg_kms(dev, "surface width(%d), height(%d) and bpp(%d)\n",
+                   sizes->surface_width, sizes->surface_height,
+                   sizes->surface_bpp);
 
        format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
        buffer = drm_client_framebuffer_create(client, sizes->surface_width,
@@ -2191,24 +2063,10 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
        drm_fb_helper_fill_info(fbi, fb_helper, sizes);
 
        if (drm_fbdev_use_shadow_fb(fb_helper)) {
-               struct fb_ops *fbops;
-               void *shadow;
-
-               /*
-                * fb_deferred_io_cleanup() clears &fbops->fb_mmap so a per
-                * instance version is necessary.
-                */
-               fbops = kzalloc(sizeof(*fbops), GFP_KERNEL);
-               shadow = vzalloc(fbi->screen_size);
-               if (!fbops || !shadow) {
-                       kfree(fbops);
-                       vfree(shadow);
+               fbi->screen_buffer = vzalloc(fbi->screen_size);
+               if (!fbi->screen_buffer)
                        return -ENOMEM;
-               }
 
-               *fbops = *fbi->fbops;
-               fbi->fbops = fbops;
-               fbi->screen_buffer = shadow;
                fbi->fbdefio = &drm_fbdev_defio;
 
                fb_deferred_io_init(fbi);
@@ -2229,7 +2087,6 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
 
        return 0;
 }
-EXPORT_SYMBOL(drm_fb_helper_generic_probe);
 
 static const struct drm_fb_helper_funcs drm_fb_helper_generic_funcs = {
        .fb_probe = drm_fb_helper_generic_probe,
@@ -2267,7 +2124,7 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
                return drm_fb_helper_hotplug_event(dev->fb_helper);
 
        if (!dev->mode_config.num_connector) {
-               DRM_DEV_DEBUG(dev->dev, "No connectors found, will not create framebuffer!\n");
+               drm_dbg_kms(dev, "No connectors found, will not create framebuffer!\n");
                return 0;
        }
 
@@ -2292,7 +2149,7 @@ err:
        fb_helper->dev = NULL;
        fb_helper->fbdev = NULL;
 
-       DRM_DEV_ERROR(dev->dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
+       drm_err(dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret);
 
        return ret;
 }
@@ -2311,8 +2168,7 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
  *                 @dev->mode_config.preferred_depth is used if this is zero.
  *
  * This function sets up generic fbdev emulation for drivers that supports
- * dumb buffers with a virtual address and that can be mmap'ed. If the driver
- * does not support these functions, it could use drm_fb_helper_fbdev_setup().
+ * dumb buffers with a virtual address and that can be mmap'ed.
  *
  * Restore, hotplug events and teardown are all taken care of. Drivers that do
  * suspend/resume need to call drm_fb_helper_set_suspend_unlocked() themselves.
@@ -2350,7 +2206,7 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
        ret = drm_client_init(dev, &fb_helper->client, "fbdev", &drm_fbdev_client_funcs);
        if (ret) {
                kfree(fb_helper);
-               DRM_DEV_ERROR(dev->dev, "Failed to register client: %d\n", ret);
+               drm_err(dev, "Failed to register client: %d\n", ret);
                return ret;
        }
 
@@ -2362,7 +2218,7 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
 
        ret = drm_fbdev_client_hotplug(&fb_helper->client);
        if (ret)
-               DRM_DEV_DEBUG(dev->dev, "client hotplug ret=%d\n", ret);
+               drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
 
        drm_client_register(&fb_helper->client);