Use drmm_kzalloc() to align encoder memory lifetime with the drm device, and use drmm_add_action_or_reset() to make sure drm_encoder_cleanup() is called before the memory is freed. Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> Acked-by: Daniel Vetter <daniel.vetter@xxxxxxxx> --- Changes since v1: - Split from patch "drm/imx: dw_hdmi-imx: use drm managed resources, switch to dw_hdmi_probe" --- drivers/gpu/drm/imx/dw_hdmi-imx.c | 34 ++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index bbd0a0cd7c3d..16be8bd92653 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -18,14 +18,21 @@ #include <drm/drm_bridge.h> #include <drm/drm_edid.h> #include <drm/drm_encoder.h> +#include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_simple_kms_helper.h> #include "imx-drm.h" +struct imx_hdmi; + +struct imx_hdmi_encoder { + struct drm_encoder encoder; + struct imx_hdmi *hdmi; +}; + struct imx_hdmi { struct device *dev; - struct drm_encoder encoder; struct drm_bridge *bridge; struct dw_hdmi *hdmi; struct regmap *regmap; @@ -33,7 +40,7 @@ struct imx_hdmi { static inline struct imx_hdmi *enc_to_imx_hdmi(struct drm_encoder *e) { - return container_of(e, struct imx_hdmi, encoder); + return container_of(e, struct imx_hdmi_encoder, encoder)->hdmi; } static const struct dw_hdmi_mpll_config imx_mpll_cfg[] = { @@ -181,18 +188,27 @@ static const struct of_device_id dw_hdmi_imx_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, dw_hdmi_imx_dt_ids); +static void dw_hdmi_imx_encoder_cleanup(struct drm_device *drm, void *data) +{ + struct drm_encoder *encoder = data; + + drm_encoder_cleanup(encoder); +} + static int dw_hdmi_imx_bind(struct device *dev, struct device *master, void *data) { struct drm_device *drm = data; + struct imx_hdmi_encoder *hdmi_encoder; struct drm_encoder *encoder; - struct imx_hdmi *hdmi; int ret; - hdmi = dev_get_drvdata(dev); - memset(&hdmi->encoder, 0, sizeof(hdmi->encoder)); + hdmi_encoder = drmm_kzalloc(drm, sizeof(*hdmi_encoder), GFP_KERNEL); + if (!hdmi_encoder) + return -ENOMEM; - encoder = &hdmi->encoder; + hdmi_encoder->hdmi = dev_get_drvdata(dev); + encoder = &hdmi_encoder->encoder; ret = imx_drm_encoder_parse_of(drm, encoder, dev->of_node); if (ret) @@ -201,7 +217,11 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, drm_encoder_helper_add(encoder, &dw_hdmi_imx_encoder_helper_funcs); drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); - return drm_bridge_attach(encoder, hdmi->bridge, NULL, 0); + ret = drmm_add_action_or_reset(drm, dw_hdmi_imx_encoder_cleanup, encoder); + if (ret) + return ret; + + return drm_bridge_attach(encoder, hdmi_encoder->hdmi->bridge, NULL, 0); } static const struct component_ops dw_hdmi_imx_ops = { -- 2.20.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel