Merge tag 'v4.8' into patchwork
[cascardo/linux.git] / drivers / gpu / drm / drm_drv.c
index bff8922..be27ed3 100644 (file)
 #include <linux/slab.h>
 #include <drm/drmP.h>
 #include <drm/drm_core.h>
+#include "drm_crtc_internal.h"
 #include "drm_legacy.h"
 #include "drm_internal.h"
+#include "drm_crtc_internal.h"
 
 /*
  * drm_debug: Enable debug output.
@@ -93,114 +95,6 @@ void drm_ut_debug_printk(const char *function_name, const char *format, ...)
 }
 EXPORT_SYMBOL(drm_ut_debug_printk);
 
-struct drm_master *drm_master_create(struct drm_minor *minor)
-{
-       struct drm_master *master;
-
-       master = kzalloc(sizeof(*master), GFP_KERNEL);
-       if (!master)
-               return NULL;
-
-       kref_init(&master->refcount);
-       spin_lock_init(&master->lock.spinlock);
-       init_waitqueue_head(&master->lock.lock_queue);
-       idr_init(&master->magic_map);
-       master->minor = minor;
-
-       return master;
-}
-
-struct drm_master *drm_master_get(struct drm_master *master)
-{
-       kref_get(&master->refcount);
-       return master;
-}
-EXPORT_SYMBOL(drm_master_get);
-
-static void drm_master_destroy(struct kref *kref)
-{
-       struct drm_master *master = container_of(kref, struct drm_master, refcount);
-       struct drm_device *dev = master->minor->dev;
-
-       if (dev->driver->master_destroy)
-               dev->driver->master_destroy(dev, master);
-
-       drm_legacy_master_rmmaps(dev, master);
-
-       idr_destroy(&master->magic_map);
-       kfree(master->unique);
-       kfree(master);
-}
-
-void drm_master_put(struct drm_master **master)
-{
-       kref_put(&(*master)->refcount, drm_master_destroy);
-       *master = NULL;
-}
-EXPORT_SYMBOL(drm_master_put);
-
-int drm_setmaster_ioctl(struct drm_device *dev, void *data,
-                       struct drm_file *file_priv)
-{
-       int ret = 0;
-
-       mutex_lock(&dev->master_mutex);
-       if (file_priv->is_master)
-               goto out_unlock;
-
-       if (file_priv->minor->master) {
-               ret = -EINVAL;
-               goto out_unlock;
-       }
-
-       if (!file_priv->master) {
-               ret = -EINVAL;
-               goto out_unlock;
-       }
-
-       if (!file_priv->allowed_master) {
-               ret = drm_new_set_master(dev, file_priv);
-               goto out_unlock;
-       }
-
-       file_priv->minor->master = drm_master_get(file_priv->master);
-       file_priv->is_master = 1;
-       if (dev->driver->master_set) {
-               ret = dev->driver->master_set(dev, file_priv, false);
-               if (unlikely(ret != 0)) {
-                       file_priv->is_master = 0;
-                       drm_master_put(&file_priv->minor->master);
-               }
-       }
-
-out_unlock:
-       mutex_unlock(&dev->master_mutex);
-       return ret;
-}
-
-int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
-                        struct drm_file *file_priv)
-{
-       int ret = -EINVAL;
-
-       mutex_lock(&dev->master_mutex);
-       if (!file_priv->is_master)
-               goto out_unlock;
-
-       if (!file_priv->minor->master)
-               goto out_unlock;
-
-       ret = 0;
-       if (dev->driver->master_drop)
-               dev->driver->master_drop(dev, file_priv, false);
-       drm_master_put(&file_priv->minor->master);
-       file_priv->is_master = 0;
-
-out_unlock:
-       mutex_unlock(&dev->master_mutex);
-       return ret;
-}
-
 /*
  * DRM Minors
  * A DRM device can provide several char-dev interfaces on the DRM-Major. Each
@@ -405,10 +299,9 @@ void drm_minor_release(struct drm_minor *minor)
  * callbacks implemented by the driver. The driver then needs to initialize all
  * the various subsystems for the drm device like memory management, vblank
  * handling, modesetting support and intial output configuration plus obviously
- * initialize all the corresponding hardware bits. An important part of this is
- * also calling drm_dev_set_unique() to set the userspace-visible unique name of
- * this device instance. Finally when everything is up and running and ready for
- * userspace the device instance can be published using drm_dev_register().
+ * initialize all the corresponding hardware bits. Finally when everything is up
+ * and running and ready for userspace the device instance can be published
+ * using drm_dev_register().
  *
  * There is also deprecated support for initalizing device instances using
  * bus-specific helpers and the ->load() callback. But due to
@@ -430,6 +323,14 @@ void drm_minor_release(struct drm_minor *minor)
  * dev_priv field of &drm_device.
  */
 
+static int drm_dev_set_unique(struct drm_device *dev, const char *name)
+{
+       kfree(dev->unique);
+       dev->unique = kstrdup(name, GFP_KERNEL);
+
+       return dev->unique ? 0 : -ENOMEM;
+}
+
 /**
  * drm_put_dev - Unregister and release a DRM device
  * @dev: DRM device
@@ -461,9 +362,7 @@ EXPORT_SYMBOL(drm_put_dev);
 void drm_unplug_dev(struct drm_device *dev)
 {
        /* for a USB device */
-       drm_minor_unregister(dev, DRM_MINOR_LEGACY);
-       drm_minor_unregister(dev, DRM_MINOR_RENDER);
-       drm_minor_unregister(dev, DRM_MINOR_CONTROL);
+       drm_dev_unregister(dev);
 
        mutex_lock(&drm_global_mutex);
 
@@ -549,11 +448,12 @@ static void drm_fs_inode_free(struct inode *inode)
 }
 
 /**
- * drm_dev_alloc - Allocate new DRM device
- * @driver: DRM driver to allocate device for
+ * drm_dev_init - Initialise new DRM device
+ * @dev: DRM device
+ * @driver: DRM driver
  * @parent: Parent device object
  *
- * Allocate and initialize a new DRM device. No device registration is done.
+ * Initialize a new DRM device. No device registration is done.
  * Call drm_dev_register() to advertice the device to user space and register it
  * with other core subsystems. This should be done last in the device
  * initialization sequence to make sure userspace can't access an inconsistent
@@ -564,19 +464,18 @@ static void drm_fs_inode_free(struct inode *inode)
  *
  * Note that for purely virtual devices @parent can be NULL.
  *
+ * Drivers that do not want to allocate their own device struct
+ * embedding struct &drm_device can call drm_dev_alloc() instead.
+ *
  * RETURNS:
- * Pointer to new DRM device, or NULL if out of memory.
+ * 0 on success, or error code on failure.
  */
-struct drm_device *drm_dev_alloc(struct drm_driver *driver,
-                                struct device *parent)
+int drm_dev_init(struct drm_device *dev,
+                struct drm_driver *driver,
+                struct device *parent)
 {
-       struct drm_device *dev;
        int ret;
 
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev)
-               return NULL;
-
        kref_init(&dev->ref);
        dev->dev = parent;
        dev->driver = driver;
@@ -605,8 +504,6 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
                ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
                if (ret)
                        goto err_minors;
-
-               WARN_ON(driver->suspend || driver->resume);
        }
 
        if (drm_core_check_feature(dev, DRIVER_RENDER)) {
@@ -619,7 +516,8 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
        if (ret)
                goto err_minors;
 
-       if (drm_ht_create(&dev->map_hash, 12))
+       ret = drm_ht_create(&dev->map_hash, 12);
+       if (ret)
                goto err_minors;
 
        drm_legacy_ctxbitmap_init(dev);
@@ -632,13 +530,13 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver,
                }
        }
 
