From nobody Sat Sep 26 18:55:10 2026 Received: from mail-106111.protonmail.ch (mail-106111.protonmail.ch [79.135.106.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 437A53F58FE for ; Mon, 31 Aug 2026 12:21:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=79.135.106.111 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788178908; cv=none; b=KSFKw2BwqBh3fphR9XyPcOCF5KLx1XPes1ljuFt6Sp5vsqC+k91AcnYHhk27NC9oN8h6gFYMuzlFOpZzvqWU60jWRoN6Sdu49Fh/GUaX0k+aJgs1Jp0uLhOfHDYmYzOSHdMVfoWMnv2efUUZqtcF+AWz0XfbK6IdL9Fd7RDq1Zc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788178908; c=relaxed/simple; bh=lxwvKIJMnuTH1RCtEzp5/BOHg+/mPbblzrT1/VXyMlU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=LTnaRTkpazDcvikP3wKoXAiaBcQV8GxeFcH3RUC/R4dHpUxoK2kC2SXLqqj8MDi/IqnlB8HeOCgZUYUZe8Ca8k5ylnpTV/oeiTWLe914IHDYGDx4rWVvpVMH11rAHx9xiozdf1o1rwGlqyZIUyoJD0Tf4IxD26Ipj3ZkwpUcE6g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=geanix.com; spf=pass smtp.mailfrom=geanix.com; dkim=pass (2048-bit key) header.d=geanix.com header.i=@geanix.com header.b=hMTWYzKN; arc=none smtp.client-ip=79.135.106.111 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=geanix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=geanix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=geanix.com header.i=@geanix.com header.b="hMTWYzKN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=geanix.com; s=protonmail; t=1788178904; x=1788438104; bh=8GEyTWJeK2D6cbmdD6iT6ihcCSdw5Azb1qii/ETTbTc=; h=From:Date:Subject:Message-Id:References:In-Reply-To:To:Cc:From:To: Cc:Date:Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector; b=hMTWYzKNBZKgEUYspi/g1i6xpgFABv5qnNqRy3+s5tSuoU2EoaJeyKHO6nDvI8zyN rScfiK+BT7aBJGKljXKZRNwOuOUDWm122TX3IR9HXDmfRh53FXc+0s+sdT1EUUKbt1 3uHpXFP8bXJ/RP+MFp3j7xMJxdj5FXVbuIxpov3qARx4uYCeydAvsKzx+YakSH65Ry f3X9XdR5l8dkU0vF8njAYD4EEhEZITwyDXYarO9DI2m2JpMPLBImYhnnUTrRSX7O+R HBBHbNvy0/h4/R5ecYwFWa/auqVpv4Musy4VYtipW7YpvuVABVQNfMePB5BI97732w M2gnoI/WL9LCw== X-Pm-Submission-Id: 4hYSlp1qB7z2SdHc From: Esben Haabendal Date: Mon, 31 Aug 2026 14:21:32 +0200 Subject: [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ti-sn65dsi83-fixes-v5-1-e712765d6c4f@geanix.com> References: <20260831-ti-sn65dsi83-fixes-v5-0-e712765d6c4f@geanix.com> In-Reply-To: <20260831-ti-sn65dsi83-fixes-v5-0-e712765d6c4f@geanix.com> To: Luca Ceresoli , Herve Codina , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Linus Walleij , Frieder Schrempf , Marek Vasut , Dmitry Baryshkov Cc: Esben Haabendal , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788178899; l=2442; i=esben@geanix.com; s=20240523; h=from:subject:message-id; bh=lxwvKIJMnuTH1RCtEzp5/BOHg+/mPbblzrT1/VXyMlU=; b=fWo47VZuQdQxlc0Vm10+LtBWnOTaCZ06OYMSxb70cIEvrG1Like4s7WeS68CcyKMA+CiyzXf1 7pUZl8xbK79CyFnQGCnbesoew9oLWME1cR7RHXvO8KcMcT3LoxjSxlx X-Developer-Key: i=esben@geanix.com; a=ed25519; pk=PbXoezm+CERhtgVeF/QAgXtEzSkDIahcWfC7RIXNdEk= The error handling of sn65dsi83_reset_pipe() in sn65dsi83_reset_work() has seen a couple of changes that seems to cause a bit of confusion. While sn65dsi83_reset_work() has implemented an early exit if sn65dsi83_reset_pipe() fails since it was added, when a commit from Maxime Ripard switched to use drm_bridge_helper_reset_crtc() [1] the sn65dsi83_reset_pipe() function would no longer return an error code, so the early exit was then a no-op, and even on sn65dsi83_reset_pipe() failure, enable_irq() has been called. When drm_bridge_enter()/drm_bridge_exit() resource protection was added, the drm_bridge_exit() incidentally was always called, which is the correct approach. But only because the early exit in sn65dsi83_reset_pipe() was never hit because sn65dsi83_reset_pipe() always returns 0. In order get back to a situation where enable_irq() is not called on sn65dsi83_reset_pipe() failure, which should help protect against irq storms, we need to reintroduce a non-zero return value from sn65dsi83_reset_pipe() on error, and fix sn65dsi83_reset_work() so that we always exit the DRM bridge critical section with drm_bridge_exit(). [1] commit e17fadff7ab9 ("drm/bridge: ti-sn65dsi83: Switch to drm_bridge_he= lper_reset_crtc") [2] commit d2e8d1bc840b ("drm/bridge: ti-sn65dsi83: protect device resource= s on unplug") Fixes: e17fadff7ab9 ("drm/bridge: ti-sn65dsi83: Switch to drm_bridge_helper= _reset_crtc") Cc: stable@vger.kernel.org Signed-off-by: Esben Haabendal Reviewed-by: Herve Codina Reviewed-by: Luca Ceresoli Tested-by: Luca Ceresoli --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge= /ti-sn65dsi83.c index 42b451432bbb..9f530cd05d2f 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -403,7 +403,7 @@ static int sn65dsi83_reset_pipe(struct sn65dsi83 *sn65d= si83) drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); =20 - return 0; + return err; } =20 static void sn65dsi83_reset_work(struct work_struct *ws) @@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct work_struct *= ws) ret =3D sn65dsi83_reset_pipe(ctx); if (ret) { dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret)); - return; + goto bridge_exit; } + if (ctx->irq) enable_irq(ctx->irq); =20 +bridge_exit: drm_bridge_exit(idx); } =20 --=20 2.55.0 From nobody Sat Sep 26 18:55:10 2026 Received: from mail-244108.protonmail.ch (mail-244108.protonmail.ch [109.224.244.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 579D0349B1C for ; Mon, 31 Aug 2026 12:21:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=109.224.244.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788178916; cv=none; b=G19d3fJFEBFQ/oj4P/ncphxr4Wo+ZWRfVqvGmQQCqXKk/07BikebtydShLy0AT+dcF6WFdXv+4K0v8Ufrn5phVM762YC5Ue/XIzv2ZCUsYy5j5VooVGxVbB6T+QMErNpbDc1kOES+pJh/hAxBaba50kOXnFT5V3169VV7rRKy9E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788178916; c=relaxed/simple; bh=riuvFlBJ34uwuG0g8BG6eW2XovO/sXh5l21IDdcUSD4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rO6URQmsIFfgaiLGac977G+eiNgCU9m7Baz2T4ZJbuAFrilZwcbzNb/8OCxg/EalIa9xlQ2HsGODWt+NvtSK9Z+0W/5W3Xt/VLCiKJ7MtM/4LyUZ5UTFlW8dAHRJ3Ov8ltT99hBwl8N5ecoeLhbeSzQKGuhyOnnwEyjNOF86twE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=geanix.com; spf=pass smtp.mailfrom=geanix.com; dkim=pass (2048-bit key) header.d=geanix.com header.i=@geanix.com header.b=yRLXBy2E; arc=none smtp.client-ip=109.224.244.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=geanix.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=geanix.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=geanix.com header.i=@geanix.com header.b="yRLXBy2E" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=geanix.com; s=protonmail; t=1788178906; x=1788438106; bh=WeFHlmiKxBHeot0vI4iTWVjsz4T6sENcTYNltgj3i4Y=; h=From:Date:Subject:Message-Id:References:In-Reply-To:To:Cc:From:To: Cc:Date:Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector; b=yRLXBy2EB1l0XdV1FzVbAmlfp4FR+vyly95xTtr4yPr6CCziwb8OPBR9zRWSMEzN7 cyhz3iVSy19HZd7yGAP2iw2wletUToPNAAYEmRm7LL189APNPMUp4OGnNFipChVhJb lD3t7J/m9YfUaeT0ri/K0siLP8OmKVm9xyCbOlSTHZ+vRD06EdzvHyZJwCtnJp+7X2 DUNBaL5tKIaAfmaKEyBOK0uu05B6iF6ymh3BTzXbwaoGq/6IvTrNauVQc6mHHcLaMf ufEfrITd4rYiheAJOLk1KJKdrp3/PE5rW3o6PZaujyxcyzqMBdm8AYscFo3nCAqLzs LfBNY9mT/Ej7w== X-Pm-Submission-Id: 4hYSlr38Vwz2ScPH From: Esben Haabendal Date: Mon, 31 Aug 2026 14:21:33 +0200 Subject: [PATCH v5 2/2] drm/bridge: ti-sn65dsi83: Support LVDS Channel B on SN65DSI84 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-ti-sn65dsi83-fixes-v5-2-e712765d6c4f@geanix.com> References: <20260831-ti-sn65dsi83-fixes-v5-0-e712765d6c4f@geanix.com> In-Reply-To: <20260831-ti-sn65dsi83-fixes-v5-0-e712765d6c4f@geanix.com> To: Luca Ceresoli , Herve Codina , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Linus Walleij , Frieder Schrempf , Marek Vasut , Dmitry Baryshkov Cc: Esben Haabendal , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1788178899; l=3907; i=esben@geanix.com; s=20240523; h=from:subject:message-id; bh=riuvFlBJ34uwuG0g8BG6eW2XovO/sXh5l21IDdcUSD4=; b=znrpJnDcwSl5Akbw/6yaWsOT4OJmg/GliUJu8dOtXPSqETMCeBDT1uqUWe+poKV8GftqZEAC5 6Crhz1dxtOpASmLu5JHA+Zsf5iHg1M0VXsPGyOLH1x0wGxu4KiQVrn7 X-Developer-Key: i=esben@geanix.com; a=ed25519; pk=PbXoezm+CERhtgVeF/QAgXtEzSkDIahcWfC7RIXNdEk= Add support for using SN65DSI84 in single-link mode with output to LVDS Channel B. Reviewed-by: Luca Ceresoli Tested-by: Luca Ceresoli Signed-off-by: Esben Haabendal --- drivers/gpu/drm/bridge/ti-sn65dsi83.c | 34 +++++++++++++++++++++++--------= --- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge= /ti-sn65dsi83.c index 9f530cd05d2f..fcbc427947b6 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -11,6 +11,8 @@ * =3D 1x Single-link DSI ~ 2x Single-link or 1x Dual-link LVDS * - Supported * - Dual-link LVDS mode tested + * - Single-link to LVDS Channel A tested + * - Single-link to LVDS Channel B tested * - 2x Single-link LVDS mode unsupported * (should be easy to add by someone who has the HW) * - SN65DSI85 @@ -162,7 +164,7 @@ struct sn65dsi83 { struct gpio_desc *enable_gpio; struct regulator *vcc; bool lvds_dual_link; - bool lvds_dual_link_even_odd_swap; + bool lvds_channel_swap; int lvds_vod_swing_conf[2]; int lvds_term_conf[2]; int irq; @@ -644,7 +646,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_brid= ge *bridge, REG_LVDS_VCOM_CHA_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_A]) | REG_LVDS_VCOM_CHB_LVDS_VOD_SWING(ctx->lvds_vod_swing_conf[CHANNEL_B])); regmap_write(ctx->regmap, REG_LVDS_LANE, - (ctx->lvds_dual_link_even_odd_swap ? + (ctx->lvds_channel_swap ? REG_LVDS_LANE_EVEN_ODD_SWAP : 0) | (ctx->lvds_term_conf[CHANNEL_A] ? REG_LVDS_LANE_CHA_LVDS_TERM : 0) | @@ -895,6 +897,7 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, en= um sn65dsi83_model model) { struct drm_bridge *panel_bridge; struct device *dev =3D ctx->dev; + u32 output_port =3D 2; int ret; =20 ret =3D sn65dsi83_parse_lvds_endpoint(ctx, CHANNEL_A); @@ -906,29 +909,38 @@ static int sn65dsi83_parse_dt(struct sn65dsi83 *ctx, = enum sn65dsi83_model model) return ret; =20 ctx->lvds_dual_link =3D false; - ctx->lvds_dual_link_even_odd_swap =3D false; + ctx->lvds_channel_swap =3D false; if (model !=3D MODEL_SN65DSI83) { - struct device_node *port2, *port3; + struct device_node *port0, *port1, *port2, *port3; int dual_link; =20 + port0 =3D of_graph_get_port_by_id(dev->of_node, 0); + port1 =3D of_graph_get_port_by_id(dev->of_node, 1); port2 =3D of_graph_get_port_by_id(dev->of_node, 2); port3 =3D of_graph_get_port_by_id(dev->of_node, 3); dual_link =3D drm_of_lvds_get_dual_link_pixel_order(port2, port3); - of_node_put(port2); - of_node_put(port3); =20 if (dual_link =3D=3D DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) { - ctx->lvds_dual_link =3D true; /* Odd pixels to LVDS Channel A, even pixels to B */ - ctx->lvds_dual_link_even_odd_swap =3D false; - } else if (dual_link =3D=3D DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) { ctx->lvds_dual_link =3D true; + } else if (dual_link =3D=3D DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) { /* Even pixels to LVDS Channel A, odd pixels to B */ - ctx->lvds_dual_link_even_odd_swap =3D true; + ctx->lvds_dual_link =3D true; + ctx->lvds_channel_swap =3D true; + } else if (port0 && !port1 && port2 && !port3) { + /* DSI Channel A to LVDS Channel A */ + } else if (port0 && !port1 && !port2 && port3) { + /* DSI Channel A to LVDS Channel B */ + ctx->lvds_channel_swap =3D true; + output_port =3D 3; } + of_node_put(port0); + of_node_put(port1); + of_node_put(port2); + of_node_put(port3); } =20 - panel_bridge =3D devm_drm_of_get_bridge(dev, dev->of_node, 2, 0); + panel_bridge =3D devm_drm_of_get_bridge(dev, dev->of_node, output_port, 0= ); if (IS_ERR(panel_bridge)) return dev_err_probe(dev, PTR_ERR(panel_bridge), "Failed to get panel br= idge\n"); =20 --=20 2.55.0