[PATCH 16/22] drm/atomic: Pass old state explicitly to .atomic_duplicate_state()

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Thu Jul 6 20:24:36 UTC 2017


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

We'll be wanting to duplicate other states besides the one pointed to
by crtc->state & co., so pass the duplicated state in explicitly.

I wanted to make the old_state const, but that would have results in
tons of new warnings because some drivers have their to_foo_state()s
as static inlines. So I decided to leave old_state as non-const in
the end.

@r@
identifier F =~ "^[^_].*duplicate_.*state$";
identifier I;
type TO, TS;
@@
TS F(TO I
+   ,TS old_state
    )
{
<...
- I->state
+ old_state
...>
}

@@
identifier r.F;
expression E;
@@
F(E
+ ,E->state
  )

@@
type r.TO;
type r.TS;
type TF;
identifier I;
@@
TF {
...
TS (*atomic_duplicate_state)(TO I
+			     ,TS old_state
			     );
...
};

@@
expression X, E;
@@
X->atomic_duplicate_state(E
+                         ,E->state
			  )

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/arm/malidp_crtc.c               |  9 +++++----
 drivers/gpu/drm/arm/malidp_planes.c             |  9 +++++----
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c  |  9 +++++----
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |  5 +++--
 drivers/gpu/drm/drm_atomic.c                    | 10 ++++++----
 drivers/gpu/drm/drm_atomic_helper.c             | 21 ++++++++++++---------
 drivers/gpu/drm/drm_crtc_helper.c               | 12 ++++++++----
 drivers/gpu/drm/drm_dp_mst_topology.c           |  7 ++++---
 drivers/gpu/drm/drm_plane_helper.c              | 12 ++++++++----
 drivers/gpu/drm/exynos/exynos_drm_plane.c       |  7 ++++---
 drivers/gpu/drm/i915/intel_atomic.c             | 14 ++++++++------
 drivers/gpu/drm/i915/intel_atomic_plane.c       |  7 ++++---
 drivers/gpu/drm/i915/intel_display.c            |  2 +-
 drivers/gpu/drm/i915/intel_drv.h                |  9 ++++++---
 drivers/gpu/drm/i915/intel_sdvo.c               |  7 ++++---
 drivers/gpu/drm/imx/ipuv3-crtc.c                |  5 +++--
 drivers/gpu/drm/imx/ipuv3-plane.c               |  7 ++++---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c         |  5 +++--
 drivers/gpu/drm/mediatek/mtk_drm_plane.c        |  7 ++++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c        |  9 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c       | 13 +++++++------
 drivers/gpu/drm/nouveau/nouveau_connector.c     |  7 ++++---
 drivers/gpu/drm/nouveau/nouveau_connector.h     |  3 ++-
 drivers/gpu/drm/nouveau/nv50_display.c          | 14 ++++++++------
 drivers/gpu/drm/rcar-du/rcar_du_plane.c         |  9 +++++----
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c           |  9 +++++----
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c     |  5 +++--
 drivers/gpu/drm/tegra/dc.c                      | 14 ++++++++------
 drivers/gpu/drm/tegra/dsi.c                     |  7 ++++---
 drivers/gpu/drm/tegra/sor.c                     |  7 ++++---
 drivers/gpu/drm/vc4/vc4_crtc.c                  |  5 +++--
 drivers/gpu/drm/vc4/vc4_plane.c                 |  9 +++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c             | 25 ++++++++++++++-----------
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h             |  9 ++++++---
 include/drm/drm_atomic.h                        |  3 ++-
 include/drm/drm_atomic_helper.h                 |  9 ++++++---
 include/drm/drm_connector.h                     |  3 ++-
 include/drm/drm_crtc.h                          |  3 ++-
 include/drm/drm_plane.h                         |  3 ++-
 39 files changed, 194 insertions(+), 136 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c
index 2a92cb066bea..8c78cb13b23b 100644
--- a/drivers/gpu/drm/arm/malidp_crtc.c
+++ b/drivers/gpu/drm/arm/malidp_crtc.c
@@ -415,20 +415,21 @@ static const struct drm_crtc_helper_funcs malidp_crtc_helper_funcs = {
 	.atomic_disable = malidp_crtc_atomic_disable,
 };
 
