drm_encoder_cleanup is responsible for calling drm_bridge_detach for
each bridge attached to the encoder. zynqmp_dp_bridge_detach is in turn
responsible for unregistering the AUX bus. However, we never ended up
calling drm_encoder_cleanup in the remove or error paths, so the AUX bus
would stick around after the rest of the driver had been removed.

I don't really understand why drm_mode_config_cleanup doesn't call
drm_encoder_cleanup for us. It will call destroy (which for
simple_encoder is drm_encoder_cleanup) on encoders in the mode_config's
encoder_list.

Should drm_encoder_cleanup get called before or after
drm_atomic_helper_shutdown?

Fixes: 2dfd045c8435 ("drm: xlnx: zynqmp_dpsub: Register AUX bus at bridge 
attach time")
Signed-off-by: Sean Anderson <sean.ander...@linux.dev>
---

Changes in v5:
- New

 drivers/gpu/drm/xlnx/zynqmp_kms.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/xlnx/zynqmp_kms.c 
b/drivers/gpu/drm/xlnx/zynqmp_kms.c
index 43bf416b33d5..f25583ce92e6 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_kms.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_kms.c
@@ -433,23 +433,28 @@ static int zynqmp_dpsub_kms_init(struct zynqmp_dpsub 
*dpsub)
                                DRM_BRIDGE_ATTACH_NO_CONNECTOR);
        if (ret) {
                dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
-               return ret;
+               goto err_encoder;
        }
 
        /* Create the connector for the chain of bridges. */
        connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder);
        if (IS_ERR(connector)) {
                dev_err(dpsub->dev, "failed to created connector\n");
-               return PTR_ERR(connector);
+               ret = PTR_ERR(connector);
+               goto err_encoder;
        }
 
        ret = drm_connector_attach_encoder(connector, encoder);
        if (ret < 0) {
                dev_err(dpsub->dev, "failed to attach connector to encoder\n");
-               return ret;
+               goto err_encoder;
        }
 
        return 0;
+
+err_encoder:
+       drm_encoder_cleanup(encoder);
+       return ret;
 }
 
 static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res)
@@ -529,5 +534,6 @@ void zynqmp_dpsub_drm_cleanup(struct zynqmp_dpsub *dpsub)
 
        drm_dev_unregister(drm);
        drm_atomic_helper_shutdown(drm);
+       drm_encoder_cleanup(&dpsub->drm->encoder);
        drm_kms_helper_poll_fini(drm);
 }
-- 
2.35.1.1320.gc452695387.dirty

Reply via email to