diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
index b9c11c2b2885..23b2134a651b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
@@ -1963,8 +1963,11 @@ amdgpu_connector_add(struct amdgpu_device *adev,
 
 	connector->display_info.subpixel_order = subpixel_order;
 
-	if (has_aux)
-		amdgpu_atombios_dp_aux_init(amdgpu_connector);
+	if (has_aux) {
+		int ret = amdgpu_atombios_dp_aux_init(amdgpu_connector);
+		if (ret)
+			goto failed;
+	}
 
 	if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
 	    connector_type == DRM_MODE_CONNECTOR_eDP) {
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
index a3ba9ca11e98..54c209ab8c9f 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -184,12 +184,18 @@ amdgpu_atombios_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *m
 	return ret;
 }
 
-void amdgpu_atombios_dp_aux_init(struct amdgpu_connector *amdgpu_connector)
+int amdgpu_atombios_dp_aux_init(struct amdgpu_connector *amdgpu_connector)
 {
+	int ret;
+
 	amdgpu_connector->ddc_bus->rec.hpd = amdgpu_connector->hpd.hpd;
 	amdgpu_connector->ddc_bus->aux.transfer = amdgpu_atombios_dp_aux_transfer;
-	drm_dp_aux_init(&amdgpu_connector->ddc_bus->aux);
+	ret = drm_dp_aux_init(&amdgpu_connector->ddc_bus->aux);
+	if (ret)
+		return ret;
+
 	amdgpu_connector->ddc_bus->has_aux = true;
+	return ret;
 }
 
 /***** general DP utility functions *****/
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_dp.h b/drivers/gpu/drm/amd/amdgpu/atombios_dp.h
index f59d85eaddf0..6b65cbf009fd 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_dp.h
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_dp.h
@@ -24,7 +24,7 @@
 #ifndef __ATOMBIOS_DP_H__
 #define __ATOMBIOS_DP_H__
 
-void amdgpu_atombios_dp_aux_init(struct amdgpu_connector *amdgpu_connector);
+int amdgpu_atombios_dp_aux_init(struct amdgpu_connector *amdgpu_connector);
 u8 amdgpu_atombios_dp_get_sinktype(struct amdgpu_connector *amdgpu_connector);
 int amdgpu_atombios_dp_get_dpcd(struct amdgpu_connector *amdgpu_connector);
 int amdgpu_atombios_dp_get_panel_mode(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index 3dee9cce9c9e..51fbbf3ef59b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -439,7 +439,10 @@ int amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 	dm_aux->aux.transfer = dm_dp_aux_transfer;
 	dm_aux->ddc_service = aconnector->dc_link->ddc;
 
-	drm_dp_aux_init(&dm_aux->aux);
+	ret = drm_dp_aux_init(&dm_aux->aux);
+	if (ret)
+		goto free_name;
+
 	drm_dp_cec_register_connector(&dm_aux->aux, &aconnector->base);
 
 	if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
@@ -456,6 +459,7 @@ int amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
 	return 0;
 unreg_cec:
 	drm_dp_cec_unregister_connector(&dm_aux->aux);
+free_name:
 	kfree(dm_aux->aux.name);
 	return ret;
 }
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
index aa6cda458eb9..c105dcb79c37 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx6345.c
@@ -794,6 +794,8 @@ static int anx6345_i2c_remove(struct i2c_client *client)
 
 	unregister_i2c_dummy_clients(anx6345);
 
+	drm_dp_aux_fini(&anx6345->aux);
+
 	kfree(anx6345->edid);
 
 	mutex_destroy(&anx6345->lock);
diff --git a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
index f20558618220..0778458e81be 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix-anx78xx.c
@@ -1364,6 +1364,8 @@ static int anx78xx_i2c_remove(struct i2c_client *client)
 
 	unregister_i2c_dummy_clients(anx78xx);
 
+	drm_dp_aux_fini(&anx78xx->aux);
+
 	kfree(anx78xx->edid);
 
 	return 0;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index f115233b1cb9..f82e193d32ae 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1806,6 +1806,7 @@ EXPORT_SYMBOL_GPL(analogix_dp_unbind);
 void analogix_dp_remove(struct analogix_dp_device *dp)
 {
 	clk_disable_unprepare(dp->clock);
+	drm_dp_aux_fini(&dp->aux);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_remove);
 
diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
index 01e95466502a..c5e2bc75b226 100644
--- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -2436,14 +2436,17 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 	mutex_init(&mhdp->link_mutex);
 	spin_lock_init(&mhdp->start_lock);
 
-	drm_dp_aux_init(&mhdp->aux);
 	mhdp->aux.dev = dev;
 	mhdp->aux.transfer = cdns_mhdp_transfer;
+	ret = drm_dp_aux_init(&mhdp->aux);
+	if (ret)
+		return ret;
 
 	mhdp->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mhdp->regs)) {
 		dev_err(dev, "Failed to get memory resource\n");
-		return PTR_ERR(mhdp->regs);
+		ret = PTR_ERR(mhdp->regs);
+		goto aux_fini;
 	}
 
 	mhdp->sapb_regs = devm_platform_ioremap_resource_byname(pdev, "mhdptx-sapb");
@@ -2458,7 +2461,8 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 	mhdp->phy = devm_of_phy_get_by_index(dev, pdev->dev.of_node, 0);
 	if (IS_ERR(mhdp->phy)) {
 		dev_err(dev, "no PHY configured\n");
-		return PTR_ERR(mhdp->phy);
+		ret = PTR_ERR(mhdp->phy);
+		goto aux_fini;
 	}
 
 	platform_set_drvdata(pdev, mhdp);
@@ -2555,6 +2559,8 @@ static int cdns_mhdp_probe(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 clk_disable:
 	clk_disable_unprepare(mhdp->clk);
+aux_fini:
+	drm_dp_aux_fini(&mhdp->aux);
 
 	return ret;
 }
@@ -2597,6 +2603,8 @@ static int cdns_mhdp_remove(struct platform_device *pdev)
 
 	clk_disable_unprepare(mhdp->clk);
 
+	drm_dp_aux_fini(&mhdp->aux);
+
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index da89922721ed..6a56acf36a9a 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -1693,7 +1693,9 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	tc->aux.name = "TC358767 AUX i2c adapter";
 	tc->aux.dev = tc->dev;
 	tc->aux.transfer = tc_aux_transfer;
-	drm_dp_aux_init(&tc->aux);
+	ret = drm_dp_aux_init(&tc->aux);
+	if (ret)
+		return ret;
 
 	tc->bridge.funcs = &tc_bridge_funcs;
 	if (tc->hpd_pin >= 0)
@@ -1713,6 +1715,7 @@ static int tc_remove(struct i2c_client *client)
 	struct tc_data *tc = i2c_get_clientdata(client);
 
 	drm_bridge_remove(&tc->bridge);
+	drm_dp_aux_fini(&tc->aux);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
index 88df4dd0f39d..6190451c9195 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -1291,17 +1291,16 @@ static int ti_sn_bridge_probe(struct i2c_client *client,
 	pm_runtime_enable(pdata->dev);
 
 	ret = ti_sn_setup_gpio_controller(pdata);
-	if (ret) {
-		pm_runtime_disable(pdata->dev);
-		return ret;
-	}
-
+	if (ret)
+		goto fail_pm;
 	i2c_set_clientdata(client, pdata);
 
 	pdata->aux.name = "ti-sn65dsi86-aux";
 	pdata->aux.dev = pdata->dev;
 	pdata->aux.transfer = ti_sn_aux_transfer;
-	drm_dp_aux_init(&pdata->aux);
+	ret = drm_dp_aux_init(&pdata->aux);
+	if (ret)
+		goto fail_pm;
 
 	pdata->bridge.funcs = &ti_sn_bridge_funcs;
 	pdata->bridge.of_node = client->dev.of_node;
@@ -1311,6 +1310,9 @@ static int ti_sn_bridge_probe(struct i2c_client *client,
 	ti_sn_debugfs_init(pdata);
 
 	return 0;
+fail_pm:
+	pm_runtime_disable(pdata->dev);
+	return ret;
 }
 
 static int ti_sn_bridge_remove(struct i2c_client *client)
@@ -1332,6 +1334,8 @@ static int ti_sn_bridge_remove(struct i2c_client *client)
 		mipi_dsi_device_unregister(pdata->dsi);
 	}
 
