From nobody Tue Apr 7 13:47:49 2026 Received: from smtp.forwardemail.net (smtp.forwardemail.net [121.127.44.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CFB15359A7E for ; Fri, 3 Apr 2026 18:54:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=121.127.44.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775242451; cv=none; b=Hy2UaOEONkt1tTj8Q9Y+MDP5V2VthvrgF3IQ09vstB29UpMMUUNfJFDpImgo/MysaPSzg+VfrkS+ZBRduzTgTpVWM2KP1UFa6RO+9Wn/YJtIAxhsuJKdB8bgWmMfquqXjl0+p9W4Iwn6YS9pP7LwtlPTvzwqzRY3Q/YoOSTP3DY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775242451; c=relaxed/simple; bh=P97axD9T8EvVwHANpZQ8eeExQuXyeNYcEjJlTgQQvU0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WOX+RM1s3PZNhGjRA9NU54+KFwfdv8f0xs8dvRpu6hJh+/ZcDOTUbZ5l+p0KMtfVCVrsscBGvLE2C/5NjsApc0YjXc041eP7UCr2ESMu6AjD2DUHbuPYnKaQg6B7onsKOp+uwlTeA+5Zho6AR0+SEvqPR5D6hZ+WcJCjFh6GevQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=kwiboo.se; spf=pass smtp.mailfrom=fe-bounces.kwiboo.se; dkim=pass (2048-bit key) header.d=kwiboo.se header.i=@kwiboo.se header.b=mgwtAkxO; arc=none smtp.client-ip=121.127.44.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=kwiboo.se Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fe-bounces.kwiboo.se Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kwiboo.se header.i=@kwiboo.se header.b="mgwtAkxO" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kwiboo.se; h=Content-Transfer-Encoding: MIME-Version: References: In-Reply-To: Message-ID: Date: Subject: Cc: To: From; q=dns/txt; s=fe-e1b5cab7be; t=1775242449; bh=cb7kV5xrgzBNF02Z/hIuS/zVAc/l0KXvVzEjt546s3c=; b=mgwtAkxOsjdrCqfLMpCdJsKS7wQNu0y2MpkwLpn5/XAAnytMZO9J+RIX4yQJeKPLn5IQ61C4d SqEipb/x3sPfUEuhEOkd66GlhWpRRd/aGatB4l53F52MgLkWpvvppqEO4h/kwzR6zwnh27iX+6j WA8gdNtr3Dlrjdp6dG0H2AlDiTpUVzMgVglVbAf3Hidc0CmA9MHBeo1y/jf+gCWru90xfMkvlDt T5MLL8US9OKe0mNbRQlhqrEnAEpaIGYcteyXBDyogVDJX0kMKDJ26QMRBEp3YKObGTkPOdLSEJp WW9sn/BMpnWVQ0omVdD8gTTe7Rm7/n2kfX/TPAuH6v/Q== X-Forward-Email-ID: 69d00ccedc98192b40b893e1 X-Forward-Email-Sender: rfc822; jonas@kwiboo.se, smtp.forwardemail.net, 121.127.44.66 X-Forward-Email-Version: 2.6.68 X-Forward-Email-Website: https://forwardemail.net X-Complaints-To: abuse@forwardemail.net X-Report-Abuse: abuse@forwardemail.net X-Report-Abuse-To: abuse@forwardemail.net From: Jonas Karlman To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: Christian Hewitt , Diederik de Haas , dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 09/13] drm: bridge: dw_hdmi: Use delayed_work to debounce hotplug event Date: Fri, 3 Apr 2026 18:52:55 +0000 Message-ID: <20260403185303.80748-10-jonas@kwiboo.se> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403185303.80748-1-jonas@kwiboo.se> References: <20260403185303.80748-1-jonas@kwiboo.se> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" HDMI Specification Version 1.4b chapter 8.5 mentions: An HDMI Sink shall not assert high voltage level on its Hot Plug Detect pin when the E-EDID is not available for reading. A Source may use a high voltage level Hot Plug Detect signal to initiate the reading of E-EDID data. An HDMI Sink shall indicate any change to the contents of the E-EDID by driving a low voltage level pulse on the Hot Plug Detect pin. This pulse shall be at least 100 msec. Use a work queue to debounce reacting on HPD events to better handle a HPD low voltage level pulse when a sink changes the EDID. The 1100 msec hotplug debounce timeout was arbitrarily picked to match other drivers using same const, and testing using a Raspberry Pi Monitor seem to use a 200-300 msec pulse when going from standby to power on state. Signed-off-by: Jonas Karlman --- v3: New patch --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 24 +++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/br= idge/synopsys/dw-hdmi.c index f3f8144ae98e..4d079b689b3b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c @@ -51,6 +51,8 @@ =20 #define HDMI14_MAX_TMDSCLK 340000000 =20 +#define HOTPLUG_DEBOUNCE_MS 1100 + static const u16 csc_coeff_default[3][4] =3D { { 0x2000, 0x0000, 0x0000, 0x0000 }, { 0x0000, 0x2000, 0x0000, 0x0000 }, @@ -192,6 +194,7 @@ struct dw_hdmi { hdmi_codec_plugged_cb plugged_cb; struct device *codec_dev; enum drm_connector_status last_connector_result; + struct delayed_work hpd_work; }; =20 const struct dw_hdmi_plat_data *dw_hdmi_to_plat_data(struct dw_hdmi *hdmi) @@ -2528,6 +2531,7 @@ static void dw_hdmi_connector_force(struct drm_connec= tor *connector) =20 mutex_lock(&hdmi->mutex); hdmi->force =3D connector->force; + hdmi->last_connector_result =3D connector->status; dw_hdmi_update_phy_mask(hdmi); mutex_unlock(&hdmi->mutex); } @@ -3046,6 +3050,16 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bo= ol hpd, bool rx_sense) } EXPORT_SYMBOL_GPL(dw_hdmi_setup_rx_sense); =20 +static void dw_hdmi_hpd_work(struct work_struct *work) +{ + struct dw_hdmi *hdmi =3D container_of(work, struct dw_hdmi, hpd_work.work= ); + + if (hdmi->bridge.dev) { + drm_helper_hpd_irq_event(hdmi->bridge.dev); + drm_bridge_hpd_notify(&hdmi->bridge, hdmi->last_connector_result); + } +} + static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) { struct dw_hdmi *hdmi =3D dev_id; @@ -3097,10 +3111,8 @@ static irqreturn_t dw_hdmi_irq(int irq, void *dev_id) status =3D=3D connector_status_connected ? "plugin" : "plugout"); =20 - if (hdmi->bridge.dev) { - drm_helper_hpd_irq_event(hdmi->bridge.dev); - drm_bridge_hpd_notify(&hdmi->bridge, status); - } + mod_delayed_work(system_percpu_wq, &hdmi->hpd_work, + msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS)); } =20 hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); @@ -3420,6 +3432,8 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device = *pdev, goto err_res; } =20 + INIT_DELAYED_WORK(&hdmi->hpd_work, dw_hdmi_hpd_work); + ret =3D devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq, dw_hdmi_irq, IRQF_SHARED, dev_name(dev), hdmi); @@ -3552,6 +3566,8 @@ EXPORT_SYMBOL_GPL(dw_hdmi_probe); =20 void dw_hdmi_remove(struct dw_hdmi *hdmi) { + disable_delayed_work_sync(&hdmi->hpd_work); + drm_bridge_remove(&hdmi->bridge); =20 if (hdmi->audio && !IS_ERR(hdmi->audio)) --=20 2.53.0