-static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc,
+							  struct drm_crtc_state *old_state)
 {
 	struct malidp_crtc_state *state, *old_mali_state;
 
-	if (WARN_ON(!crtc->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	old_mali_state = to_malidp_crtc_state(crtc->state);
+	old_mali_state = to_malidp_crtc_state(old_state);
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base,
-						 crtc->state);
+						 old_state);
 	memcpy(state->gamma_coeffs, old_mali_state->gamma_coeffs,
 	       sizeof(state->gamma_coeffs));
 	memcpy(state->coloradj_coeffs, old_mali_state->coloradj_coeffs,
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index fe744396bc99..33b0c07ad3a3 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -86,20 +86,21 @@ static void malidp_plane_reset(struct drm_plane *plane)
 }
 
 static struct
-drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane)
+drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane,
+					      struct drm_plane_state *old_state)
 {
 	struct malidp_plane_state *state, *m_state;
 
-	if (!plane->state)
+	if (!old_state)
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
-	m_state = to_malidp_plane_state(plane->state);
+	m_state = to_malidp_plane_state(old_state);
 	__drm_atomic_helper_plane_duplicate_state(plane, &state->base,
-						  plane->state);
+						  old_state);
 	state->rotmem_size = m_state->rotmem_size;
 	state->format = m_state->format;
 	state->n_planes = m_state->n_planes;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index bb7c5eb9526a..cabba730c79a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -375,20 +375,21 @@ static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc)
 }
 
 static struct drm_crtc_state *
-atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
+atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc,
+				 struct drm_crtc_state *old_state)
 {
 	struct atmel_hlcdc_crtc_state *state, *cur;
 
-	if (WARN_ON(!crtc->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base,
-						 crtc->state);
+						 old_state);
 
-	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
+	cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(old_state);
 	state->output_mode = cur->output_mode;
 
 	return &state->base;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index b5bd9b005225..2ebf5c632a7a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -1009,10 +1009,11 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p)
 }
 
 static struct drm_plane_state *
-atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p)
+atmel_hlcdc_plane_atomic_duplicate_state(struct drm_plane *p,
+					 struct drm_plane_state *old_state)
 {
 	struct atmel_hlcdc_plane_state *state =
-			drm_plane_state_to_atmel_hlcdc_plane_state(p->state);
+			drm_plane_state_to_atmel_hlcdc_plane_state(old_state);
 	struct atmel_hlcdc_plane_state *copy;
 
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index da7752230e4c..b1983e7b65d2 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -294,7 +294,7 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
 	if (ret)
 		return ERR_PTR(ret);
 
-	crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
+	crtc_state = crtc->funcs->atomic_duplicate_state(crtc, crtc->state);
 	if (!crtc_state)
 		return ERR_PTR(-ENOMEM);
 
@@ -709,7 +709,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
 	if (ret)
 		return ERR_PTR(ret);
 
-	plane_state = plane->funcs->atomic_duplicate_state(plane);
+	plane_state = plane->funcs->atomic_duplicate_state(plane,
+							   plane->state);
 	if (!plane_state)
 		return ERR_PTR(-ENOMEM);
 
@@ -1072,7 +1073,7 @@ drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
 
 	p = __drm_atomic_state_private_obj(state, index);
 
-	obj_state = funcs->atomic_duplicate_state(obj);
+	obj_state = funcs->atomic_duplicate_state(obj, obj->state);
 	if (!obj_state)
 		return ERR_PTR(-ENOMEM);
 
@@ -1133,7 +1134,8 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
 	if (c->state)
 		return c->state;
 
-	connector_state = connector->funcs->atomic_duplicate_state(connector);
+	connector_state = connector->funcs->atomic_duplicate_state(connector,
+								   connector->state);
 	if (!connector_state)
 		return ERR_PTR(-ENOMEM);
 
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 0745a08a6cc2..c60fb6289276 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3406,17 +3406,18 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
  * subclassed CRTC state structure.
  */
 struct drm_crtc_state *
-drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
+drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
+				       struct drm_crtc_state *old_state)
 {
 	struct drm_crtc_state *state;
 
-	if (WARN_ON(!crtc->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (state)
 		__drm_atomic_helper_crtc_duplicate_state(crtc, state,
-							 crtc->state);
+							 old_state);
 
 	return state;
 }
@@ -3506,17 +3507,18 @@ EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
  * subclassed plane state structure.
  */
 struct drm_plane_state *
-drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
+drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
+					struct drm_plane_state *old_state)
 {
 	struct drm_plane_state *state;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (state)
 		__drm_atomic_helper_plane_duplicate_state(plane, state,
-							  plane->state);
+							  old_state);
 
 	return state;
 }
@@ -3627,18 +3629,19 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
  * subclassed connector state structure.
  */
 struct drm_connector_state *
-drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
+drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
+					    struct drm_connector_state *old_state)
 {
 	struct drm_connector_state *state;
 
-	if (WARN_ON(!connector->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (state)
 		__drm_atomic_helper_connector_duplicate_state(connector,
 							      state,
-							      connector->state);
+							      old_state);
 
 	return state;
 }
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 4afdf7902eda..d0806c5cc472 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -1011,12 +1011,14 @@ int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mod
 	int ret;
 
 	if (crtc->funcs->atomic_duplicate_state)
-		crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
+		crtc_state = crtc->funcs->atomic_duplicate_state(crtc,
+								 crtc->state);
 	else {
 		if (!crtc->state)
 			drm_atomic_helper_crtc_reset(crtc);
 
-		crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc);
+		crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc,
+								    crtc->state);
 	}
 
 	if (!crtc_state)
