lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251219104659.114032-1-biju.das.jz@bp.renesas.com>
Date: Fri, 19 Dec 2025 10:46:53 +0000
From: Biju <biju.das.au@...il.com>
To: Andrzej Hajda <andrzej.hajda@...el.com>,
	Neil Armstrong <neil.armstrong@...aro.org>,
	Robert Foss <rfoss@...nel.org>,
	Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
	Maxime Ripard <mripard@...nel.org>,
	Thomas Zimmermann <tzimmermann@...e.de>,
	David Airlie <airlied@...il.com>,
	Simona Vetter <simona@...ll.ch>
Cc: Biju Das <biju.das.jz@...renesas.com>,
	Laurent Pinchart <Laurent.pinchart@...asonboard.com>,
	Jonas Karlman <jonas@...boo.se>,
	Jernej Skrabec <jernej.skrabec@...il.com>,
	Dmitry Baryshkov <dmitry.baryshkov@....qualcomm.com>,
	Tommaso Merciai <tommaso.merciai.xr@...renesas.com>,
	Andy Yan <andy.yan@...k-chips.com>,
	Douglas Anderson <dianders@...omium.org>,
	Luca Ceresoli <luca.ceresoli@...tlin.com>,
	Jesse Van Gavere <jesseevg@...il.com>,
	dri-devel@...ts.freedesktop.org,
	linux-kernel@...r.kernel.org,
	Geert Uytterhoeven <geert+renesas@...der.be>,
	Prabhakar Mahadev Lad <prabhakar.mahadev-lad.rj@...renesas.com>,
	Biju Das <biju.das.au@...il.com>,
	linux-renesas-soc@...r.kernel.org
Subject: [PATCH] drm/bridge: adv7511: Clear HPD IRQ before powering on device during resume()

From: Biju Das <biju.das.jz@...renesas.com>

On RZ/G3E SMARC EVK using PSCI, s2ram powers down the SoC. Testing ADV7535
IRQ configured as edge-triggered interrupt on RZ/G3E SMARC EVK shows that
it is missing HPD IRQ during system resume, as the status change occurs
before the IRQ/pincontrol resume. Once the status bit is set, there won't
be any further IRQ unless the status bit is cleared.

Clear any pending HPD IRQs before powering on the ADV7535 device to
deliver HPD interrupts after resume().

Signed-off-by: Biju Das <biju.das.jz@...renesas.com>
---
 drivers/gpu/drm/bridge/adv7511/adv7511.h     |  1 +
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 32 ++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 8be7266fd4f4..03aa23836ca4 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -393,6 +393,7 @@ struct adv7511 {
 	bool cec_enabled_adap;
 	struct clk *cec_clk;
 	u32 cec_clk_freq;
+	bool suspended;
 };
 
 static inline struct adv7511 *bridge_to_adv7511(struct drm_bridge *bridge)
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index b9be86541307..8d9467187d7c 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -790,6 +790,25 @@ static void adv7511_bridge_atomic_enable(struct drm_bridge *bridge,
 	struct drm_connector_state *conn_state;
 	struct drm_crtc_state *crtc_state;
 
+	if (adv->i2c_main->irq && adv->suspended) {
+		unsigned int irq;
+
+		/*
+		 * If ADV7511 IRQ is configured as edge triggered interrupt, it
+		 * will miss the IRQ during system resume as the status change
+		 * occurs before IRQ/pincontrol resume. Once the status bit is
+		 * set there won't be any further IRQ unless the status bit is
+		 * cleared. So, clear the IRQ status bit for further delivery
+		 * of HPD IRQ.
+		 */
+		regmap_read(adv->regmap, ADV7511_REG_INT(0), &irq);
+		if (irq & ADV7511_INT0_HPD)
+			regmap_write(adv->regmap, ADV7511_REG_INT(0),
+				     ADV7511_INT0_HPD);
+
+		adv->suspended = false;
+	}
+
 	adv7511_power_on(adv);
 
 	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
@@ -1407,6 +1426,16 @@ static void adv7511_remove(struct i2c_client *i2c)
 	i2c_unregister_device(adv7511->i2c_edid);
 }
 
+static int adv7511_suspend(struct device *dev)
+{
+	struct i2c_client *i2c = to_i2c_client(dev);
+	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
+
+	adv7511->suspended = true;
+
+	return 0;
+}
+
 static const struct adv7511_chip_info adv7511_chip_info = {
 	.type = ADV7511,
 	.name = "ADV7511",
@@ -1439,6 +1468,8 @@ static const struct adv7511_chip_info adv7535_chip_info = {
 	.hpd_override_enable = true,
 };
 
+static DEFINE_SIMPLE_DEV_PM_OPS(adv7511_pm_ops, adv7511_suspend, NULL);
+
 static const struct i2c_device_id adv7511_i2c_ids[] = {
 	{ "adv7511", (kernel_ulong_t)&adv7511_chip_info },
 	{ "adv7511w", (kernel_ulong_t)&adv7511_chip_info },
@@ -1467,6 +1498,7 @@ static struct i2c_driver adv7511_driver = {
 	.driver = {
 		.name = "adv7511",
 		.of_match_table = adv7511_of_ids,
+		.pm = pm_sleep_ptr(&adv7511_pm_ops),
 	},
 	.id_table = adv7511_i2c_ids,
 	.probe = adv7511_probe,
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