+	drm_dp_aux_fini(&pdata->aux);
+
 	drm_bridge_remove(&pdata->bridge);
 
 	return 0;
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index cb2f53e56685..6c9e552233fd 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1731,10 +1731,18 @@ EXPORT_SYMBOL(drm_dp_remote_aux_init);
  * If you need to use the drm_dp_aux's i2c adapter prior to registering it
  * with the outside world, call drm_dp_aux_init() first. You must still
  * call drm_dp_aux_register() once the connector has been registered to
- * allow userspace access to the auxiliary DP channel.
+ * allow userspace access to the auxiliary DP channel. Once the AUX channel is
+ * no longer being used and has been unregistered with
+ * drm_dp_aux_unregister(), the driver must clean up any resources it's
+ * allocated with drm_dp_aux_fini().
+ *
+ * Returns:
+ * %0 on success, negative error code on failure
  */
-void drm_dp_aux_init(struct drm_dp_aux *aux)
+int drm_dp_aux_init(struct drm_dp_aux *aux)
 {
+	int ret;
+
 	mutex_init(&aux->hw_mutex);
 	mutex_init(&aux->cec.lock);
 	INIT_WORK(&aux->crc_work, drm_dp_aux_crc_work);
@@ -1744,16 +1752,55 @@ void drm_dp_aux_init(struct drm_dp_aux *aux)
 	aux->ddc.retries = 3;
 
 	aux->ddc.lock_ops = &drm_dp_i2c_lock_ops;
+
+	aux->ddc.class = I2C_CLASS_DDC;
+	aux->ddc.owner = THIS_MODULE;
+	aux->ddc.dev.parent = aux->dev;
+
+	strlcpy(aux->ddc.name, aux->name ?: dev_name(aux->dev), sizeof(aux->ddc.name));
+
+	ret = i2c_add_adapter(&aux->ddc);
+	if (ret) {
+		aux->ddc.algo = NULL;
+		mutex_destroy(&aux->hw_mutex);
+		mutex_destroy(&aux->cec.lock);
+	}
+
+	return ret;
 }
 EXPORT_SYMBOL(drm_dp_aux_init);
 
 /**
- * drm_dp_aux_register() - initialise and register aux channel
+ * drm_dp_aux_fini() - release resources from an aux channel
  * @aux: DisplayPort AUX channel
  *
- * Automatically calls drm_dp_aux_init() if this hasn't been done yet.
+ * Cleans up any resources associated with a DP AUX channel, along with
+ * removing it's associated i2c adapter. Must always be called once an AUX
+ * channel is being removed. Note that if drm_dp_aux_init() was not called on
+ * @aux, this function is a no-op.
+ */
+void drm_dp_aux_fini(struct drm_dp_aux *aux)
+{
+	if (!aux->ddc.algo)
+		return;
+
+	i2c_del_adapter(&aux->ddc);
+	mutex_destroy(&aux->hw_mutex);
+	mutex_destroy(&aux->cec.lock);
+}
+EXPORT_SYMBOL(drm_dp_aux_fini);
+
+/**
+ * drm_dp_aux_register() - register aux channel
+ * @aux: DisplayPort AUX channel
+ *
+ * Automatically calls drm_dp_aux_init() if this hasn't been done yet. The
+ * driver must make sure to call drm_dp_aux_unregister() to unregister the
+ * device, and drm_dp_aux_fini() to cleanup the device after it's been
+ * unregistered.
+ *
  * This should only be called when the underlying &struct drm_connector is
- * initialiazed already. Therefore the best place to call this is from
+ * initialized already. Therefore the best place to call this is from
  * &drm_connector_funcs.late_register. Not that drivers which don't follow this
  * will Oops when CONFIG_DRM_DP_AUX_CHARDEV is enabled.
  *
@@ -1766,39 +1813,32 @@ EXPORT_SYMBOL(drm_dp_aux_init);
 int drm_dp_aux_register(struct drm_dp_aux *aux)
 {
 	int ret;
+	const bool init_aux = !aux->ddc.algo;
 
-	if (!aux->ddc.algo)
-		drm_dp_aux_init(aux);
-
-	aux->ddc.class = I2C_CLASS_DDC;
-	aux->ddc.owner = THIS_MODULE;
-	aux->ddc.dev.parent = aux->dev;
-
-	strlcpy(aux->ddc.name, aux->name ? aux->name : dev_name(aux->dev),
-		sizeof(aux->ddc.name));
+	if (init_aux) {
+		ret = drm_dp_aux_init(aux);
+		if (ret)
+			return ret;
+	}
 
 	ret = drm_dp_aux_register_devnode(aux);
-	if (ret)
-		return ret;
+	if (ret && init_aux)
+		drm_dp_aux_fini(aux);
 
-	ret = i2c_add_adapter(&aux->ddc);
-	if (ret) {
-		drm_dp_aux_unregister_devnode(aux);
-		return ret;
-	}
-
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL(drm_dp_aux_register);
 
 /**
  * drm_dp_aux_unregister() - unregister an AUX adapter
  * @aux: DisplayPort AUX channel
+ *
+ * Note that this function does not take care of calling drm_dp_aux_fini(),
+ * the driver must handle this part itself.
  */
 void drm_dp_aux_unregister(struct drm_dp_aux *aux)
 {
 	drm_dp_aux_unregister_devnode(aux);
-	i2c_del_adapter(&aux->ddc);
 }
 EXPORT_SYMBOL(drm_dp_aux_unregister);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c
