[PATCH v2 01/10] drm/bridge: analogix_dp: Manage pm runtime and IRQ for native HPD pin detection

Damon Ding <[email protected]>
Newsgroups gmane.linux.drivers.devicetree,gmane.comp.video.dri.devel,gmane.linux.kernel,gmane.linux.ports.arm.rockchip,gmane.linux.ports.arm.kernel
Message-ID <[email protected]>
On Rockchip platforms, the Analogix DP native HPD pin IRQ functionality
requires the DP controller to be powered, clocked and initialized to
generate plug/unplug interrupts correctly.

To keep HPD detection active while the display is disabled, move
enable_irq()/disable_irq() out of bridge enable/disable handlers and
split IRQ management paths:
- Native HPD pin mode: enable IRQ in analogix_dp_bind() and disable
  in analogix_dp_unbind(). Hold runtime PM power to keep controller
  alive for hotplug interrupts.
- GPIO HPD and force-HPD modes: retain original logic, manage IRQ
  within bridge enable/disable callbacks.

Persistent power hold is only necessary for native HPD pin mode.
It is not required for force-HPD or GPIO HPD modes. Add helper
analogix_dp_require_pm_for_hpd_irq() to identify Rockchip native HPD
pin configurations and switch IRQ handling accordingly.

Signed-off-by: Damon Ding <[email protected]>

---

Change in v2:
- Split IRQ enable/disable logic, handle native HPD pin and
  GPIO/force-HPD modes separately to avoid unbalanced enable_irq()
  calls.(Sashiko)
---
 .../drm/bridge/analogix/analogix_dp_core.c    | 25 +++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 8d3d4a6e6ca2..18f300b49644 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -40,6 +40,12 @@
 
 static const bool verify_fast_training;
 
+static bool analogix_dp_require_pm_for_hpd_irq(struct analogix_dp_device *dp)
+{
+	return analogix_dp_is_rockchip(dp->plat_data->dev_type) && !dp->hpd_gpiod &&
+	       !dp->force_hpd;
+}
+
 static void analogix_dp_init_dp(struct analogix_dp_device *dp)
 {
 	analogix_dp_reset(dp);
@@ -1014,7 +1020,8 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp)
 		goto out_dp_init;
 	}
 
-	enable_irq(dp->irq);
+	if (!analogix_dp_require_pm_for_hpd_irq(dp))
+		enable_irq(dp->irq);
 	return 0;
 
 out_dp_init:
@@ -1156,7 +1163,8 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge)
 	if (dp->dpms_mode != DRM_MODE_DPMS_ON)
 		return;
 
-	disable_irq(dp->irq);
+	if (!analogix_dp_require_pm_for_hpd_irq(dp))
+		disable_irq(dp->irq);
 
 	analogix_dp_set_analog_power_down(dp, POWER_ALL, 1);
 
@@ -1504,6 +1512,14 @@ int analogix_dp_bind(struct analogix_dp_device *dp, struct drm_device *drm_dev)
 		goto err_unregister_aux;
 	}
 
+	if (analogix_dp_require_pm_for_hpd_irq(dp)) {
+		ret = pm_runtime_resume_and_get(dp->dev);
+		if (ret)
+			goto err_unregister_aux;
+
+		enable_irq(dp->irq);
+	}
+
 	return 0;
 
 err_unregister_aux:
@@ -1515,6 +1531,11 @@ EXPORT_SYMBOL_GPL(analogix_dp_bind);
 
 void analogix_dp_unbind(struct analogix_dp_device *dp)
 {
+	if (analogix_dp_require_pm_for_hpd_irq(dp)) {
+		disable_irq(dp->irq);
+		pm_runtime_put_sync(dp->dev);
+	}
+
 	drm_dp_aux_unregister(&dp->aux);
 }
 EXPORT_SYMBOL_GPL(analogix_dp_unbind);
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.