@@ -1074,12 +1076,14 @@ int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 	struct drm_plane *plane = crtc->primary;
 
 	if (plane->funcs->atomic_duplicate_state)
-		plane_state = plane->funcs->atomic_duplicate_state(plane);
+		plane_state = plane->funcs->atomic_duplicate_state(plane,
+								   plane->state);
 	else {
 		if (!plane->state)
 			drm_atomic_helper_plane_reset(plane);
 
-		plane_state = drm_atomic_helper_plane_duplicate_state(plane);
+		plane_state = drm_atomic_helper_plane_duplicate_state(plane,
+								      plane->state);
 	}
 	if (!plane_state)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index 140c24258b7b..d679fcb9b912 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2995,16 +2995,17 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
 }
 
 static struct drm_private_state *
-drm_dp_mst_duplicate_state(struct drm_private_obj *obj)
+drm_dp_mst_duplicate_state(struct drm_private_obj *obj,
+			   struct drm_private_state *old_state)
 {
 	struct drm_dp_mst_topology_state *state;
 
-	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
 	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base,
-							obj->state);
+							old_state);
 
 	return &state->base;
 }
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 06aee1741e96..cf3bbc4a3f6b 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -552,12 +552,14 @@ int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
 	struct drm_plane_state *plane_state;
 
 	if (plane->funcs->atomic_duplicate_state)
-		plane_state = plane->funcs->atomic_duplicate_state(plane);
+		plane_state = plane->funcs->atomic_duplicate_state(plane,
+								   plane->state);
 	else {
 		if (!plane->state)
 			drm_atomic_helper_plane_reset(plane);
 
-		plane_state = drm_atomic_helper_plane_duplicate_state(plane);
+		plane_state = drm_atomic_helper_plane_duplicate_state(plane,
+								      plane->state);
 	}
 	if (!plane_state)
 		return -ENOMEM;
@@ -601,12 +603,14 @@ int drm_plane_helper_disable(struct drm_plane *plane)
 		return 0;
 
 	if (plane->funcs->atomic_duplicate_state)
-		plane_state = plane->funcs->atomic_duplicate_state(plane);
+		plane_state = plane->funcs->atomic_duplicate_state(plane,
+								   plane->state);
 	else {
 		if (!plane->state)
 			drm_atomic_helper_plane_reset(plane);
 
-		plane_state = drm_atomic_helper_plane_duplicate_state(plane);
+		plane_state = drm_atomic_helper_plane_duplicate_state(plane,
+								      plane->state);
 	}
 	if (!plane_state)
 		return -ENOMEM;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 1807f4c7bcf6..fc57e880f75c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -146,18 +146,19 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
 }
 
 static struct drm_plane_state *
-exynos_drm_plane_duplicate_state(struct drm_plane *plane)
+exynos_drm_plane_duplicate_state(struct drm_plane *plane,
+				 struct drm_plane_state *old_state)
 {
 	struct exynos_drm_plane_state *exynos_state;
 	struct exynos_drm_plane_state *copy;
 
-	exynos_state = to_exynos_plane_state(plane->state);
+	exynos_state = to_exynos_plane_state(old_state);
 	copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
 	if (!copy)
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &copy->base,
-						  plane->state);
+						  old_state);
 	return &copy->base;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index e5d5a558c84a..978902d19c5f 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -138,16 +138,17 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn,
  * Returns: The newly allocated connector state, or NULL on failure.
  */
 struct drm_connector_state *
-intel_digital_connector_duplicate_state(struct drm_connector *connector)
+intel_digital_connector_duplicate_state(struct drm_connector *connector,
+					struct drm_connector_state *old_state)
 {
 	struct intel_digital_connector_state *state;
 
-	state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
+	state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
 	__drm_atomic_helper_connector_duplicate_state(connector, &state->base,
-						      connector->state);
+						      old_state);
 	return &state->base;
 }
 
@@ -161,16 +162,17 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector)
  * Returns: The newly allocated crtc state, or NULL on failure.
  */
 struct drm_crtc_state *
-intel_crtc_duplicate_state(struct drm_crtc *crtc)
+intel_crtc_duplicate_state(struct drm_crtc *crtc,
+			   struct drm_crtc_state *old_state)
 {
 	struct intel_crtc_state *crtc_state;
 
-	crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
+	crtc_state = kmemdup(old_state, sizeof(*crtc_state), GFP_KERNEL);
 	if (!crtc_state)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base,
-						 crtc->state);
+						 old_state);
 
 	crtc_state->update_pipe = false;
 	crtc_state->disable_lp_wm = false;
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
index 41a7354c14d3..4716e8dadba8 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -71,19 +71,20 @@ intel_create_plane_state(struct drm_plane *plane)
  * Returns: The newly allocated plane state, or NULL on failure.
  */
 struct drm_plane_state *