index 7e83bc2cc34a..a79c6e781638 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c
@@ -644,15 +644,17 @@ void intel_dp_aux_fini(struct intel_dp *intel_dp)
 	if (cpu_latency_qos_request_active(&intel_dp->pm_qos))
 		cpu_latency_qos_remove_request(&intel_dp->pm_qos);
 
+	drm_dp_aux_fini(&intel_dp->aux);
 	kfree(intel_dp->aux.name);
 }
 
-void intel_dp_aux_init(struct intel_dp *intel_dp)
+int intel_dp_aux_init(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *encoder = &dig_port->base;
 	enum aux_ch aux_ch = dig_port->aux_ch;
+	int ret;
 
 	if (DISPLAY_VER(dev_priv) >= 12) {
 		intel_dp->aux_ch_ctl_reg = tgl_aux_ctl_reg;
@@ -682,7 +684,9 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
 	else
 		intel_dp->get_aux_send_ctl = g4x_get_aux_send_ctl;
 
-	drm_dp_aux_init(&intel_dp->aux);
+	ret = drm_dp_aux_init(&intel_dp->aux);
+	if (ret)
+		return ret;
 
 	/* Failure to allocate our preferred name is not critical */
 	if (DISPLAY_VER(dev_priv) >= 12 && aux_ch >= AUX_CH_USBC1)
@@ -696,4 +700,6 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
 
 	intel_dp->aux.transfer = intel_dp_aux_transfer;
 	cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
+
+	return ret;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.h b/drivers/gpu/drm/i915/display/intel_dp_aux.h
index 4afbe76217b9..321bab28eb07 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux.h
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux.h
@@ -13,6 +13,6 @@ struct intel_dp;
 u32 intel_dp_pack_aux(const u8 *src, int src_bytes);
 
 void intel_dp_aux_fini(struct intel_dp *intel_dp);
-void intel_dp_aux_init(struct intel_dp *intel_dp);
+int intel_dp_aux_init(struct intel_dp *intel_dp);
 
 #endif /* __INTEL_DP_AUX_H__ */
diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c
index 7c22bfe0fc7d..2ef42ca1fda5 100644
--- a/drivers/gpu/drm/msm/dp/dp_aux.c
+++ b/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -494,6 +494,7 @@ int dp_aux_register(struct drm_dp_aux *dp_aux)
 void dp_aux_unregister(struct drm_dp_aux *dp_aux)
 {
 	drm_dp_aux_unregister(dp_aux);
+	drm_dp_aux_fini(dp_aux);
 }
 
 struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog)
diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c
index df10a0196d94..ced3a38781ed 100644
--- a/drivers/gpu/drm/msm/edp/edp_aux.c
+++ b/drivers/gpu/drm/msm/edp/edp_aux.c
@@ -218,6 +218,7 @@ void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux)
 {
 	if (aux) {
 		drm_dp_aux_unregister(&aux->drm_aux);
+		drm_dp_aux_fini(&aux->drm_aux);
 		mutex_destroy(&aux->msg_mutex);
 	}
 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 61e6d7412505..e5a93fab856e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -402,6 +402,7 @@ nouveau_connector_destroy(struct drm_connector *connector)
 	if (nv_connector->aux.transfer) {
 		drm_dp_cec_unregister_connector(&nv_connector->aux);
 		drm_dp_aux_unregister(&nv_connector->aux);
+		drm_dp_aux_fini(&nv_connector->aux);
 		kfree(nv_connector->aux.name);
 	}
 	kfree(connector);
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 607ad5620bd9..f185d3e96bf8 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -921,6 +921,7 @@ static void radeon_connector_unregister(struct drm_connector *connector)
 
 	if (radeon_connector->ddc_bus && radeon_connector->ddc_bus->has_aux) {
 		drm_dp_aux_unregister(&radeon_connector->ddc_bus->aux);
+		drm_dp_aux_fini(&radeon_connector->ddc_bus->aux);
 		radeon_connector->ddc_bus->has_aux = false;
 	}
 }
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index ea56c6ec25e4..6379f2f32d4d 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -534,7 +534,9 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 	dpaux->aux.transfer = tegra_dpaux_transfer;
 	dpaux->aux.dev = &pdev->dev;
 
