drm/i915: Split out load time early initialization
authorImre Deak <imre.deak@intel.com>
Wed, 16 Mar 2016 11:39:03 +0000 (13:39 +0200)
committerImre Deak <imre.deak@intel.com>
Thu, 17 Mar 2016 13:22:07 +0000 (15:22 +0200)
According to the new init phases scheme we should initialize "SW-only"
state not requiring accessing the device as the very first step, so that
the reasoning about dependencies of later steps becomes easier. So move
these init steps into a separate function. This also has the benefit of
making the error path cleaner both in the new function and int
i915_driver_load()/unload().

No functional change.

Suggested by Chris.

CC: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/1458128348-15730-15-git-send-email-imre.deak@intel.com
drivers/gpu/drm/i915/i915_dma.c

index 7618a3f4c21fa8847597540e439d1bf554f58c31..182770dee746197f5dda8c2800947b0c4bc75878 100644 (file)
@@ -933,6 +933,83 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv)
        destroy_workqueue(dev_priv->wq);
 }
 
+/**
+ * i915_driver_init_early - setup state not requiring device access
+ * @dev_priv: device private
+ *
+ * Initialize everything that is a "SW-only" state, that is state not
+ * requiring accessing the device or exposing the driver via kernel internal
+ * or userspace interfaces. Example steps belonging here: lock initialization,
+ * system memory allocation, setting up device specific attributes and
+ * function hooks not requiring accessing the device.
+ */
+static int i915_driver_init_early(struct drm_i915_private *dev_priv,
+                                 struct drm_device *dev,
+                                 struct intel_device_info *info)
+{
+       struct intel_device_info *device_info;
+       int ret = 0;
+
+       dev_priv->dev = dev;
+
+       /* Setup the write-once "constant" device info */
+       device_info = (struct intel_device_info *)&dev_priv->info;
+       memcpy(device_info, info, sizeof(dev_priv->info));
+       device_info->device_id = dev->pdev->device;
+
+       spin_lock_init(&dev_priv->irq_lock);
+       spin_lock_init(&dev_priv->gpu_error.lock);
+       mutex_init(&dev_priv->backlight_lock);
+       spin_lock_init(&dev_priv->uncore.lock);
+       spin_lock_init(&dev_priv->mm.object_stat_lock);
+       spin_lock_init(&dev_priv->mmio_flip_lock);
+       mutex_init(&dev_priv->sb_lock);
+       mutex_init(&dev_priv->modeset_restore_lock);
+       mutex_init(&dev_priv->av_mutex);
+       mutex_init(&dev_priv->wm.wm_mutex);
+       mutex_init(&dev_priv->pps_mutex);
+
+       ret = i915_workqueues_init(dev_priv);
+       if (ret < 0)
+               return ret;
+
+       /* This must be called before any calls to HAS_PCH_* */
+       intel_detect_pch(dev);
+
+       intel_pm_setup(dev);
+       intel_init_dpio(dev_priv);
+       intel_power_domains_init(dev_priv);
+       intel_irq_init(dev_priv);
+       intel_init_display_hooks(dev_priv);
+       intel_init_clock_gating_hooks(dev_priv);
+       intel_init_audio_hooks(dev_priv);
+       i915_gem_load_init(dev);
+
+       intel_display_crc_init(dev);
+
+       i915_dump_device_info(dev_priv);
+
+       /* Not all pre-production machines fall into this category, only the
+        * very first ones. Almost everything should work, except for maybe
+        * suspend/resume. And we don't implement workarounds that affect only
+        * pre-production machines. */
+       if (IS_HSW_EARLY_SDV(dev))
+               DRM_INFO("This is an early pre-production Haswell machine. "
+                        "It may not be fully functional.\n");
+
+       return 0;
+}
+
+/**
+ * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early()
+ * @dev_priv: device private
+ */
+static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv)
+{
+       i915_gem_load_cleanup(dev_priv->dev);
+       i915_workqueues_cleanup(dev_priv);
+}
+
 static int i915_mmio_setup(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = to_i915(dev);
@@ -987,64 +1064,21 @@ static void i915_mmio_cleanup(struct drm_device *dev)
 int i915_driver_load(struct drm_device *dev, unsigned long flags)
 {
        struct drm_i915_private *dev_priv;
-       struct intel_device_info *info, *device_info;
        int ret = 0;
        uint32_t aperture_size;
 
-       info = (struct intel_device_info *) flags;
-
        dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
        if (dev_priv == NULL)
                return -ENOMEM;
 
        dev->dev_private = dev_priv;
-       dev_priv->dev = dev;
 
-       /* Setup the write-once "constant" device info */
-       device_info = (struct intel_device_info *)&dev_priv->info;
-       memcpy(device_info, info, sizeof(dev_priv->info));
-       device_info->device_id = dev->pdev->device;
+       ret = i915_driver_init_early(dev_priv, dev,
+                                    (struct intel_device_info *)flags);
 
-       spin_lock_init(&dev_priv->irq_lock);
-       spin_lock_init(&dev_priv->gpu_error.lock);
-       mutex_init(&dev_priv->backlight_lock);
-       spin_lock_init(&dev_priv->uncore.lock);
-       spin_lock_init(&dev_priv->mm.object_stat_lock);
-       spin_lock_init(&dev_priv->mmio_flip_lock);
-       mutex_init(&dev_priv->sb_lock);
-       mutex_init(&dev_priv->modeset_restore_lock);
-       mutex_init(&dev_priv->av_mutex);
-       mutex_init(&dev_priv->wm.wm_mutex);
-       mutex_init(&dev_priv->pps_mutex);
-
-       ret = i915_workqueues_init(dev_priv);
        if (ret < 0)
                goto out_free_priv;
 
-       /* This must be called before any calls to HAS_PCH_* */
-       intel_detect_pch(dev);
-
-       intel_pm_setup(dev);
-       intel_init_dpio(dev_priv);
-       intel_power_domains_init(dev_priv);
-       intel_irq_init(dev_priv);
-       intel_init_display_hooks(dev_priv);
-       intel_init_clock_gating_hooks(dev_priv);
-       intel_init_audio_hooks(dev_priv);
-       i915_gem_load_init(dev);
-
-       intel_display_crc_init(dev);
-
-       i915_dump_device_info(dev_priv);
-
-       /* Not all pre-production machines fall into this category, only the
-        * very first ones. Almost everything should work, except for maybe
-        * suspend/resume. And we don't implement workarounds that affect only
-        * pre-production machines. */
-       if (IS_HSW_EARLY_SDV(dev))
-               DRM_INFO("This is an early pre-production Haswell machine. "
-                        "It may not be fully functional.\n");
-
        intel_runtime_pm_get(dev_priv);
 
        if (i915_get_bridge_dev(dev)) {
@@ -1191,8 +1225,7 @@ put_bridge:
        pci_dev_put(dev_priv->bridge_dev);
 out_runtime_pm_put:
        intel_runtime_pm_put(dev_priv);
-       i915_gem_load_cleanup(dev);
-       i915_workqueues_cleanup(dev_priv);
+       i915_driver_cleanup_early(dev_priv);
 out_free_priv:
        kfree(dev_priv);
 
@@ -1277,8 +1310,7 @@ int i915_driver_unload(struct drm_device *dev)
 
        intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
 
-       i915_gem_load_cleanup(dev);
-       i915_workqueues_cleanup(dev_priv);
+       i915_driver_cleanup_early(dev_priv);
        kfree(dev_priv);
 
        return 0;