-intel_plane_duplicate_state(struct drm_plane *plane)
+intel_plane_duplicate_state(struct drm_plane *plane,
+			    struct drm_plane_state *old_state)
 {
 	struct drm_plane_state *state;
 	struct intel_plane_state *intel_state;
 
-	intel_state = kmemdup(plane->state, sizeof(*intel_state), GFP_KERNEL);
+	intel_state = kmemdup(old_state, sizeof(*intel_state), GFP_KERNEL);
 
 	if (!intel_state)
 		return NULL;
 
 	state = &intel_state->base;
 
-	__drm_atomic_helper_plane_duplicate_state(plane, state, plane->state);
+	__drm_atomic_helper_plane_duplicate_state(plane, state, old_state);
 
 	intel_state->vma = NULL;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 791204c8621c..1016afebef27 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13646,7 +13646,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 	    !old_plane_state->fb != !fb)
 		goto slow;
 
-	new_plane_state = intel_plane_duplicate_state(plane);
+	new_plane_state = intel_plane_duplicate_state(plane, plane->state);
 	if (!new_plane_state)
 		return -ENOMEM;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index ea36d1a61e86..4be10983e7cc 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1945,9 +1945,11 @@ int intel_digital_connector_atomic_set_property(struct drm_connector *connector,
 int intel_digital_connector_atomic_check(struct drm_connector *conn,
 					 struct drm_connector_state *new_state);
 struct drm_connector_state *
-intel_digital_connector_duplicate_state(struct drm_connector *connector);
+intel_digital_connector_duplicate_state(struct drm_connector *connector,
+					struct drm_connector_state *old_state);
 
-struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
+struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc,
+						  struct drm_crtc_state *old_state);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
 struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
@@ -1996,7 +1998,8 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
 
 /* intel_atomic_plane.c */
 struct intel_plane_state *intel_create_plane_state(struct drm_plane *plane);
-struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
+struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane,
+						    struct drm_plane_state *old_state);
 void intel_plane_destroy_state(struct drm_plane *plane,
 			       struct drm_plane_state *state);
 extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 0d14807b38a5..9ed722b1c6fd 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2179,17 +2179,18 @@ intel_sdvo_connector_unregister(struct drm_connector *connector)
 }
 
 static struct drm_connector_state *
-intel_sdvo_connector_duplicate_state(struct drm_connector *connector)
+intel_sdvo_connector_duplicate_state(struct drm_connector *connector,
+				     struct drm_connector_state *old_state)
 {
 	struct intel_sdvo_connector_state *state;
 
-	state = kmemdup(connector->state, sizeof(*state), GFP_KERNEL);
+	state = kmemdup(old_state, sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
 	__drm_atomic_helper_connector_duplicate_state(connector,
 						      &state->base.base,
-						      connector->state);
+						      old_state);
 	return &state->base.base;
 }
 
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 44598b6a5cfc..666c02f27a3c 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -129,7 +129,8 @@ static void imx_drm_crtc_reset(struct drm_crtc *crtc)
 	state->base.crtc = crtc;
 }
 
-static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc,
+							   struct drm_crtc_state *old_state)
 {
 	struct imx_crtc_state *state;
 
@@ -138,7 +139,7 @@ static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base,
-						 crtc->state);
+						 old_state);
 
 	WARN_ON(state->base.crtc != crtc);
 	state->base.crtc = crtc;
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 3b3c979c4f6d..474fff30ae79 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -279,17 +279,18 @@ void ipu_plane_state_reset(struct drm_plane *plane)
 	plane->state = &ipu_state->base;
 }
 
-struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
+struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane,
+						  struct drm_plane_state *old_state)
 {
 	struct ipu_plane_state *state;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
 	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (state)
 		__drm_atomic_helper_plane_duplicate_state(plane, &state->base,
-							  plane->state);
+							  old_state);
 
 	return &state->base;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 4bdc612fbe89..c11d0f26a4b5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -126,7 +126,8 @@ static void mtk_drm_crtc_reset(struct drm_crtc *crtc)
 	state->base.crtc = crtc;
 }
 
-static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc,
+							   struct drm_crtc_state *old_state)
 {
 	struct mtk_crtc_state *state;
 
@@ -135,7 +136,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base,
-						 crtc->state);
+						 old_state);
 
 	WARN_ON(state->base.crtc != crtc);
 	state->base.crtc = crtc;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 67c7bd17e350..a0ccad4c577e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -50,9 +50,10 @@ static void mtk_plane_reset(struct drm_plane *plane)
 	state->pending.format = DRM_FORMAT_RGB565;
 }
 
-static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane)
+static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane,
+							 struct drm_plane_state *old_state)
 {
-	struct mtk_plane_state *old_mtk_state = to_mtk_plane_state(plane->state);
+	struct mtk_plane_state *old_mtk_state = to_mtk_plane_state(old_state);
 	struct mtk_plane_state *state;
 
 	state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -60,7 +61,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &state->base,
-						  plane->state);
+						  old_state);
 
 	WARN_ON(state->base.plane != plane);
 
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 49c7410d0ef6..2f0d08dc15b1 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -889,20 +889,21 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc)
 }
 
 static struct drm_crtc_state *
