Skip to contentSkip to conversation

drm/atomic: Allocate drm_private_state through a callback

PATCH Applied Maxime Ripard 3 participants 8 messages Feb 24 – Mar 20

Subsystems (15)
lore
Share & tools
lore

Maxime Ripard

author maintainer
#0 lore raw

v5 cover drm/atomic: Allocate drm_private_state through a callback

Hi,

This series started from my work on the hardware state readout[1], and was suggested by Dmitry[2].

This series deal with the fact that drm_private_obj (and thus bridges) are not initialized using the same pattern than any other object. This series solves that inconsistency by aligning it to what we're doing for all the other objects.

This was tested on a TI SK-AM62, with three bridges.

Let me know what you think,
Maxime

1: https://lore.kernel.org/dri-devel/[email protected]/
2: https://lore.kernel.org/dri-devel/zvqtehg66dbrrdmik6ylo2kdk74umfzo5hbfkizwsb352nlyqv@jgouvmbfwa4x/

---
Changes in v5:
- Rebase to drm-misc-next
- Link to v4: https://lore.kernel.org/r/[email protected]

Changes in v4:
- Fix a circular dependencies between modules by calling __drm_atomic_helper_private_obj_create_state from __drm_atomic_helper_bridge_reset instead of
drm_bridge_atomic_create_priv_state()
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Switch to a new hook instead of reset since some drm_private_objs want
to persist across suspends
- Drop the call to drm_private_obj_funcs.reset in
drm_mode_config_reset()
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Maxime Ripard (4):
drm/amdgpu: Switch private_obj initialization to atomic_create_state drm/omapdrm: Switch private_obj initialization to atomic_create_state drm/tegra: Switch private_obj initialization to atomic_create_state drm/atomic: Remove state argument to drm_atomic_private_obj_init

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 51 ++++++++++++----------
 .../drm/arm/display/komeda/komeda_private_obj.c    | 16 +++----
 drivers/gpu/drm/display/drm_dp_mst_topology.c      |  1 -
 drivers/gpu/drm/display/drm_dp_tunnel.c            |  2 +-
 drivers/gpu/drm/drm_atomic.c                       | 22 +++-------
 drivers/gpu/drm/drm_bridge.c                       |  1 -
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c          |  2 +-
 drivers/gpu/drm/ingenic/ingenic-ipu.c              |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  1 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c           |  1 -
 drivers/gpu/drm/omapdrm/omap_drv.c                 | 22 +++++++---
 drivers/gpu/drm/tegra/hub.c                        | 22 +++++++---
 drivers/gpu/drm/vc4/vc4_kms.c                      |  4 +-
 include/drm/drm_atomic.h                           |  1 -
 14 files changed, 76 insertions(+), 72 deletions(-)

---
base-commit: 196b2b95fec447c2c4460f753b277d840633fbef
change-id: 20251008-drm-private-obj-reset-ae1e2741027a

Best regards,

Signature · 1 line
Maxime Ripard <[email protected]>
author maintainer
#1 lore raw

PATCH v5 1/4 drm/amdgpu: Switch private_obj initialization to atomic_create_state

The amdgpu driver relies on a drm_private_obj, that is initialized by allocating and initializing a state, and then passing it to drm_private_obj_init.

Since we're gradually moving away from that pattern to the more established one relying on a atomic_create_state implementation, let's migrate this instance to the new pattern.

---

Cc Harry Wentland <[email protected]>
Cc Leo Li <[email protected]>
Cc Rodrigo Siqueira <[email protected]>
Cc Alex Deucher <[email protected]>
Cc "Christian König" <[email protected]>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 52 ++++++++++++-----------
 1 file changed, 28 insertions(+), 24 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +28 -24
index a8e4e3ab5e40276b3c723297ca6520688079e0a7..98ed54afb02864342bb2c04782d05c5fb6e38672 100644
@@ -4912,18 +4912,41 @@ static void dm_atomic_destroy_state(struct drm_private_obj *obj,
 		dc_state_release(dm_state->context);
 
 	kfree(dm_state);
 }
 