-       if (parent) {
-               ret = drm_dev_set_unique(dev, dev_name(parent));
-               if (ret)
-                       goto err_setunique;
-       }
+       /* Use the parent device name as DRM device unique identifier, but fall
+        * back to the driver name for virtual devices like vgem. */
+       ret = drm_dev_set_unique(dev, parent ? dev_name(parent) : driver->name);
+       if (ret)
+               goto err_setunique;
 
-       return dev;
+       return 0;
 
 err_setunique:
        if (drm_core_check_feature(dev, DRIVER_GEM))
@@ -653,8 +551,49 @@ err_minors:
        drm_fs_inode_free(dev->anon_inode);
 err_free:
        mutex_destroy(&dev->master_mutex);
-       kfree(dev);
-       return NULL;
+       return ret;
+}
+EXPORT_SYMBOL(drm_dev_init);
+
+/**
+ * drm_dev_alloc - Allocate new DRM device
+ * @driver: DRM driver to allocate device for
+ * @parent: Parent device object
+ *
+ * Allocate and initialize a new DRM device. No device registration is done.
+ * Call drm_dev_register() to advertice the device to user space and register it
+ * with other core subsystems. This should be done last in the device
+ * initialization sequence to make sure userspace can't access an inconsistent
+ * state.
+ *
+ * The initial ref-count of the object is 1. Use drm_dev_ref() and
+ * drm_dev_unref() to take and drop further ref-counts.
+ *
+ * Note that for purely virtual devices @parent can be NULL.
+ *
+ * Drivers that wish to subclass or embed struct &drm_device into their
+ * own struct should look at using drm_dev_init() instead.
+ *
+ * RETURNS:
+ * Pointer to new DRM device, or NULL if out of memory.
+ */
+struct drm_device *drm_dev_alloc(struct drm_driver *driver,
+                                struct device *parent)
+{
+       struct drm_device *dev;
+       int ret;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev)
+               return NULL;
+
+       ret = drm_dev_init(dev, driver, parent);
+       if (ret) {
+               kfree(dev);
+               return NULL;
+       }
+
+       return dev;
 }
 EXPORT_SYMBOL(drm_dev_alloc);
 
@@ -718,11 +657,7 @@ EXPORT_SYMBOL(drm_dev_unref);
  *
  * Register the DRM device @dev with the system, advertise device to user-space
  * and start normal device operation. @dev must be allocated via drm_dev_alloc()
- * previously. Right after drm_dev_register() the driver should call
- * drm_connector_register_all() to register all connectors in sysfs. This is
- * a separate call for backward compatibility with drivers still using
- * the deprecated ->load() callback, where connectors are registered from within
- * the ->load() callback.
+ * previously.
  *
  * Never call this twice on any device!
  *
@@ -759,6 +694,9 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
                        goto err_minors;
        }
 
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_modeset_register_all(dev);
+
        ret = 0;
        goto out_unlock;
 
@@ -789,6 +727,9 @@ void drm_dev_unregister(struct drm_device *dev)
 
        drm_lastclose(dev);
 
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               drm_modeset_unregister_all(dev);
+
        if (dev->driver->unload)
                dev->driver->unload(dev);
 
@@ -806,26 +747,6 @@ void drm_dev_unregister(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_dev_unregister);
 
-/**
- * drm_dev_set_unique - Set the unique name of a DRM device
- * @dev: device of which to set the unique name
- * @name: unique name
- *
- * Sets the unique name of a DRM device using the specified string. Drivers
- * can use this at driver probe time if the unique name of the devices they
- * drive is static.
- *
- * Return: 0 on success or a negative error code on failure.
- */
-int drm_dev_set_unique(struct drm_device *dev, const char *name)
-{
-       kfree(dev->unique);
-       dev->unique = kstrdup(name, GFP_KERNEL);
-
-       return dev->unique ? 0 : -ENOMEM;
-}
-EXPORT_SYMBOL(drm_dev_set_unique);
-
 /*
  * DRM Core
  * The DRM core module initializes all global DRM objects and makes them