-mdp5_crtc_duplicate_state(struct drm_crtc *crtc)
+mdp5_crtc_duplicate_state(struct drm_crtc *crtc,
+			  struct drm_crtc_state *old_state)
 {
 	struct mdp5_crtc_state *mdp5_cstate;
 
-	if (WARN_ON(!crtc->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	mdp5_cstate = kmemdup(to_mdp5_crtc_state(crtc->state),
+	mdp5_cstate = kmemdup(to_mdp5_crtc_state(old_state),
 			      sizeof(*mdp5_cstate), GFP_KERNEL);
 	if (!mdp5_cstate)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &mdp5_cstate->base,
-						 crtc->state);
+						 old_state);
 
 	return &mdp5_cstate->base;
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index de00c9ad14fd..7400632877ff 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -214,20 +214,21 @@ static void mdp5_plane_reset(struct drm_plane *plane)
 }
 
 static struct drm_plane_state *
-mdp5_plane_duplicate_state(struct drm_plane *plane)
+mdp5_plane_duplicate_state(struct drm_plane *plane,
+			   struct drm_plane_state *old_state)
 {
 	struct mdp5_plane_state *mdp5_state;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	mdp5_state = kmemdup(to_mdp5_plane_state(plane->state),
-			sizeof(*mdp5_state), GFP_KERNEL);
+	mdp5_state = kmemdup(to_mdp5_plane_state(old_state),
+			     sizeof(*mdp5_state), GFP_KERNEL);
 	if (!mdp5_state)
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &mdp5_state->base,
-						  plane->state);
+						  old_state);
 
 	return &mdp5_state->base;
 }
@@ -1032,7 +1033,7 @@ static int mdp5_update_cursor_plane_legacy(struct drm_plane *plane,
 	    plane_state->fb != fb)
 		goto slow;
 
-	new_plane_state = mdp5_plane_duplicate_state(plane);
+	new_plane_state = mdp5_plane_duplicate_state(plane, plane->state);
 	if (!new_plane_state)
 		return -ENOMEM;
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index dc1880eb00bf..4418220e3d6c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -228,14 +228,15 @@ nouveau_conn_atomic_destroy_state(struct drm_connector *connector,
 }
 
 struct drm_connector_state *
-nouveau_conn_atomic_duplicate_state(struct drm_connector *connector)
+nouveau_conn_atomic_duplicate_state(struct drm_connector *connector,
+				    struct drm_connector_state *old_state)
 {
-	struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state);
+	struct nouveau_conn_atom *armc = nouveau_conn_atom(old_state);
 	struct nouveau_conn_atom *asyc;
 	if (!(asyc = kmalloc(sizeof(*asyc), GFP_KERNEL)))
 		return NULL;
 	__drm_atomic_helper_connector_duplicate_state(connector, &asyc->state,
-						      connector->state);
+						      old_state);
 	asyc->dither = armc->dither;
 	asyc->scaler = armc->scaler;
 	asyc->procamp = armc->procamp;
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index a4d1a059bd3d..2e4b20f5ffb7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -141,7 +141,8 @@ struct nouveau_conn_atom {
 void nouveau_conn_attach_properties(struct drm_connector *);
 void nouveau_conn_reset(struct drm_connector *);
 struct drm_connector_state *
-nouveau_conn_atomic_duplicate_state(struct drm_connector *);
+nouveau_conn_atomic_duplicate_state(struct drm_connector *,
+				    struct drm_connector_state *);
 void nouveau_conn_atomic_destroy_state(struct drm_connector *,
 				       struct drm_connector_state *);
 int nouveau_conn_atomic_set_property(struct drm_connector *,
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 6ca8d97e7dbc..a2401c3894a1 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1005,14 +1005,15 @@ nv50_wndw_atomic_destroy_state(struct drm_plane *plane,
 }
 
 static struct drm_plane_state *
-nv50_wndw_atomic_duplicate_state(struct drm_plane *plane)
+nv50_wndw_atomic_duplicate_state(struct drm_plane *plane,
+				 struct drm_plane_state *old_state)
 {
-	struct nv50_wndw_atom *armw = nv50_wndw_atom(plane->state);
+	struct nv50_wndw_atom *armw = nv50_wndw_atom(old_state);
 	struct nv50_wndw_atom *asyw;
 	if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL)))
 		return NULL;
 	__drm_atomic_helper_plane_duplicate_state(plane, &asyw->state,
-						  plane->state);
+						  old_state);
 	asyw->interval = 1;
 	asyw->sema = armw->sema;
 	asyw->ntfy = armw->ntfy;
