From: Kory Maincent <kory.maincent@bootlin.com>
To: Jani Nikula <jani.nikula@linux.intel.com>,
Rodrigo Vivi <rodrigo.vivi@intel.com>,
Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
Tvrtko Ursulin <tursulin@ursulin.net>,
David Airlie <airlied@gmail.com>,
Simona Vetter <simona@ffwll.ch>,
Dave Airlie <airlied@redhat.com>,
Jesse Barnes <jbarnes@virtuousgeek.org>,
Eric Anholt <eric@anholt.net>,
Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
Maxime Ripard <mripard@kernel.org>,
Thomas Zimmermann <tzimmermann@suse.de>,
Andrzej Hajda <andrzej.hajda@intel.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Robert Foss <rfoss@kernel.org>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
Jonas Karlman <jonas@kwiboo.se>,
Jernej Skrabec <jernej.skrabec@gmail.com>,
Chun-Kuang Hu <chunkuang.hu@kernel.org>,
Philipp Zabel <p.zabel@pengutronix.de>,
Matthias Brugger <matthias.bgg@gmail.com>,
AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com>,
Chris Wilson <chris@chris-wilson.co.uk>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Mark Yacoub <markyacoub@google.com>,
Sean Paul <seanpaul@google.com>,
Louis Chauvet <louis.chauvet@bootlin.com>,
intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-mediatek@lists.infradead.org,
linux-arm-kernel@lists.infradead.org,
Simona Vetter <simona.vetter@ffwll.ch>,
Kory Maincent <kory.maincent@bootlin.com>
Subject: [PATCH RFC 07/12] drm/i915/display: Switch to managed for encoder
Date: Thu, 09 Apr 2026 19:08:23 +0200 [thread overview]
Message-ID: <20260409-feat_link_cap-v1-7-7069e8199ce2@bootlin.com> (raw)
In-Reply-To: <20260409-feat_link_cap-v1-0-7069e8199ce2@bootlin.com>
The current i915 driver uses non-managed function to create encoder. It
is not an issue yet, but in order to comply with the latest DRM
requirement, convert this code to use drm and device managed helpers.
Assisted-by: Claude Code:2.1.90
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
drivers/gpu/drm/i915/display/g4x_dp.c | 31 ++++++++---------
drivers/gpu/drm/i915/display/g4x_hdmi.c | 19 ++++-------
drivers/gpu/drm/i915/display/icl_dsi.c | 20 +++--------
drivers/gpu/drm/i915/display/intel_crt.c | 9 +++--
drivers/gpu/drm/i915/display/intel_ddi.c | 50 +++++++++++++++-------------
drivers/gpu/drm/i915/display/intel_display.c | 8 -----
drivers/gpu/drm/i915/display/intel_display.h | 1 -
drivers/gpu/drm/i915/display/intel_dp_mst.c | 20 +++--------
drivers/gpu/drm/i915/display/intel_dvo.c | 22 ++++++------
drivers/gpu/drm/i915/display/intel_encoder.c | 6 ++--
drivers/gpu/drm/i915/display/intel_encoder.h | 3 +-
drivers/gpu/drm/i915/display/intel_lvds.c | 13 +++-----
drivers/gpu/drm/i915/display/intel_sdvo.c | 45 +++++++++++--------------
drivers/gpu/drm/i915/display/intel_tv.c | 11 +++---
drivers/gpu/drm/i915/display/vlv_dsi.c | 22 +++++-------
15 files changed, 114 insertions(+), 166 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/g4x_dp.c b/drivers/gpu/drm/i915/display/g4x_dp.c
index 5e74d8a3ba5c8..99b6c5ce39b2a 100644
--- a/drivers/gpu/drm/i915/display/g4x_dp.c
+++ b/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -7,6 +7,7 @@
#include <linux/string_helpers.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "g4x_dp.h"
@@ -1250,12 +1251,9 @@ static void g4x_dp_suspend_complete(struct intel_encoder *encoder)
intel_encoder_link_check_flush_work(encoder);
}
-static void intel_dp_encoder_destroy(struct drm_encoder *encoder)
+static void intel_dp_encoder_flush_work_cleanup(struct drm_device *drm, void *data)
{
- intel_dp_encoder_flush_work(encoder);
-
- drm_encoder_cleanup(encoder);
- kfree(enc_to_dig_port(to_intel_encoder(encoder)));
+ intel_dp_encoder_flush_work(data);
}
static void intel_dp_encoder_reset(struct drm_encoder *encoder)
@@ -1276,7 +1274,6 @@ static void intel_dp_encoder_reset(struct drm_encoder *encoder)
static const struct drm_encoder_funcs intel_dp_enc_funcs = {
.reset = intel_dp_encoder_reset,
- .destroy = intel_dp_encoder_destroy,
};
bool g4x_dp_init(struct intel_display *display,
@@ -1298,22 +1295,26 @@ bool g4x_dp_init(struct intel_display *display,
drm_dbg_kms(display->drm, "No VBT child device for DP-%c\n",
port_name(port));
- dig_port = intel_dig_port_alloc();
+ dig_port = intel_dig_port_alloc(display->drm);
if (!dig_port)
return false;
intel_connector = intel_connector_alloc();
if (!intel_connector)
- goto err_connector_alloc;
+ return false;
intel_encoder = &dig_port->base;
encoder = &intel_encoder->base;
intel_encoder->devdata = devdata;
- if (drm_encoder_init(display->drm, &intel_encoder->base,
- &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
- "DP %c", port_name(port)))
+ if (drmm_encoder_init(display->drm, &intel_encoder->base,
+ &intel_dp_enc_funcs, DRM_MODE_ENCODER_TMDS,
+ "DP %c", port_name(port)))
+ goto err_encoder_init;
+
+ if (drmm_add_action_or_reset(display->drm,
+ intel_dp_encoder_flush_work_cleanup, encoder))
goto err_encoder_init;
intel_encoder_link_check_init(intel_encoder, intel_dp_link_check);
@@ -1411,18 +1412,14 @@ bool g4x_dp_init(struct intel_display *display,
dig_port->aux_ch = intel_dp_aux_ch(intel_encoder);
if (dig_port->aux_ch == AUX_CH_NONE)
- goto err_init_connector;
+ goto err_encoder_init;
if (!intel_dp_init_connector(dig_port, intel_connector))
- goto err_init_connector;
+ goto err_encoder_init;
return true;
-err_init_connector:
- drm_encoder_cleanup(encoder);
err_encoder_init:
kfree(intel_connector);
-err_connector_alloc:
- kfree(dig_port);
return false;
}
diff --git a/drivers/gpu/drm/i915/display/g4x_hdmi.c b/drivers/gpu/drm/i915/display/g4x_hdmi.c
index 5fe5067c4237c..45ee1ad504bc1 100644
--- a/drivers/gpu/drm/i915/display/g4x_hdmi.c
+++ b/drivers/gpu/drm/i915/display/g4x_hdmi.c
@@ -5,6 +5,7 @@
* HDMI support for G4x,ILK,SNB,IVB,VLV,CHV (HSW+ handled by the DDI code).
*/
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include "g4x_hdmi.h"
@@ -562,7 +563,6 @@ static void chv_hdmi_pre_enable(struct intel_atomic_state *state,
}
static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
- .destroy = intel_encoder_destroy,
};
static enum intel_hotplug_state
@@ -686,21 +686,21 @@ bool g4x_hdmi_init(struct intel_display *display,
drm_dbg_kms(display->drm, "No VBT child device for HDMI-%c\n",
port_name(port));
- dig_port = intel_dig_port_alloc();
+ dig_port = intel_dig_port_alloc(display->drm);
if (!dig_port)
return false;
intel_connector = intel_connector_alloc();
if (!intel_connector)
- goto err_connector_alloc;
+ return false;
intel_encoder = &dig_port->base;
intel_encoder->devdata = devdata;
- if (drm_encoder_init(display->drm, &intel_encoder->base,
- &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
- "HDMI %c", port_name(port)))
+ if (drmm_encoder_init(display->drm, &intel_encoder->base,
+ &intel_hdmi_enc_funcs, DRM_MODE_ENCODER_TMDS,
+ "HDMI %c", port_name(port)))
goto err_encoder_init;
intel_encoder->hotplug = intel_hdmi_hotplug;
@@ -763,16 +763,11 @@ bool g4x_hdmi_init(struct intel_display *display,
intel_infoframe_init(dig_port);
if (!intel_hdmi_init_connector(dig_port, intel_connector))
- goto err_init_connector;
+ goto err_encoder_init;
return true;
-
-err_init_connector:
- drm_encoder_cleanup(&intel_encoder->base);
err_encoder_init:
kfree(intel_connector);
-err_connector_alloc:
- kfree(dig_port);
return false;
}
diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index afbaa0465842a..cfee173a2367a 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -30,6 +30,7 @@
#include <drm/display/drm_dsc_helper.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fixed.h>
+#include <drm/drm_managed.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -1775,13 +1776,7 @@ static bool gen11_dsi_initial_fastset_check(struct intel_encoder *encoder,
return true;
}
-static void gen11_dsi_encoder_destroy(struct drm_encoder *encoder)
-{
- intel_encoder_destroy(encoder);
-}
-
static const struct drm_encoder_funcs gen11_dsi_encoder_funcs = {
- .destroy = gen11_dsi_encoder_destroy,
};
static const struct drm_connector_funcs gen11_dsi_connector_funcs = {
@@ -1934,8 +1929,10 @@ void icl_dsi_init(struct intel_display *display,
if (port == PORT_NONE)
return;
- intel_dsi = kzalloc_obj(*intel_dsi);
- if (!intel_dsi)
+ intel_dsi = drmm_encoder_alloc(display->drm, struct intel_dsi, base.base,
+ &gen11_dsi_encoder_funcs,
+ DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
+ if (IS_ERR(intel_dsi))
return;
intel_connector = intel_connector_alloc();
@@ -1950,11 +1947,6 @@ void icl_dsi_init(struct intel_display *display,
encoder->devdata = devdata;
- /* register DSI encoder with DRM subsystem */
- drm_encoder_init(display->drm, &encoder->base,
- &gen11_dsi_encoder_funcs,
- DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
-
encoder->pre_pll_enable = gen11_dsi_pre_pll_enable;
encoder->pre_enable = gen11_dsi_pre_enable;
encoder->enable = gen11_dsi_enable;
@@ -2037,7 +2029,5 @@ void icl_dsi_init(struct intel_display *display,
err:
drm_connector_cleanup(connector);
- drm_encoder_cleanup(&encoder->base);
- kfree(intel_dsi);
kfree(intel_connector);
}
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index 6aa6a1dd6e1b0..39bb115955f5a 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -31,6 +31,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <video/vga.h>
@@ -1004,7 +1005,6 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs
static const struct drm_encoder_funcs intel_crt_enc_funcs = {
.reset = intel_crt_reset,
- .destroy = intel_encoder_destroy,
};
void intel_crt_init(struct intel_display *display)
@@ -1041,8 +1041,9 @@ void intel_crt_init(struct intel_display *display)
intel_de_write(display, adpa_reg, adpa);
}
- crt = kzalloc_obj(struct intel_crt);
- if (!crt)
+ crt = drmm_encoder_alloc(display->drm, struct intel_crt, base.base,
+ &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC, "CRT");
+ if (IS_ERR(crt))
return;
connector = intel_connector_alloc();
@@ -1058,8 +1059,6 @@ void intel_crt_init(struct intel_display *display)
DRM_MODE_CONNECTOR_VGA,
intel_gmbus_get_adapter(display, ddc_pin));
- drm_encoder_init(display->drm, &crt->base.base, &intel_crt_enc_funcs,
- DRM_MODE_ENCODER_DAC, "CRT");
intel_connector_attach_encoder(connector, &crt->base);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index ebefa889bc8c5..003287ad5bc59 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -31,6 +31,7 @@
#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_scdc_helper.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_privacy_screen_consumer.h>
@@ -4644,19 +4645,19 @@ static int intel_ddi_compute_config_late(struct intel_encoder *encoder,
return 0;
}
-static void intel_ddi_encoder_destroy(struct drm_encoder *encoder)
+static void intel_ddi_encoder_cleanup(struct drm_device *drm, void *data)
{
- struct intel_display *display = to_intel_display(encoder->dev);
- struct intel_digital_port *dig_port = enc_to_dig_port(to_intel_encoder(encoder));
+ struct intel_digital_port *dig_port = data;
+ struct intel_display *display = to_intel_display(&dig_port->base);
- intel_dp_encoder_flush_work(encoder);
- if (intel_encoder_is_tc(&dig_port->base))
- intel_tc_port_cleanup(dig_port);
+ intel_dp_encoder_flush_work(&dig_port->base.base);
intel_display_power_flush_work(display);
-
- drm_encoder_cleanup(encoder);
kfree(dig_port->hdcp.port_data.streams);
- kfree(dig_port);
+}
+
+static void intel_tc_port_cleanup_action(struct drm_device *drm, void *data)
+{
+ intel_tc_port_cleanup(data);
}
static void intel_ddi_encoder_reset(struct drm_encoder *encoder)
@@ -4684,7 +4685,6 @@ static int intel_ddi_encoder_late_register(struct drm_encoder *_encoder)
static const struct drm_encoder_funcs intel_ddi_funcs = {
.reset = intel_ddi_encoder_reset,
- .destroy = intel_ddi_encoder_destroy,
.late_register = intel_ddi_encoder_late_register,
};
@@ -5243,16 +5243,20 @@ void intel_ddi_init(struct intel_display *display,
phy_name(phy));
}
- dig_port = intel_dig_port_alloc();
+ dig_port = intel_dig_port_alloc(display->drm);
if (!dig_port)
return;
encoder = &dig_port->base;
encoder->devdata = devdata;
- drm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs,
- DRM_MODE_ENCODER_TMDS, "%s",
- intel_ddi_encoder_name(display, port, phy, &encoder_name));
+ if (drmm_encoder_init(display->drm, &encoder->base, &intel_ddi_funcs,
+ DRM_MODE_ENCODER_TMDS, "%s",
+ intel_ddi_encoder_name(display, port, phy, &encoder_name)))
+ return;
+
+ if (drmm_add_action_or_reset(display->drm, intel_ddi_encoder_cleanup, dig_port))
+ return;
intel_encoder_link_check_init(encoder, intel_ddi_link_check);
@@ -5411,7 +5415,7 @@ void intel_ddi_init(struct intel_display *display,
if (need_aux_ch(encoder, init_dp)) {
dig_port->aux_ch = intel_dp_aux_ch(encoder);
if (dig_port->aux_ch == AUX_CH_NONE)
- goto err;
+ return;
}
/*
@@ -5447,7 +5451,11 @@ void intel_ddi_init(struct intel_display *display,
dig_port->unlock = intel_tc_port_unlock;
if (intel_tc_port_init(dig_port, is_legacy) < 0)
- goto err;
+ return;
+
+ if (drmm_add_action_or_reset(display->drm,
+ intel_tc_port_cleanup_action, dig_port))
+ return;
}
drm_WARN_ON(display->drm, port > PORT_I);
@@ -5478,7 +5486,7 @@ void intel_ddi_init(struct intel_display *display,
if (init_dp) {
if (intel_ddi_init_dp_connector(dig_port))
- goto err;
+ return;
dig_port->hpd_pulse = intel_dp_hpd_pulse;
@@ -5492,12 +5500,6 @@ void intel_ddi_init(struct intel_display *display,
*/
if (encoder->type != INTEL_OUTPUT_EDP && init_hdmi) {
if (intel_ddi_init_hdmi_connector(dig_port))
- goto err;
+ return;
}
-
- return;
-
-err:
- drm_encoder_cleanup(&encoder->base);
- kfree(dig_port);
}
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 10b6c6fcb03f6..049a796da4c38 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2192,14 +2192,6 @@ static void i9xx_crtc_disable(struct intel_atomic_state *state,
i830_enable_pipe(display, pipe);
}
-void intel_encoder_destroy(struct drm_encoder *encoder)
-{
- struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
-
- drm_encoder_cleanup(encoder);
- kfree(intel_encoder);
-}
-
static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
{
struct intel_display *display = to_intel_display(crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 552a59d19e0f6..6c2681738e6b2 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -416,7 +416,6 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state);
void i830_enable_pipe(struct intel_display *display, enum pipe pipe);
void i830_disable_pipe(struct intel_display *display, enum pipe pipe);
bool intel_has_pending_fb_unpin(struct intel_display *display);
-void intel_encoder_destroy(struct drm_encoder *encoder);
struct drm_display_mode *
intel_encoder_current_mode(struct intel_encoder *encoder);
void intel_encoder_get_config(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 887b6de14e467..5fe6fbcaf9371 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -30,6 +30,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_edid.h>
#include <drm/drm_fixed.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -1645,16 +1646,7 @@ static const struct drm_connector_helper_funcs mst_connector_helper_funcs = {
.detect_ctx = mst_connector_detect_ctx,
};
-static void mst_stream_encoder_destroy(struct drm_encoder *encoder)
-{
- struct intel_dp_mst_encoder *intel_mst = enc_to_mst(to_intel_encoder(encoder));
-
- drm_encoder_cleanup(encoder);
- kfree(intel_mst);
-}
-
static const struct drm_encoder_funcs mst_stream_encoder_funcs = {
- .destroy = mst_stream_encoder_destroy,
};
static bool mst_connector_get_hw_state(struct intel_connector *connector)
@@ -1850,18 +1842,16 @@ mst_stream_encoder_create(struct intel_digital_port *dig_port, enum pipe pipe)
struct intel_dp_mst_encoder *intel_mst;
struct intel_encoder *encoder;
- intel_mst = kzalloc_obj(*intel_mst);
-
- if (!intel_mst)
+ intel_mst = drmm_encoder_alloc(display->drm, struct intel_dp_mst_encoder,
+ base.base, &mst_stream_encoder_funcs,
+ DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe));
+ if (IS_ERR(intel_mst))
return NULL;
intel_mst->pipe = pipe;
encoder = &intel_mst->base;
intel_mst->primary = dig_port;
- drm_encoder_init(display->drm, &encoder->base, &mst_stream_encoder_funcs,
- DRM_MODE_ENCODER_DPMST, "DP-MST %c", pipe_name(pipe));
-
encoder->type = INTEL_OUTPUT_DP_MST;
encoder->power_domain = primary_encoder->power_domain;
encoder->port = primary_encoder->port;
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 405b33aca9dde..ea2f6426fd77d 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -31,6 +31,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -372,18 +373,15 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs
.get_modes = intel_dvo_get_modes,
};
-static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
+static void intel_dvo_dev_destroy(struct drm_device *drm, void *data)
{
- struct intel_dvo *intel_dvo = enc_to_dvo(to_intel_encoder(encoder));
+ struct intel_dvo *intel_dvo = data;
if (intel_dvo->dev.dev_ops->destroy)
intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
-
- intel_encoder_destroy(encoder);
}
static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
- .destroy = intel_dvo_enc_destroy,
};
static int intel_dvo_encoder_type(const struct intel_dvo_device *dvo)
@@ -494,7 +492,7 @@ void intel_dvo_init(struct intel_display *display)
struct intel_encoder *encoder;
struct intel_dvo *intel_dvo;
- intel_dvo = kzalloc_obj(*intel_dvo);
+ intel_dvo = drmm_kzalloc(display->drm, sizeof(*intel_dvo), GFP_KERNEL);
if (!intel_dvo)
return;
@@ -517,13 +515,15 @@ void intel_dvo_init(struct intel_display *display)
connector->get_hw_state = intel_dvo_connector_get_hw_state;
if (!intel_dvo_probe(display, intel_dvo)) {
- kfree(intel_dvo);
intel_connector_free(connector);
return;
}
assert_port_valid(display, intel_dvo->dev.port);
+ if (drmm_add_action_or_reset(display->drm, intel_dvo_dev_destroy, intel_dvo))
+ return;
+
encoder->type = INTEL_OUTPUT_DVO;
encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
encoder->port = intel_dvo->dev.port;
@@ -533,10 +533,10 @@ void intel_dvo_init(struct intel_display *display)
encoder->cloneable = BIT(INTEL_OUTPUT_ANALOG) |
BIT(INTEL_OUTPUT_DVO);
- drm_encoder_init(display->drm, &encoder->base,
- &intel_dvo_enc_funcs,
- intel_dvo_encoder_type(&intel_dvo->dev),
- "DVO %c", port_name(encoder->port));
+ drmm_encoder_init(display->drm, &encoder->base,
+ &intel_dvo_enc_funcs,
+ intel_dvo_encoder_type(&intel_dvo->dev),
+ "DVO %c", port_name(encoder->port));
drm_dbg_kms(display->drm, "[ENCODER:%d:%s] detected %s\n",
encoder->base.base.id, encoder->base.name,
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.c b/drivers/gpu/drm/i915/display/intel_encoder.c
index d01b081a60740..2ebd1e4457482 100644
--- a/drivers/gpu/drm/i915/display/intel_encoder.c
+++ b/drivers/gpu/drm/i915/display/intel_encoder.c
@@ -5,6 +5,8 @@
#include <linux/workqueue.h>
+#include <drm/drm_managed.h>
+
#include "intel_display_core.h"
#include "intel_display_types.h"
#include "intel_encoder.h"
@@ -104,11 +106,11 @@ void intel_encoder_shutdown_all(struct intel_display *display)
encoder->shutdown_complete(encoder);
}
-struct intel_digital_port *intel_dig_port_alloc(void)
+struct intel_digital_port *intel_dig_port_alloc(struct drm_device *drm)
{
struct intel_digital_port *dig_port;
- dig_port = kzalloc_obj(*dig_port);
+ dig_port = drmm_kzalloc(drm, sizeof(*dig_port), GFP_KERNEL);
if (!dig_port)
return NULL;
diff --git a/drivers/gpu/drm/i915/display/intel_encoder.h b/drivers/gpu/drm/i915/display/intel_encoder.h
index ace0fe1a8f27a..42f3982970065 100644
--- a/drivers/gpu/drm/i915/display/intel_encoder.h
+++ b/drivers/gpu/drm/i915/display/intel_encoder.h
@@ -6,6 +6,7 @@
#ifndef __INTEL_ENCODER_H__
#define __INTEL_ENCODER_H__
+struct drm_device;
struct intel_digital_port;
struct intel_display;
struct intel_encoder;
@@ -21,6 +22,6 @@ void intel_encoder_shutdown_all(struct intel_display *display);
void intel_encoder_block_all_hpds(struct intel_display *display);
void intel_encoder_unblock_all_hpds(struct intel_display *display);
-struct intel_digital_port *intel_dig_port_alloc(void);
+struct intel_digital_port *intel_dig_port_alloc(struct drm_device *drm);
#endif /* __INTEL_ENCODER_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index e78a41e2b268c..7bb99eb44a5a4 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -37,6 +37,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -517,7 +518,6 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = {
};
static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
- .destroy = intel_encoder_destroy,
};
static int intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
@@ -886,15 +886,14 @@ void intel_lvds_init(struct intel_display *display)
"LVDS is not present in VBT, but enabled anyway\n");
}
- lvds_encoder = kzalloc_obj(*lvds_encoder);
- if (!lvds_encoder)
+ lvds_encoder = drmm_encoder_alloc(display->drm, struct intel_lvds_encoder, base.base,
+ &intel_lvds_enc_funcs, DRM_MODE_ENCODER_LVDS, "LVDS");
+ if (IS_ERR(lvds_encoder))
return;
connector = intel_connector_alloc();
- if (!connector) {
- kfree(lvds_encoder);
+ if (!connector)
return;
- }
lvds_encoder->attached_connector = connector;
encoder = &lvds_encoder->base;
@@ -904,8 +903,6 @@ void intel_lvds_init(struct intel_display *display)
DRM_MODE_CONNECTOR_LVDS,
intel_gmbus_get_adapter(display, ddc_pin));
- drm_encoder_init(display->drm, &encoder->base, &intel_lvds_enc_funcs,
- DRM_MODE_ENCODER_LVDS, "LVDS");
encoder->enable = intel_enable_lvds;
encoder->pre_enable = intel_pre_enable_lvds;
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index 6eb2b4b45a9b4..f5aaa38002674 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -36,6 +36,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -2542,24 +2543,19 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs
.atomic_check = intel_sdvo_atomic_check,
};
-static void intel_sdvo_encoder_destroy(struct drm_encoder *_encoder)
+static void intel_sdvo_unselect_i2c_bus(struct intel_sdvo *sdvo);
+
+static void intel_sdvo_cleanup(struct drm_device *drm, void *data)
{
- struct intel_encoder *encoder = to_intel_encoder(_encoder);
- struct intel_sdvo *sdvo = to_sdvo(encoder);
+ struct intel_sdvo *intel_sdvo = data;
int i;
- for (i = 0; i < ARRAY_SIZE(sdvo->ddc); i++) {
- if (sdvo->ddc[i].ddc_bus)
- i2c_del_adapter(&sdvo->ddc[i].ddc);
+ for (i = 0; i < ARRAY_SIZE(intel_sdvo->ddc); i++) {
+ if (intel_sdvo->ddc[i].ddc_bus)
+ i2c_del_adapter(&intel_sdvo->ddc[i].ddc);
}
-
- drm_encoder_cleanup(&encoder->base);
- kfree(sdvo);
-};
-
-static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
- .destroy = intel_sdvo_encoder_destroy,
-};
+ intel_sdvo_unselect_i2c_bus(intel_sdvo);
+}
static int
intel_sdvo_guess_ddc_bus(struct intel_sdvo *sdvo,
@@ -3381,8 +3377,9 @@ bool intel_sdvo_init(struct intel_display *display,
if (!assert_sdvo_port_valid(display, port))
return false;
- intel_sdvo = kzalloc_obj(*intel_sdvo);
- if (!intel_sdvo)
+ intel_sdvo = drmm_encoder_alloc(display->drm, struct intel_sdvo, base.base,
+ NULL, 0, "SDVO %c", port_name(port));
+ if (IS_ERR(intel_sdvo))
return false;
/* encoder type will be decided later */
@@ -3391,15 +3388,14 @@ bool intel_sdvo_init(struct intel_display *display,
intel_encoder->power_domain = POWER_DOMAIN_PORT_OTHER;
intel_encoder->port = port;
- drm_encoder_init(display->drm, &intel_encoder->base,
- &intel_sdvo_enc_funcs, 0,
- "SDVO %c", port_name(port));
-
intel_sdvo->sdvo_reg = sdvo_reg;
intel_sdvo->target_addr = intel_sdvo_get_target_addr(intel_sdvo) >> 1;
intel_sdvo_select_i2c_bus(intel_sdvo);
+ if (drmm_add_action_or_reset(display->drm, intel_sdvo_cleanup, intel_sdvo))
+ return false;
+
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
u8 byte;
@@ -3408,7 +3404,7 @@ bool intel_sdvo_init(struct intel_display *display,
drm_dbg_kms(display->drm,
"No SDVO device found on %s\n",
SDVO_NAME(intel_sdvo));
- goto err;
+ return false;
}
}
@@ -3428,7 +3424,7 @@ bool intel_sdvo_init(struct intel_display *display,
/* In default case sdvo lvds is false */
if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps))
- goto err;
+ return false;
intel_sdvo->colorimetry_cap =
intel_sdvo_get_colorimetry_cap(intel_sdvo);
@@ -3439,7 +3435,7 @@ bool intel_sdvo_init(struct intel_display *display,
ret = intel_sdvo_init_ddc_proxy(&intel_sdvo->ddc[i],
intel_sdvo, i + 1);
if (ret)
- goto err;
+ return false;
}
if (!intel_sdvo_output_setup(intel_sdvo)) {
@@ -3502,9 +3498,6 @@ bool intel_sdvo_init(struct intel_display *display,
err_output:
intel_sdvo_output_cleanup(intel_sdvo);
-err:
- intel_sdvo_unselect_i2c_bus(intel_sdvo);
- intel_sdvo_encoder_destroy(&intel_encoder->base);
return false;
}
diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
index 8fbf0adb56992..05df0acc6dc3e 100644
--- a/drivers/gpu/drm/i915/display/intel_tv.c
+++ b/drivers/gpu/drm/i915/display/intel_tv.c
@@ -33,6 +33,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -1881,7 +1882,6 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs =
};
static const struct drm_encoder_funcs intel_tv_enc_funcs = {
- .destroy = intel_encoder_destroy,
};
static void intel_tv_add_properties(struct drm_connector *connector)
@@ -1966,10 +1966,10 @@ intel_tv_init(struct intel_display *display)
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
- intel_tv = kzalloc_obj(*intel_tv);
- if (!intel_tv) {
+ intel_tv = drmm_encoder_alloc(display->drm, struct intel_tv, base.base,
+ &intel_tv_enc_funcs, DRM_MODE_ENCODER_TVDAC, "TV");
+ if (IS_ERR(intel_tv))
return;
- }
intel_connector = intel_connector_alloc();
if (!intel_connector) {
@@ -1996,9 +1996,6 @@ intel_tv_init(struct intel_display *display)
drm_connector_init(display->drm, connector, &intel_tv_connector_funcs,
DRM_MODE_CONNECTOR_SVIDEO);
- drm_encoder_init(display->drm, &intel_encoder->base,
- &intel_tv_enc_funcs,
- DRM_MODE_ENCODER_TVDAC, "TV");
intel_encoder->compute_config = intel_tv_compute_config;
intel_encoder->get_config = intel_tv_get_config;
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index d4db73c184e5c..e84edb6242716 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -30,6 +30,7 @@
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_managed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
@@ -1531,7 +1532,6 @@ static void intel_dsi_unprepare(struct intel_encoder *encoder)
}
static const struct drm_encoder_funcs intel_dsi_funcs = {
- .destroy = intel_encoder_destroy,
};
static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector,
@@ -1918,22 +1918,19 @@ void vlv_dsi_init(struct intel_display *display)
else
display->dsi.mmio_base = VLV_MIPI_BASE;
- intel_dsi = kzalloc_obj(*intel_dsi);
- if (!intel_dsi)
+ intel_dsi = drmm_encoder_alloc(display->drm, struct intel_dsi, base.base,
+ &intel_dsi_funcs, DRM_MODE_ENCODER_DSI,
+ "DSI %c", port_name(port));
+ if (IS_ERR(intel_dsi))
return;
connector = intel_connector_alloc();
- if (!connector) {
- kfree(intel_dsi);
+ if (!connector)
return;
- }
encoder = &intel_dsi->base;
intel_dsi->attached_connector = connector;
- drm_encoder_init(display->drm, &encoder->base, &intel_dsi_funcs,
- DRM_MODE_ENCODER_DSI, "DSI %c", port_name(port));
-
encoder->compute_config = intel_dsi_compute_config;
encoder->pre_enable = intel_dsi_pre_enable;
if (display->platform.geminilake || display->platform.broxton)
@@ -1985,14 +1982,14 @@ void vlv_dsi_init(struct intel_display *display)
host = intel_dsi_host_init(intel_dsi, &intel_dsi_host_ops,
port);
if (!host)
- goto err;
+ return;
intel_dsi->dsi_hosts[port] = host;
}
if (!intel_dsi_vbt_init(intel_dsi, MIPI_DSI_GENERIC_PANEL_ID)) {
drm_dbg_kms(display->drm, "no device found\n");
- goto err;
+ return;
}
/* Use clock read-back from current hw-state for fastboot */
@@ -2050,8 +2047,5 @@ void vlv_dsi_init(struct intel_display *display)
err_cleanup_connector:
drm_connector_cleanup(&connector->base);
-err:
- drm_encoder_cleanup(&encoder->base);
- kfree(intel_dsi);
kfree(connector);
}
--
2.43.0
next prev parent reply other threads:[~2026-04-09 17:09 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 17:08 [PATCH RFC 00/12] Add support for DisplayPort link training information report Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 01/12] drm/i915/display/intel_sdvo: Fix double connector destroy in error paths Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 02/12] drm/i915/display/intel_lvds: Drop redundant manual cleanup on init failure Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 03/12] drm/i915/display/intel_dp: Drop redundant intel_dp_aux_fini() " Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 04/12] drm/i915/display: Switch to drmm_mode_config_init() and drop manual cleanup Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 05/12] drm/i915/display: Switch to managed for crtc Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 06/12] drm/i915/display: Switch to managed for plane Kory Maincent
2026-04-09 17:08 ` Kory Maincent [this message]
2026-04-09 17:08 ` [PATCH RFC 08/12] drm/i915/display: Switch to managed for connector Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 09/12] drm: Introduce drmm_connector_dp_init() with link training state properties Kory Maincent
2026-04-09 21:53 ` Dmitry Baryshkov
2026-04-09 17:08 ` [PATCH RFC 10/12] drm/i915/display/dp: Adopt dp_connector helpers to expose link training state Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 11/12] drm/bridge: Wire drmm_connector_dp_init() via new DRM_BRIDGE_OP_DP flag Kory Maincent
2026-04-09 17:08 ` [PATCH RFC 12/12] drm/mediatek: Use dp_connector helpers to report link training state Kory Maincent
2026-04-09 20:36 ` [PATCH RFC 00/12] Add support for DisplayPort link training information report Ville Syrjälä
2026-04-09 21:36 ` Dmitry Baryshkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260409-feat_link_cap-v1-7-7069e8199ce2@bootlin.com \
--to=kory.maincent@bootlin.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=airlied@redhat.com \
--cc=andrzej.hajda@intel.com \
--cc=angelogioacchino.delregno@collabora.com \
--cc=chris@chris-wilson.co.uk \
--cc=chunkuang.hu@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=eric@anholt.net \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=jbarnes@virtuousgeek.org \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=joonas.lahtinen@linux.intel.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mediatek@lists.infradead.org \
--cc=louis.chauvet@bootlin.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=markyacoub@google.com \
--cc=matthias.bgg@gmail.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=p.zabel@pengutronix.de \
--cc=rfoss@kernel.org \
--cc=rodrigo.vivi@intel.com \
--cc=seanpaul@google.com \
--cc=simona.vetter@ffwll.ch \
--cc=simona@ffwll.ch \
--cc=thomas.petazzoni@bootlin.com \
--cc=tursulin@ursulin.net \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox