When moving around drm_dp_aux_register() calls, it turned out we
accidentally managed to cause issues with the Tegra driver due to the fact
the Tegra driver would attempt to retrieve a reference to the AUX channel's
i2c adapter - which wouldn't be initialized until drm_dp_aux_register() is
called.
This doesn't actually make a whole ton of sense, as it's not unexpected for
a driver to need to be able to use an AUX adapter before it's been
registered. Likewise-it's not unexpected for a driver to try using the i2c
adapter for said AUX channel before it's been registered as well. In fact,
the current documentation for drm_dp_aux_init() even seems to imply that
drm_dp_aux_init() is supposed to be handling i2c adapter creation for this
precise reason - not drm_dp_aux_register().
Since the i2c adapter doesn't need to be linked to the DRM device in any
way, we can just fix this problem by moving i2c adapter creation out of
drm_dp_aux_register() and into drm_dp_aux_init(). Additionally, since this
means that drm_dp_aux_init() can fail we go ahead and add a __must_check
attribute to it so that drivers don't ignore its return status on failures.
And finally, we add a drm_dp_aux_fini() and hook it up in all DRM drivers
across the kernel to take care of cleaning up the i2c adapter once it's no
longer needed.
This should also fix the regressions noted in the Tegra driver.
Signed-off-by: Lyude Paul
Fixes: 39c17ae60ea9 ("drm/tegra: Don't register DP AUX channels before
connectors")
Cc: Thierry Reding
Cc: Thierry Reding
---
.../gpu/drm/amd/amdgpu/amdgpu_connectors.c| 7 +-
drivers/gpu/drm/amd/amdgpu/atombios_dp.c | 10 ++-
drivers/gpu/drm/amd/amdgpu/atombios_dp.h | 2 +-
.../display/amdgpu_dm/amdgpu_dm_mst_types.c | 6 +-
.../drm/bridge/analogix/analogix-anx6345.c| 2 +
.../drm/bridge/analogix/analogix-anx78xx.c| 2 +
.../drm/bridge/analogix/analogix_dp_core.c| 1 +
.../drm/bridge/cadence/cdns-mhdp8546-core.c | 14 ++-
drivers/gpu/drm/bridge/tc358767.c | 5 +-
drivers/gpu/drm/bridge/ti-sn65dsi86.c | 16 ++--
drivers/gpu/drm/drm_dp_helper.c | 88 ++-
drivers/gpu/drm/i915/display/intel_dp_aux.c | 10 ++-
drivers/gpu/drm/i915/display/intel_dp_aux.h | 2 +-
drivers/gpu/drm/msm/dp/dp_aux.c | 1 +
drivers/gpu/drm/msm/edp/edp_aux.c | 1 +
drivers/gpu/drm/nouveau/nouveau_connector.c | 1 +
drivers/gpu/drm/radeon/radeon_connectors.c| 1 +
drivers/gpu/drm/tegra/dpaux.c | 14 ++-
drivers/gpu/drm/xlnx/zynqmp_dp.c | 1 +
include/drm/drm_dp_helper.h | 3 +-
20 files changed, 140 insertions(+), 47 deletions(-)
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(_connector->ddc_bus->aux);
+ ret = drm_dp_aux_init(_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