@@ -2258,14 +2259,15 @@ nv50_head_atomic_destroy_state(struct drm_crtc *crtc,
 }
 
 static struct drm_crtc_state *
-nv50_head_atomic_duplicate_state(struct drm_crtc *crtc)
+nv50_head_atomic_duplicate_state(struct drm_crtc *crtc,
+				 struct drm_crtc_state *old_state)
 {
-	struct nv50_head_atom *armh = nv50_head_atom(crtc->state);
+	struct nv50_head_atom *armh = nv50_head_atom(old_state);
 	struct nv50_head_atom *asyh;
 	if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL)))
 		return NULL;
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state,
-						 crtc->state);
+						 old_state);
 	asyh->view = armh->view;
 	asyh->mode = armh->mode;
 	asyh->lut  = armh->lut;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index a856507f5717..a46a5eee89ef 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -610,21 +610,22 @@ static const struct drm_plane_helper_funcs rcar_du_plane_helper_funcs = {
 };
 
 static struct drm_plane_state *
-rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane)
+rcar_du_plane_atomic_duplicate_state(struct drm_plane *plane,
+				     struct drm_plane_state *old_state)
 {
 	struct rcar_du_plane_state *state;
 	struct rcar_du_plane_state *copy;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	state = to_rcar_plane_state(plane->state);
+	state = to_rcar_plane_state(old_state);
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
 	if (copy == NULL)
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &copy->state,
-						  plane->state);
+						  old_state);
 
 	return &copy->state;
 }
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index 21a30775edb7..5f1547f4215e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -303,21 +303,22 @@ static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
 };
 
 static struct drm_plane_state *
-rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane)
+rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane,
+					 struct drm_plane_state *old_state)
 {
 	struct rcar_du_vsp_plane_state *state;
 	struct rcar_du_vsp_plane_state *copy;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	state = to_rcar_vsp_plane_state(plane->state);
+	state = to_rcar_vsp_plane_state(old_state);
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
 	if (copy == NULL)
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &copy->state,
-						  plane->state);
+						  old_state);
 
 	return &copy->state;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9f586f698e52..a8af4d752b68 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1104,7 +1104,8 @@ static void vop_crtc_reset(struct drm_crtc *crtc)
 		crtc->state->crtc = crtc;
 }
 
-static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc,
+						       struct drm_crtc_state *old_state)
 {
 	struct rockchip_crtc_state *rockchip_state;
 
@@ -1113,7 +1114,7 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &rockchip_state->base,
-						 crtc->state);
+						 old_state);
 	return &rockchip_state->base;
 }
 
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index d725115d011d..5e3d02ae9653 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -448,9 +448,10 @@ static void tegra_plane_reset(struct drm_plane *plane)
 	}
 }
 
-static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
+static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_plane *plane,
+								  struct drm_plane_state *old_state)
 {
-	struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
+	struct tegra_plane_state *state = to_tegra_plane_state(old_state);
 	struct tegra_plane_state *copy;
 
 	copy = kmalloc(sizeof(*copy), GFP_KERNEL);
@@ -458,7 +459,7 @@ static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_pla
 		return NULL;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &copy->base,
-						  plane->state);
+						  old_state);
 	copy->tiling = state->tiling;
 	copy->format = state->format;
 	copy->swap = state->swap;
@@ -1034,9 +1035,10 @@ static void tegra_crtc_reset(struct drm_crtc *crtc)
 }
 
 static struct drm_crtc_state *
-tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
+tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc,
+				  struct drm_crtc_state *old_state)
 {
-	struct tegra_dc_state *state = to_dc_state(crtc->state);
+	struct tegra_dc_state *state = to_dc_state(old_state);
 	struct tegra_dc_state *copy;
 
 	copy = kmalloc(sizeof(*copy), GFP_KERNEL);
@@ -1044,7 +1046,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &copy->base,
-						 crtc->state);
+						 old_state);
 	copy->clk = state->clk;
 	copy->pclk = state->pclk;
 	copy->div = state->div;
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c
index ce646493e939..9156434e0627 100644
--- a/drivers/gpu/drm/tegra/dsi.c
+++ b/drivers/gpu/drm/tegra/dsi.c
@@ -799,9 +799,10 @@ static void tegra_dsi_connector_reset(struct drm_connector *connector)
 }
 
 static struct drm_connector_state *
-tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
+tegra_dsi_connector_duplicate_state(struct drm_connector *connector,
+				    struct drm_connector_state *old_state)
 {
-	struct tegra_dsi_state *state = to_dsi_state(connector->state);
+	struct tegra_dsi_state *state = to_dsi_state(old_state);
 	struct tegra_dsi_state *copy;
 
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
@@ -810,7 +811,7 @@ tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
 
 	__drm_atomic_helper_connector_duplicate_state(connector,
 						      &copy->base,
-						      connector->state);
+						      old_state);
 
 	return &copy->base;
 }
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 02c3439c2e96..4e79ae0561cd 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -1325,9 +1325,10 @@ tegra_sor_connector_detect(struct drm_connector *connector, bool force)
 }
 
 static struct drm_connector_state *
