drm/i915: Improve how the memory for crtc state is allocated
authorAnder Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Thu, 15 Jan 2015 12:55:26 +0000 (14:55 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 27 Jan 2015 08:50:51 +0000 (09:50 +0100)
The previous patch changed the config field in intel_crtc to a pointer,
but to keep the mechanical changes (done with spatch) separate from the
new code, the pointer was made to point to a new _config field with type
struct intel_crtc_state added to that struct. This patch improves that
code by getting rid of that field, allocating a state struct in
intel_crtc_init() a keeping it properly updated when a mode set
happens.

v2: Manual changes split from previous patch. (Matt)
    Don't leak the current state when the crtc is destroyed (Matt)

Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
[danvet: Squash in fixup from Matt Roper for driver unload.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h

index a333177..5f2601a 100644 (file)
@@ -8926,6 +8926,13 @@ out:
        intel_runtime_pm_put(dev_priv);
 }
 
+static void intel_crtc_set_state(struct intel_crtc *crtc,
+                                struct intel_crtc_state *crtc_state)
+{
+       kfree(crtc->config);
+       crtc->config = crtc_state;
+}
+
 static void intel_crtc_destroy(struct drm_crtc *crtc)
 {
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -8942,6 +8949,7 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
                kfree(work);
        }
 
+       intel_crtc_set_state(intel_crtc, NULL);
        drm_crtc_cleanup(crtc);
 
        kfree(intel_crtc);
@@ -10995,8 +11003,7 @@ static int __intel_set_mode(struct drm_crtc *crtc,
                crtc->mode = *mode;
                /* mode_set/enable/disable functions rely on a correct pipe
                 * config. */
-               (*(to_intel_crtc(crtc)->config)) = *pipe_config;
-               to_intel_crtc(crtc)->new_config = to_intel_crtc(crtc)->config;
+               intel_crtc_set_state(to_intel_crtc(crtc), pipe_config);
 
                /*
                 * Calculate and store various constants which
@@ -11040,7 +11047,6 @@ done:
        if (ret && crtc->enabled)
                crtc->mode = *saved_mode;
 
-       kfree(pipe_config);
        kfree(saved_mode);
        return ret;
 }
@@ -12186,6 +12192,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc;
+       struct intel_crtc_state *crtc_state = NULL;
        struct drm_plane *primary = NULL;
        struct drm_plane *cursor = NULL;
        int i, ret;
@@ -12194,6 +12201,11 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
        if (intel_crtc == NULL)
                return;
 
+       crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
+       if (!crtc_state)
+               goto fail;
+       intel_crtc_set_state(intel_crtc, crtc_state);
+
        primary = intel_primary_plane_create(dev, pipe);
        if (!primary)
                goto fail;
@@ -12239,7 +12251,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
        drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs);
 
        WARN_ON(drm_crtc_index(&intel_crtc->base) != intel_crtc->pipe);
-       intel_crtc->config = &intel_crtc->_config;
        return;
 
 fail:
@@ -12247,6 +12258,7 @@ fail:
                drm_plane_cleanup(primary);
        if (cursor)
                drm_plane_cleanup(cursor);
+       kfree(crtc_state);
        kfree(intel_crtc);
 }
 
index 7177a40..e4b83a6 100644 (file)
@@ -469,7 +469,6 @@ struct intel_crtc {
        uint32_t cursor_base;
 
        struct intel_plane_config plane_config;
-       struct intel_crtc_state _config;
        struct intel_crtc_state *config;
        struct intel_crtc_state *new_config;
        bool new_enabled;