+static struct drm_private_state *
+dm_atomic_create_state(struct drm_private_obj *obj)
+{
+	struct amdgpu_device *adev = drm_to_adev(obj->dev);
+	struct dm_atomic_state *dm_state;
+	struct dc_state *context;
+
+	dm_state = kzalloc_obj(*dm_state);
+	if (!dm_state)
+		return ERR_PTR(-ENOMEM);
+
+	context = dc_state_create_current_copy(adev->dm.dc);
+	if (!context) {
+		kfree(dm_state);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	__drm_atomic_helper_private_obj_create_state(obj, &dm_state->base);
+	dm_state->context = context;
+
+	return &dm_state->base;
+}
+
 static struct drm_private_state_funcs dm_atomic_state_funcs = {
+	.atomic_create_state = dm_atomic_create_state,
 	.atomic_duplicate_state = dm_atomic_duplicate_state,
 	.atomic_destroy_state = dm_atomic_destroy_state,
 };
 
 static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
 {
-	struct dm_atomic_state *state;
 	int r;
 
 	adev->mode_info.mode_config_initialized = true;
 
 	adev_to_drm(adev)->mode_config.funcs = (void *)&amdgpu_dm_mode_funcs;
@@ -4939,46 +4962,27 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
 	else
 		adev_to_drm(adev)->mode_config.prefer_shadow = 1;
 	/* indicates support for immediate flip */
 	adev_to_drm(adev)->mode_config.async_page_flip = true;
 
-	state = kzalloc_obj(*state);
-	if (!state)
-		return -ENOMEM;
-
-	state->context = dc_state_create_current_copy(adev->dm.dc);
-	if (!state->context) {
-		kfree(state);
-		return -ENOMEM;
-	}
-
 	drm_atomic_private_obj_init(adev_to_drm(adev),
 				    &adev->dm.atomic_obj,
-				    &state->base,
+				    NULL,
 				    &dm_atomic_state_funcs);
 
 	r = amdgpu_display_modeset_create_props(adev);
-	if (r) {
-		dc_state_release(state->context);
-		kfree(state);
+	if (r)
 		return r;
-	}
 
 #ifdef AMD_PRIVATE_COLOR
-	if (amdgpu_dm_create_color_properties(adev)) {
-		dc_state_release(state->context);
-		kfree(state);
+	if (amdgpu_dm_create_color_properties(adev))
 		return -ENOMEM;
-	}
 #endif
 
 	r = amdgpu_dm_audio_init(adev);
-	if (r) {
-		dc_state_release(state->context);
-		kfree(state);
+	if (r)
 		return r;
-	}
 
 	return 0;
 }
 
 #define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12
Signature · 1 line
2.52.0
author maintainer
#2 lore raw

PATCH v5 2/4 drm/omapdrm: Switch private_obj initialization to atomic_create_state

In reply to Maxime Ripard

The omapdrm driver relies on a drm_private_obj, that is initialized by allocating and initializing a state, and then passing it to drm_private_obj_init.

Since we're gradually moving away from that pattern to the more established one relying on a atomic_create_state implementation, let's migrate this instance to the new pattern.

---

Cc Tomi Valkeinen <[email protected]>
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/gpu/drm/omapdrm/omap_drv.c +16 -6
index bf0bad8c8cf120baa124b439f3fcbfe36c976d12..90832b4b8c9dd540c8778cb39de7cf80e8796857 100644
@@ -273,25 +273,35 @@ static void omap_global_destroy_state(struct drm_private_obj *obj,
 	struct omap_global_state *omap_state = to_omap_global_state(state);
 
 	kfree(omap_state);
 }
 
+static struct drm_private_state *
+omap_global_atomic_create_state(struct drm_private_obj *obj)
+{
+	struct omap_global_state *state;
+
+	state = kzalloc_obj(*state);
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	__drm_atomic_helper_private_obj_create_state(obj, &state->base);
+
+	return &state->base;
+}
+
 static const struct drm_private_state_funcs omap_global_state_funcs = {
+	.atomic_create_state = omap_global_atomic_create_state,
 	.atomic_duplicate_state = omap_global_duplicate_state,
 	.atomic_destroy_state = omap_global_destroy_state,
 };
 
 static int omap_global_obj_init(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
-	struct omap_global_state *state;
 
-	state = kzalloc_obj(*state);
-	if (!state)
-		return -ENOMEM;
-
-	drm_atomic_private_obj_init(dev, &priv->glob_obj, &state->base,
+	drm_atomic_private_obj_init(dev, &priv->glob_obj, NULL,
 				    &omap_global_state_funcs);
 	return 0;
 }
 
 static void omap_global_obj_fini(struct omap_drm_private *priv)
Signature · 1 line
2.52.0
author maintainer
#3 lore raw

PATCH v5 3/4 drm/tegra: Switch private_obj initialization to atomic_create_state

In reply to Maxime Ripard

The tegra driver relies on a drm_private_obj, that is initialized by allocating and initializing a state, and then passing it to drm_private_obj_init.

Since we're gradually moving away from that pattern to the more established one relying on a atomic_create_state implementation, let's migrate this instance to the new pattern.

---

Cc Thierry Reding <[email protected]>
Cc Mikko Perttunen <[email protected]>
Cc Jonathan Hunter <[email protected]>
---
 drivers/gpu/drm/tegra/hub.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)
drivers/gpu/drm/tegra/hub.c +16 -6
index a6fa196c28132ea9839c48639fb3214b32396d02..73190a4b4d0546be6d6cae746ba5d03ab8e98b92 100644
@@ -823,11 +823,26 @@ static void tegra_display_hub_destroy_state(struct drm_private_obj *obj,
 		to_tegra_display_hub_state(state);
 
 	kfree(hub_state);
 }
 
+static struct drm_private_state *
+tegra_display_hub_create_state(struct drm_private_obj *obj)
+{
+	struct tegra_display_hub_state *hub_state;
+
+	hub_state = kzalloc_obj(*hub_state);
+	if (!hub_state)
+		return ERR_PTR(-ENOMEM);
+
+	__drm_atomic_helper_private_obj_create_state(obj, &hub_state->base);
+
+	return &hub_state->base;
+}
+
 static const struct drm_private_state_funcs tegra_display_hub_state_funcs = {
+	.atomic_create_state = tegra_display_hub_create_state,
 	.atomic_duplicate_state = tegra_display_hub_duplicate_state,
 	.atomic_destroy_state = tegra_display_hub_destroy_state,
 };
 
 static struct tegra_display_hub_state *
@@ -939,17 +954,12 @@ void tegra_display_hub_atomic_commit(struct drm_device *drm,
 static int tegra_display_hub_init(struct host1x_client *client)
 {
 	struct tegra_display_hub *hub = to_tegra_display_hub(client);
 	struct drm_device *drm = dev_get_drvdata(client->host);
 	struct tegra_drm *tegra = drm->dev_private;
-	struct tegra_display_hub_state *state;
 
-	state = kzalloc_obj(*state);
-	if (!state)
-		return -ENOMEM;
-
-	drm_atomic_private_obj_init(drm, &hub->base, &state->base,
+	drm_atomic_private_obj_init(drm, &hub->base, NULL,
 				    &tegra_display_hub_state_funcs);
 
 	tegra->hub = hub;
 
 	return 0;
Signature · 1 line
2.52.0
author maintainer
#4 lore raw

PATCH v5 4/4 drm/atomic: Remove state argument to drm_atomic_private_obj_init

In reply to Maxime Ripard

Now that all drm_private_objs users have been converted to use atomic_create_state instead of the old ad-hoc initialization, we can remove the state parameter from drm_private_obj_init and the fallback code.

---

To: Liviu Dudau <[email protected]>
To: Andrzej Hajda <[email protected]>
To: Neil Armstrong <[email protected]>
To: Robert Foss <[email protected]>
To: Paul Cercueil <[email protected]>
To: Tomi Valkeinen <[email protected]>
To: Thierry Reding <[email protected]>
To: Mikko Perttunen <[email protected]>
To: Jonathan Hunter <[email protected]>
To: Dave Stevenson <[email protected]>
Cc: Rodrigo Siqueira <[email protected]>
Cc: Laurent Pinchart <[email protected]>
Cc: Jonas Karlman <[email protected]>
Cc: Jernej Skrabec <[email protected]>
Cc: Abhinav Kumar <[email protected]>
Cc: Jessica Zhang <[email protected]>
Cc: Sean Paul <[email protected]>
Cc: Marijn Suijten <[email protected]>
Cc: "Maíra Canal" <[email protected]>
Cc: Raspberry Pi Kernel Maintenance <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]

---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  1 -
 .../drm/arm/display/komeda/komeda_private_obj.c    | 16 ++++++++--------
 drivers/gpu/drm/display/drm_dp_mst_topology.c      |  1 -
 drivers/gpu/drm/display/drm_dp_tunnel.c            |  2 +-
 drivers/gpu/drm/drm_atomic.c                       | 22 +++++-----------------
 drivers/gpu/drm/drm_bridge.c                       |  1 -
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c          |  2 +-
 drivers/gpu/drm/ingenic/ingenic-ipu.c              |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  1 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c           |  1 -
 drivers/gpu/drm/omapdrm/omap_drv.c                 |  2 +-
 drivers/gpu/drm/tegra/hub.c                        |  2 +-
 drivers/gpu/drm/vc4/vc4_kms.c                      |  4 +---
 include/drm/drm_atomic.h                           |  1 -
 14 files changed, 19 insertions(+), 39 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +0 -1
index 98ed54afb02864342bb2c04782d05c5fb6e38672..72cfba657d1f49b42e9f5f99fced653e7e24a4e9 100644
@@ -4964,11 +4964,10 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
 	/* indicates support for immediate flip */
 	adev_to_drm(adev)->mode_config.async_page_flip = true;
 
 	drm_atomic_private_obj_init(adev_to_drm(adev),
 				    &adev->dm.atomic_obj,
-				    NULL,
 				    &dm_atomic_state_funcs);
 
 	r = amdgpu_display_modeset_create_props(adev);
 	if (r)
 		return r;
drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c +8 -8
index 49b934c6dbdf0fdbf1dfa10bf74536481350a381..77b3f361091fc3e07d30cee4a74f69c7ea1f6e90 100644
@@ -63,11 +63,11 @@ static const struct drm_private_state_funcs komeda_layer_obj_funcs = {
 };
 
 static int komeda_layer_obj_add(struct komeda_kms_dev *kms,
 				struct komeda_layer *layer)
 {
-	drm_atomic_private_obj_init(&kms->base, &layer->base.obj, NULL,
+	drm_atomic_private_obj_init(&kms->base, &layer->base.obj,
 				    &komeda_layer_obj_funcs);
 	return 0;
 }
 
 static struct drm_private_state *
@@ -116,11 +116,11 @@ static const struct drm_private_state_funcs komeda_scaler_obj_funcs = {
 
 static int komeda_scaler_obj_add(struct komeda_kms_dev *kms,
 				 struct komeda_scaler *scaler)
 {
 	drm_atomic_private_obj_init(&kms->base,
-				    &scaler->base.obj, NULL,
+				    &scaler->base.obj,
 				    &komeda_scaler_obj_funcs);
 	return 0;
 }
 
 static struct drm_private_state *
@@ -168,11 +168,11 @@ static const struct drm_private_state_funcs komeda_compiz_obj_funcs = {
 };
 
 static int komeda_compiz_obj_add(struct komeda_kms_dev *kms,
 				 struct komeda_compiz *compiz)
 {
-	drm_atomic_private_obj_init(&kms->base, &compiz->base.obj, NULL,
+	drm_atomic_private_obj_init(&kms->base, &compiz->base.obj,
 				    &komeda_compiz_obj_funcs);
 
 	return 0;
 }
 
@@ -222,11 +222,11 @@ static const struct drm_private_state_funcs komeda_splitter_obj_funcs = {
 
 static int komeda_splitter_obj_add(struct komeda_kms_dev *kms,
 				   struct komeda_splitter *splitter)
 {
 	drm_atomic_private_obj_init(&kms->base,
-				    &splitter->base.obj, NULL,
+				    &splitter->base.obj,
 				    &komeda_splitter_obj_funcs);
 
 	return 0;
 }
 
@@ -275,11 +275,11 @@ static const struct drm_private_state_funcs komeda_merger_obj_funcs = {
 
 static int komeda_merger_obj_add(struct komeda_kms_dev *kms,
 				 struct komeda_merger *merger)
 {
 	drm_atomic_private_obj_init(&kms->base,
-				    &merger->base.obj, NULL,
+				    &merger->base.obj,
 				    &komeda_merger_obj_funcs);
 
 	return 0;
 }
 
@@ -328,11 +328,11 @@ static const struct drm_private_state_funcs komeda_improc_obj_funcs = {
 };
 
 static int komeda_improc_obj_add(struct komeda_kms_dev *kms,
 				 struct komeda_improc *improc)
 {
-	drm_atomic_private_obj_init(&kms->base, &improc->base.obj, NULL,
+	drm_atomic_private_obj_init(&kms->base, &improc->base.obj,
 				    &komeda_improc_obj_funcs);
 
 	return 0;
 }
 
@@ -381,11 +381,11 @@ static const struct drm_private_state_funcs komeda_timing_ctrlr_obj_funcs = {
 };
 
 static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms,
 				       struct komeda_timing_ctrlr *ctrlr)
 {
-	drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj, NULL,
+	drm_atomic_private_obj_init(&kms->base, &ctrlr->base.obj,
 				    &komeda_timing_ctrlr_obj_funcs);
 
 	return 0;
 }
 
@@ -435,11 +435,11 @@ static const struct drm_private_state_funcs komeda_pipeline_obj_funcs = {
 };
 
 static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms,
 				   struct komeda_pipeline *pipe)
 {
-	drm_atomic_private_obj_init(&kms->base, &pipe->obj, NULL,
+	drm_atomic_private_obj_init(&kms->base, &pipe->obj,
 				    &komeda_pipeline_obj_funcs);
 
 	return 0;
 }
 
drivers/gpu/drm/display/drm_dp_mst_topology.c +0 -1
index d8a732f21d3c04eaeefa64d5fe34d156369787ac..8757972e8e2427cbbab2e90d1c9c291d97e96c0a 100644
@@ -5763,11 +5763,10 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr,
 	mgr->max_dpcd_transaction_bytes = max_dpcd_transaction_bytes;
 	mgr->max_payloads = max_payloads;
 	mgr->conn_base_id = conn_base_id;
 
 	drm_atomic_private_obj_init(dev, &mgr->base,
-				    NULL,
 				    &drm_dp_mst_topology_state_funcs);
 
 	return 0;
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
drivers/gpu/drm/display/drm_dp_tunnel.c +1 -1
index f442430d8de78221ec88d0567dc68f2fa8d2b82a..6519b42447285b58892ac07a3570cf6c457e4c27 100644
@@ -1598,11 +1598,11 @@ static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_tunnel_group
 {
 	group->mgr = mgr;
 	group->available_bw = -1;
 	INIT_LIST_HEAD(&group->tunnels);
 
-	drm_atomic_private_obj_init(mgr->dev, &group->base, NULL,
+	drm_atomic_private_obj_init(mgr->dev, &group->base,
 				    &tunnel_group_funcs);
 
 	return true;
 }
 
drivers/gpu/drm/drm_atomic.c +5 -17
index 04925166df989bcb30b111739aa4ed5c84f3a5ae..4283ab4d06c581727cc98b1dc870bf69691ea654 100644
@@ -918,11 +918,10 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
 
 /**
  * drm_atomic_private_obj_init - initialize private object
  * @dev: DRM device this object will be attached to
  * @obj: private object
- * @state: initial private object state
  * @funcs: pointer to the struct of function pointers that identify the object
  * type
  *
  * Initialize the private object, which can be embedded into any
  * driver private object that needs its own atomic state.
@@ -930,37 +929,26 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
  * RETURNS:
  * Zero on success, error code on failure
  */
 int drm_atomic_private_obj_init(struct drm_device *dev,
 				struct drm_private_obj *obj,
-				struct drm_private_state *state,
 				const struct drm_private_state_funcs *funcs)
 {
+	struct drm_private_state *state;
 	memset(obj, 0, sizeof(*obj));
 
 	drm_modeset_lock_init(&obj->lock);
 
 	obj->dev = dev;
 	obj->funcs = funcs;
 	list_add_tail(&obj->head, &dev->mode_config.privobj_list);
 
-	/*
-	 * Not all users of drm_atomic_private_obj_init have been
-	 * converted to using &drm_private_obj_funcs.atomic_create_state yet.
-	 * For the time being, let's only call reset if the passed state is
-	 * NULL. Otherwise, we will fallback to the previous behaviour.
-	 */
-	if (!state) {
-		state = obj->funcs->atomic_create_state(obj);
-		if (IS_ERR(state))
-			return PTR_ERR(state);
+	state = obj->funcs->atomic_create_state(obj);
+	if (IS_ERR(state))
+		return PTR_ERR(state);
 
-		obj->state = state;
-	} else {
-		obj->state = state;
-		state->obj = obj;
-	}
+	obj->state = state;
 
 	return 0;
 }
 EXPORT_SYMBOL(drm_atomic_private_obj_init);
 
drivers/gpu/drm/drm_bridge.c +0 -1
index f8b0333a0a3bf5bdf4036d2f7ca5565934e44b4c..1868d512ffa1fabc8adab97bc7cb96fd32a78997 100644
@@ -551,11 +551,10 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
 			goto err_reset_bridge;
 	}
 
 	if (drm_bridge_is_atomic(bridge))
 		drm_atomic_private_obj_init(bridge->dev, &bridge->base,
-					    NULL,
 					    &drm_bridge_priv_state_funcs);
 
 	return 0;
 
 err_reset_bridge:
drivers/gpu/drm/ingenic/ingenic-drm-drv.c +1 -1
index 9522a2e6ecd4166efc648a24e237b8166e426d48..4068114adf8c2068a94a3aaa308cf91847712acb 100644
@@ -1399,11 +1399,11 @@ static int ingenic_drm_bind(struct device *dev, bool has_components)
 	if (ret) {
 		dev_err(dev, "Unable to register clock notifier\n");
 		goto err_devclk_disable;
 	}
 
-	drm_atomic_private_obj_init(drm, &priv->private_obj, NULL,
+	drm_atomic_private_obj_init(drm, &priv->private_obj,
 				    &ingenic_drm_private_state_funcs);
 
 	ret = drmm_add_action_or_reset(drm, ingenic_drm_atomic_private_obj_fini,
 				       &priv->private_obj);
 	if (ret)
drivers/gpu/drm/ingenic/ingenic-ipu.c +1 -1
index 4fec37c63e7cb7c96b32191d680c89e20837b155..34545b9c8c33833c3cc65f3d111b3f3bf9a60137 100644
@@ -899,11 +899,11 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d)
 	if (err) {
 		dev_err(dev, "Unable to prepare clock\n");
 		return err;
 	}
 
-	drm_atomic_private_obj_init(drm, &ipu->private_obj, NULL,
+	drm_atomic_private_obj_init(drm, &ipu->private_obj,
 				    &ingenic_ipu_private_state_funcs);
 
 	return 0;
 }
 
drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +0 -1
index 4495525139978e64e0c650aae0cdc1a57e0c8398..31743699d05f6667e37fe70d79549cfe736474fe 100644
@@ -1159,11 +1159,10 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 
 	dev->mode_config.cursor_width = 512;
 	dev->mode_config.cursor_height = 512;
 
 	drm_atomic_private_obj_init(dpu_kms->dev, &dpu_kms->global_state,
-				    NULL,
 				    &dpu_kms_global_state_funcs);
 
 	atomic_set(&dpu_kms->bandwidth_ref, 0);
 
 	rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev);
drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +0 -1
index 1e3dc9bf9494c2b06ad5acaca74f7b17221b7833..2d26b07b06f54bbe8e26e538c155b8de994a4543 100644
@@ -715,11 +715,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 	int ret;
 
 	mdp5_kms->dev = dev;
 
 	drm_atomic_private_obj_init(mdp5_kms->dev, &mdp5_kms->glob_state,
-				    NULL,
 				    &mdp5_global_state_funcs);
 
 	/* we need to set a default rate before enabling.  Set a safe
 	 * rate first, then figure out hw revision, and then set a
 	 * more optimal rate:
drivers/gpu/drm/omapdrm/omap_drv.c +1 -1
index 90832b4b8c9dd540c8778cb39de7cf80e8796857..ae678696fbacb0572869c7152a484fc5736ac44a 100644
@@ -297,11 +297,11 @@ static const struct drm_private_state_funcs omap_global_state_funcs = {
 
 static int omap_global_obj_init(struct drm_device *dev)
 {
 	struct omap_drm_private *priv = dev->dev_private;
 
-	drm_atomic_private_obj_init(dev, &priv->glob_obj, NULL,
+	drm_atomic_private_obj_init(dev, &priv->glob_obj,
 				    &omap_global_state_funcs);
 	return 0;
 }
 
 static void omap_global_obj_fini(struct omap_drm_private *priv)
drivers/gpu/drm/tegra/hub.c +1 -1
index 73190a4b4d0546be6d6cae746ba5d03ab8e98b92..10d993b8d043ab08ee65ab4db1e31624c953d0f3 100644
@@ -955,11 +955,11 @@ static int tegra_display_hub_init(struct host1x_client *client)
 {
 	struct tegra_display_hub *hub = to_tegra_display_hub(client);
 	struct drm_device *drm = dev_get_drvdata(client->host);
 	struct tegra_drm *tegra = drm->dev_private;
 
-	drm_atomic_private_obj_init(drm, &hub->base, NULL,
+	drm_atomic_private_obj_init(drm, &hub->base,
 				    &tegra_display_hub_state_funcs);
 
 	tegra->hub = hub;
 
 	return 0;
drivers/gpu/drm/vc4/vc4_kms.c +1 -3
index 0507f24adcdd05660b9ef349dd609b095d52a9f8..264b5e80c24d67f59dea8085f7d02d218db25697 100644
@@ -114,11 +114,11 @@ static void vc4_ctm_obj_fini(struct drm_device *dev, void *unused)
 
 static int vc4_ctm_obj_init(struct vc4_dev *vc4)
 {
 	drm_modeset_lock_init(&vc4->ctm_state_lock);
 
-	drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager, NULL,
+	drm_atomic_private_obj_init(&vc4->base, &vc4->ctm_manager,
 				    &vc4_ctm_state_funcs);
 
 	return drmm_add_action_or_reset(&vc4->base, vc4_ctm_obj_fini, NULL);
 }
 
@@ -755,11 +755,10 @@ static void vc4_load_tracker_obj_fini(struct drm_device *dev, void *unused)
 }
 
 static int vc4_load_tracker_obj_init(struct vc4_dev *vc4)
 {
 	drm_atomic_private_obj_init(&vc4->base, &vc4->load_tracker,
-				    NULL,
 				    &vc4_load_tracker_state_funcs);
 
 	return drmm_add_action_or_reset(&vc4->base, vc4_load_tracker_obj_fini, NULL);
 }
 
@@ -847,11 +846,10 @@ static void vc4_hvs_channels_obj_fini(struct drm_device *dev, void *unused)
 }
 
 static int vc4_hvs_channels_obj_init(struct vc4_dev *vc4)
 {
 	drm_atomic_private_obj_init(&vc4->base, &vc4->hvs_channels,
-				    NULL,
 				    &vc4_hvs_state_funcs);
 
 	return drmm_add_action_or_reset(&vc4->base, vc4_hvs_channels_obj_fini, NULL);
 }
 
include/drm/drm_atomic.h +0 -1
index 0b1b32bcd2bda1b92299fd369ba7c23b1c2d3dfa..f03cd199aee73fa8e15b2d9e16a53d134fc7de7d 100644
@@ -736,11 +736,10 @@ struct drm_connector_state * __must_check
 drm_atomic_get_connector_state(struct drm_atomic_state *state,
 			       struct drm_connector *connector);
 
 int drm_atomic_private_obj_init(struct drm_device *dev,
 				struct drm_private_obj *obj,
-				struct drm_private_state *state,
 				const struct drm_private_state_funcs *funcs);
 void drm_atomic_private_obj_fini(struct drm_private_obj *obj);
 
 struct drm_private_state * __must_check
 drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
Signature · 1 line
2.52.0
maintainer Reviewed-by on the v5 series
#5 lore raw
In reply to Maxime Ripard

Hi,

Quoted 10 lines · Maxime Ripard

Hi,

This series started from my work on the hardware state readout[1], and was suggested by Dmitry[2].

This series deal with the fact that drm_private_obj (and thus bridges) are not initialized using the same pattern than any other object. This series solves that inconsistency by aligning it to what we're doing for all the other objects.

Quoted 4 lines

This was tested on a TI SK-AM62, with three bridges.

Let me know what you think,
Maxime

Looks fine to me, except for one thing: the return value of drm_atomic_private_obj_init() is ignored everywhere, so we won't catch ENOMEM. Is there a plan or follow-up series for that? If yes:

Tomi

Quoted 55 lines

1: https://lore.kernel.org/dri-devel/[email protected]/
2: https://lore.kernel.org/dri-devel/zvqtehg66dbrrdmik6ylo2kdk74umfzo5hbfkizwsb352nlyqv@jgouvmbfwa4x/

---
Changes in v5:
- Rebase to drm-misc-next
- Link to v4: https://lore.kernel.org/r/[email protected]

Changes in v4:
- Fix a circular dependencies between modules by calling __drm_atomic_helper_private_obj_create_state from __drm_atomic_helper_bridge_reset instead of
drm_bridge_atomic_create_priv_state()
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Switch to a new hook instead of reset since some drm_private_objs want
to persist across suspends
- Drop the call to drm_private_obj_funcs.reset in
drm_mode_config_reset()
- Link to v1: https://lore.kernel.org/r/[email protected]

---
Maxime Ripard (4):
drm/amdgpu: Switch private_obj initialization to atomic_create_state drm/omapdrm: Switch private_obj initialization to atomic_create_state drm/tegra: Switch private_obj initialization to atomic_create_state drm/atomic: Remove state argument to drm_atomic_private_obj_init

 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 51 ++++++++++++----------
 .../drm/arm/display/komeda/komeda_private_obj.c    | 16 +++----
 drivers/gpu/drm/display/drm_dp_mst_topology.c      |  1 -
 drivers/gpu/drm/display/drm_dp_tunnel.c            |  2 +-
 drivers/gpu/drm/drm_atomic.c                       | 22 +++-------
 drivers/gpu/drm/drm_bridge.c                       |  1 -
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c          |  2 +-
 drivers/gpu/drm/ingenic/ingenic-ipu.c              |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  1 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c           |  1 -
 drivers/gpu/drm/omapdrm/omap_drv.c                 | 22 +++++++---
 drivers/gpu/drm/tegra/hub.c                        | 22 +++++++---
 drivers/gpu/drm/vc4/vc4_kms.c                      |  4 +-
 include/drm/drm_atomic.h                           |  1 -
 14 files changed, 76 insertions(+), 72 deletions(-)

---
base-commit: 196b2b95fec447c2c4460f753b277d840633fbef
change-id: 20251008-drm-private-obj-reset-ae1e2741027a

Best regards,

maintainer Reviewed-by on the v5 series
#6 lore raw
In reply to Maxime Ripard

Hi

Am 24.02.26 um 17:10 schrieb Maxime Ripard:

Quoted 43 lines

Hi,

This series started from my work on the hardware state readout[1], and was suggested by Dmitry[2].

This series deal with the fact that drm_private_obj (and thus bridges) are not initialized using the same pattern than any other object. This series solves that inconsistency by aligning it to what we're doing for all the other objects.

This was tested on a TI SK-AM62, with three bridges.

Let me know what you think,
Maxime

1: https://lore.kernel.org/dri-devel/[email protected]/
2: https://lore.kernel.org/dri-devel/zvqtehg66dbrrdmik6ylo2kdk74umfzo5hbfkizwsb352nlyqv@jgouvmbfwa4x/

---
Changes in v5:
- Rebase to drm-misc-next
- Link to v4: https://lore.kernel.org/r/[email protected]

Changes in v4:
- Fix a circular dependencies between modules by calling __drm_atomic_helper_private_obj_create_state from __drm_atomic_helper_bridge_reset instead of drm_bridge_atomic_create_priv_state()
- Link to v3: https://lore.kernel.org/r/[email protected]

Changes in v3:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Switch to a new hook instead of reset since some drm_private_objs want
to persist across suspends
- Drop the call to drm_private_obj_funcs.reset in
drm_mode_config_reset()
- Link to v1: https://lore.kernel.org/r/[email protected]

Quoted 6 lines

---
Maxime Ripard (4):
drm/amdgpu: Switch private_obj initialization to atomic_create_state drm/omapdrm: Switch private_obj initialization to atomic_create_state drm/tegra: Switch private_obj initialization to atomic_create_state drm/atomic: Remove state argument to drm_atomic_private_obj_init

Nice cleanup. For the whole series:

Best regards
Thomas

Quoted 21 lines
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  | 51 ++++++++++++----------
  .../drm/arm/display/komeda/komeda_private_obj.c    | 16 +++----
  drivers/gpu/drm/display/drm_dp_mst_topology.c      |  1 -
  drivers/gpu/drm/display/drm_dp_tunnel.c            |  2 +-
  drivers/gpu/drm/drm_atomic.c                       | 22 +++-------
  drivers/gpu/drm/drm_bridge.c                       |  1 -
  drivers/gpu/drm/ingenic/ingenic-drm-drv.c          |  2 +-
  drivers/gpu/drm/ingenic/ingenic-ipu.c              |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  1 -
  drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c           |  1 -
  drivers/gpu/drm/omapdrm/omap_drv.c                 | 22 +++++++---
  drivers/gpu/drm/tegra/hub.c                        | 22 +++++++---
  drivers/gpu/drm/vc4/vc4_kms.c                      |  4 +-
  include/drm/drm_atomic.h                           |  1 -
  14 files changed, 76 insertions(+), 72 deletions(-)

---
base-commit: 196b2b95fec447c2c4460f753b277d840633fbef
change-id: 20251008-drm-private-obj-reset-ae1e2741027a

Best regards,

Signature · 6 lines
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
author maintainer Applied
#7 lore raw
In reply to Maxime Ripard
Quoted 9 lines · Maxime Ripard

This series started from my work on the hardware state readout[1], and was suggested by Dmitry[2].

This series deal with the fact that drm_private_obj (and thus bridges) are not initialized using the same pattern than any other object. This series solves that inconsistency by aligning it to what we're doing for all the other objects.

[...]

Applied to misc/kernel.git (drm-misc-next).

Thanks!
Maxime