-tegra_sor_connector_duplicate_state(struct drm_connector *connector)
+tegra_sor_connector_duplicate_state(struct drm_connector *connector,
+				    struct drm_connector_state *old_state)
 {
-	struct tegra_sor_state *state = to_sor_state(connector->state);
+	struct tegra_sor_state *state = to_sor_state(old_state);
 	struct tegra_sor_state *copy;
 
 	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
@@ -1335,7 +1336,7 @@ tegra_sor_connector_duplicate_state(struct drm_connector *connector)
 		return NULL;
 
 	__drm_atomic_helper_connector_duplicate_state(connector, &copy->base,
-						      connector->state);
+						      old_state);
 
 	return &copy->base;
 }
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 28bdfb5adb9e..1d7e46af7450 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -813,7 +813,8 @@ static int vc4_page_flip(struct drm_crtc *crtc,
 		return drm_atomic_helper_page_flip(crtc, fb, event, flags, ctx);
 }
 
-static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
+static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc,
+						       struct drm_crtc_state *old_state)
 {
 	struct vc4_crtc_state *vc4_state;
 
@@ -822,7 +823,7 @@ static struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc)
 		return NULL;
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &vc4_state->base,
-						 crtc->state);
+						 old_state);
 	return &vc4_state->base;
 }
 
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 43b388a42c1e..0c57309d6c2f 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -174,21 +174,22 @@ static bool plane_enabled(struct drm_plane_state *state)
 	return state->fb && state->crtc;
 }
 