-	drm_dp_aux_init(&dpaux->aux);
+	err = drm_dp_aux_init(&dpaux->aux);
+	if (err)
+		return err;
 
 	/*
 	 * Assume that by default the DPAUX/I2C pads will be used for HDMI,
@@ -546,7 +548,7 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 	 */
 	err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
 	if (err < 0)
-		return err;
+		goto aux_fini;
 
 #ifdef CONFIG_GENERIC_PINCONF
 	dpaux->desc.name = dev_name(&pdev->dev);
@@ -559,7 +561,8 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 	dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
 	if (IS_ERR(dpaux->pinctrl)) {
 		dev_err(&pdev->dev, "failed to register pincontrol\n");
-		return PTR_ERR(dpaux->pinctrl);
+		err = PTR_ERR(dpaux->pinctrl);
+		goto aux_fini;
 	}
 #endif
 	/* enable and clear all interrupts */
@@ -573,6 +576,9 @@ static int tegra_dpaux_probe(struct platform_device *pdev)
 	mutex_unlock(&dpaux_lock);
 
 	return 0;
+aux_fini:
+	drm_dp_aux_fini(&dpaux->aux);
+	return err;
 }
 
 static int tegra_dpaux_remove(struct platform_device *pdev)
@@ -584,6 +590,8 @@ static int tegra_dpaux_remove(struct platform_device *pdev)
 	/* make sure pads are powered down when not in use */
 	tegra_dpaux_pad_power_down(dpaux);
 
+	drm_dp_aux_fini(&dpaux->aux);
+
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 59d1fb017da0..5370b99aabdf 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1083,6 +1083,7 @@ static int zynqmp_dp_aux_init(struct zynqmp_dp *dp)
 static void zynqmp_dp_aux_cleanup(struct zynqmp_dp *dp)
 {
 	drm_dp_aux_unregister(&dp->aux);
+	drm_dp_aux_fini(&dp->aux);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index e44b0ee7b85e..54d13a4d819f 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -2009,7 +2009,8 @@ bool drm_dp_lttpr_voltage_swing_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP
 bool drm_dp_lttpr_pre_emphasis_level_3_supported(const u8 caps[DP_LTTPR_PHY_CAP_SIZE]);
 
 void drm_dp_remote_aux_init(struct drm_dp_aux *aux);
-void drm_dp_aux_init(struct drm_dp_aux *aux);
+__must_check int drm_dp_aux_init(struct drm_dp_aux *aux);
+void drm_dp_aux_fini(struct drm_dp_aux *aux);
 __must_check int drm_dp_aux_register(struct drm_dp_aux *aux);
 void drm_dp_aux_unregister(struct drm_dp_aux *aux);
 
