Re: [Freedreno] [PATCH v3 03/20] drm/dp: Move i2c init to drm_dp_aux_init, add __must_check and fini

2021-04-19 Thread Ville Syrjälä
On Mon, Apr 19, 2021 at 06:55:05PM -0400, Lyude Paul wrote:
> 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.

The init vs. register split is intentional. Registering the thing
and allowing userspace access to it before the rest of the driver
is ready isn't particularly great. For a while now we've tried to
move towards an architecture where the driver is fully initialzied
before anything gets exposed to userspace.

-- 
Ville Syrjälä
Intel
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 03/20] drm/dp: Move i2c init to drm_dp_aux_init, add __must_check and fini

2021-04-19 Thread Lyude Paul
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