-static struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane)
+static struct drm_plane_state *vc4_plane_duplicate_state(struct drm_plane *plane,
+							 struct drm_plane_state *old_state)
 {
 	struct vc4_plane_state *vc4_state;
 
-	if (WARN_ON(!plane->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	vc4_state = kmemdup(plane->state, sizeof(*vc4_state), GFP_KERNEL);
+	vc4_state = kmemdup(old_state, sizeof(*vc4_state), GFP_KERNEL);
 	if (!vc4_state)
 		return NULL;
 
 	memset(&vc4_state->lbm, 0, sizeof(vc4_state->lbm));
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &vc4_state->base,
-						  plane->state);
+						  old_state);
 
 	if (vc4_state->dlist) {
 		vc4_state->dlist = kmemdup(vc4_state->dlist,
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index dc3b4a9e3d25..946f11c93619 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -597,22 +597,23 @@ void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
  * Returns: The newly allocated crtc state, or NULL on failure.
  */
 struct drm_crtc_state *
-vmw_du_crtc_duplicate_state(struct drm_crtc *crtc)
+vmw_du_crtc_duplicate_state(struct drm_crtc *crtc,
+			    struct drm_crtc_state *old_state)
 {
 	struct drm_crtc_state *state;
 	struct vmw_crtc_state *vcs;
 
-	if (WARN_ON(!crtc->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	vcs = kmemdup(crtc->state, sizeof(*vcs), GFP_KERNEL);
+	vcs = kmemdup(old_state, sizeof(*vcs), GFP_KERNEL);
 
 	if (!vcs)
 		return NULL;
 
 	state = &vcs->base;
 
-	__drm_atomic_helper_crtc_duplicate_state(crtc, state, crtc->state);
+	__drm_atomic_helper_crtc_duplicate_state(crtc, state, old_state);
 
 	return state;
 }
@@ -675,12 +676,13 @@ vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
  * Returns: The newly allocated plane state, or NULL on failure.
  */
 struct drm_plane_state *
-vmw_du_plane_duplicate_state(struct drm_plane *plane)
+vmw_du_plane_duplicate_state(struct drm_plane *plane,
+			     struct drm_plane_state *old_state)
 {
 	struct drm_plane_state *state;
 	struct vmw_plane_state *vps;
 
-	vps = kmemdup(plane->state, sizeof(*vps), GFP_KERNEL);
+	vps = kmemdup(old_state, sizeof(*vps), GFP_KERNEL);
 
 	if (!vps)
 		return NULL;
@@ -701,7 +703,7 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane)
 
 	state = &vps->base;
 
-	__drm_atomic_helper_plane_duplicate_state(plane, state, plane->state);
+	__drm_atomic_helper_plane_duplicate_state(plane, state, old_state);
 
 	return state;
 }
@@ -781,15 +783,16 @@ vmw_du_plane_destroy_state(struct drm_plane *plane,
  * Returns: The newly allocated connector state, or NULL on failure.
  */
 struct drm_connector_state *
-vmw_du_connector_duplicate_state(struct drm_connector *connector)
+vmw_du_connector_duplicate_state(struct drm_connector *connector,
+				 struct drm_connector_state *old_state)
 {
 	struct drm_connector_state *state;
 	struct vmw_connector_state *vcs;
 
-	if (WARN_ON(!connector->state))
+	if (WARN_ON(!old_state))
 		return NULL;
 
-	vcs = kmemdup(connector->state, sizeof(*vcs), GFP_KERNEL);
+	vcs = kmemdup(old_state, sizeof(*vcs), GFP_KERNEL);
 
 	if (!vcs)
 		return NULL;
@@ -797,7 +800,7 @@ vmw_du_connector_duplicate_state(struct drm_connector *connector)
 	state = &vcs->base;
 
 	__drm_atomic_helper_connector_duplicate_state(connector, state,
-						      connector->state);
+						      old_state);
 
 	return state;
 }
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index ff9c8389ff21..4769c8a412c2 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -348,7 +348,8 @@ int vmw_du_cursor_plane_prepare_fb(struct drm_plane *plane,
 void vmw_du_plane_cleanup_fb(struct drm_plane *plane,
 			     struct drm_plane_state *old_state);
 void vmw_du_plane_reset(struct drm_plane *plane);
-struct drm_plane_state *vmw_du_plane_duplicate_state(struct drm_plane *plane);
+struct drm_plane_state *vmw_du_plane_duplicate_state(struct drm_plane *plane,
+						     struct drm_plane_state *old_state);
 void vmw_du_plane_destroy_state(struct drm_plane *plane,
 				struct drm_plane_state *state);
 void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
@@ -361,12 +362,14 @@ void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc,
 void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc,
 			      struct drm_crtc_state *old_crtc_state);
 void vmw_du_crtc_reset(struct drm_crtc *crtc);
-struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc);
+struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc,
+						   struct drm_crtc_state *old_state);
 void vmw_du_crtc_destroy_state(struct drm_crtc *crtc,
 				struct drm_crtc_state *state);
 void vmw_du_connector_reset(struct drm_connector *connector);
 struct drm_connector_state *
-vmw_du_connector_duplicate_state(struct drm_connector *connector);
+vmw_du_connector_duplicate_state(struct drm_connector *connector,
+				 struct drm_connector_state *old_state);
 
 void vmw_du_connector_destroy_state(struct drm_connector *connector,
 				    struct drm_connector_state *state);
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index addec49a14bf..0e6c54b3e0af 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -180,7 +180,8 @@ struct drm_private_state_funcs {
 	 * Duplicated atomic state or NULL when obj->state is not
 	 * initialized or allocation failed.
 	 */
-	struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj);
+	struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj,
+							    struct drm_private_state *old_state);
 
 	/**
 	 * @atomic_destroy_state:
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 0adacaca0941..b799687a4b09 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -155,7 +155,8 @@ void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
 					      struct drm_crtc_state *state,
 					      const struct drm_crtc_state *old_state);
 struct drm_crtc_state *
-drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
+drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
+				       struct drm_crtc_state *old_state);
 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state);
 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 					  struct drm_crtc_state *state);
@@ -165,7 +166,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 					       struct drm_plane_state *state,
 					       const struct drm_plane_state *old_state);
 struct drm_plane_state *
-drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane);
+drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
+					struct drm_plane_state *old_state);
 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state);
 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
 					  struct drm_plane_state *state);
@@ -178,7 +180,8 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
 					   struct drm_connector_state *state,
 					   const struct drm_connector_state *old_state);
 struct drm_connector_state *
-drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector);
+drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
+					    struct drm_connector_state *old_state);
 struct drm_atomic_state *
 drm_atomic_helper_duplicate_state(struct drm_device *dev,
 				  struct drm_modeset_acquire_ctx *ctx);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ae5b7dc316c8..ee9a15a87db5 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -540,7 +540,8 @@ struct drm_connector_funcs {
 	 *
 	 * Duplicated atomic state or NULL when the allocation failed.
 	 */
-	struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector);
+	struct drm_connector_state *(*atomic_duplicate_state)(struct drm_connector *connector,
+							      struct drm_connector_state *old_state);
 
 	/**
 	 * @atomic_destroy_state:
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 3a911a64c257..1d187331fe5d 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -523,7 +523,8 @@ struct drm_crtc_funcs {
 	 *
 	 * Duplicated atomic state or NULL when the allocation failed.
 	 */
-	struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc);
+	struct drm_crtc_state *(*atomic_duplicate_state)(struct drm_crtc *crtc,
+							 struct drm_crtc_state *old_state);
 
 	/**
 	 * @atomic_destroy_state:
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 9ab3e7044812..f01023ed1c7b 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -275,7 +275,8 @@ struct drm_plane_funcs {
 	 *
 	 * Duplicated atomic state or NULL when the allocation failed.
 	 */
-	struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane);
+	struct drm_plane_state *(*atomic_duplicate_state)(struct drm_plane *plane,
+							  struct drm_plane_state *old_state);
 
 	/**
 	 * @atomic_destroy_state:
-- 
2.13.0



More information about the dri-devel mailing list