* [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-08-31 12:21 [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes Esben Haabendal
@ 2026-08-31 12:21 ` Esben Haabendal
2026-08-31 12:31 ` sashiko-bot
` (3 more replies)
2026-08-31 12:21 ` [PATCH v5 2/2] drm/bridge: ti-sn65dsi83: Support LVDS Channel B on SN65DSI84 Esben Haabendal
2026-09-09 15:18 ` (subset) [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes Luca Ceresoli
2 siblings, 4 replies; 8+ messages in thread
From: Esben Haabendal @ 2026-08-31 12:21 UTC (permalink / raw)
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, linux-kernel, stable
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_helper_reset_crtc")
[2] commit d2e8d1bc840b ("drm/bridge: ti-sn65dsi83: protect device resources 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 <esben@geanix.com>
---
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 *sn65dsi83)
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
- return 0;
+ return err;
}
static void sn65dsi83_reset_work(struct work_struct *ws)
@@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct work_struct *ws)
ret = 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);
+bridge_exit:
drm_bridge_exit(idx);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
@ 2026-08-31 12:31 ` sashiko-bot
2026-08-31 12:59 ` Herve Codina
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-08-31 12:31 UTC (permalink / raw)
To: Esben Haabendal; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing `cancel_work_sync` for `reset_work` leads to a use-after-free on driver unbind.
--
commit 47920da4c643294656a651a954618ec33114a7d9
Author: Esben Haabendal <esben@geanix.com>
drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
The commit reintroduces a non-zero return value from sn65dsi83_reset_pipe()
on error to prevent erroneous IRQ re-enabling during failures. It also
updates sn65dsi83_reset_work() to properly exit the DRM bridge critical
section by always calling drm_bridge_exit().
> diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> index 42b451432bbb6..9f530cd05d2f3 100644
> --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
> +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
[ ... ]
> @@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct work_struct *ws)
> ret = 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);
>
> +bridge_exit:
> drm_bridge_exit(idx);
> }
[Severity: High]
This isn't a bug introduced by this patch, but I noticed a potential
use-after-free related to the reset_work structure that is being modified here.
During driver unbind (e.g., via sysfs), sn65dsi83_remove() unplugs the bridge
but does not explicitly call cancel_work_sync(&ctx->reset_work). After
sn65dsi83_remove() returns, devres automatically frees the IRQ and the ctx
structure.
If an interrupt had previously scheduled the work, the work item might remain
in the queue and eventually execute sn65dsi83_reset_work(), which will attempt
to access the freed ctx pointer (e.g., when calling
drm_bridge_enter(&ctx->bridge, &idx)).
Should sn65dsi83_remove() be updated to include a call to
cancel_work_sync(&ctx->reset_work) to ensure the work is fully cancelled
before devres tears down the allocated memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260831-ti-sn65dsi83-fixes-v5-0-e712765d6c4f@geanix.com?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
2026-08-31 12:31 ` sashiko-bot
@ 2026-08-31 12:59 ` Herve Codina
2026-09-01 9:48 ` Luca Ceresoli
2026-09-01 12:05 ` Luca Ceresoli
3 siblings, 0 replies; 8+ messages in thread
From: Herve Codina @ 2026-08-31 12:59 UTC (permalink / raw)
To: Esben Haabendal
Cc: Luca Ceresoli, 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, dri-devel, linux-kernel, stable
Hi Esben,
On Mon, 31 Aug 2026 14:21:32 +0200
Esben Haabendal <esben@geanix.com> wrote:
> 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_helper_reset_crtc")
> [2] commit d2e8d1bc840b ("drm/bridge: ti-sn65dsi83: protect device resources 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 <esben@geanix.com>
> ---
> drivers/gpu/drm/bridge/ti-sn65dsi83.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
LGTM.
Reviewed-by: Herve Codina <herve.codina@bootlin.com>
Best regards,
Hervé
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
2026-08-31 12:31 ` sashiko-bot
2026-08-31 12:59 ` Herve Codina
@ 2026-09-01 9:48 ` Luca Ceresoli
2026-09-01 12:05 ` Luca Ceresoli
3 siblings, 0 replies; 8+ messages in thread
From: Luca Ceresoli @ 2026-09-01 9:48 UTC (permalink / raw)
To: Esben Haabendal
Cc: 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, dri-devel, linux-kernel, stable
On Mon, 31 Aug 2026 14:21:32 +0200, Esben Haabendal <esben@geanix.com> wrote:
> 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.
>
> [...]
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
` (2 preceding siblings ...)
2026-09-01 9:48 ` Luca Ceresoli
@ 2026-09-01 12:05 ` Luca Ceresoli
3 siblings, 0 replies; 8+ messages in thread
From: Luca Ceresoli @ 2026-09-01 12:05 UTC (permalink / raw)
To: Esben Haabendal, 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: dri-devel, linux-kernel, stable
Hi Esben,
On Mon Aug 31, 2026 at 2:21 PM CEST, Esben Haabendal wrote:
> 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_helper_reset_crtc")
> [2] commit d2e8d1bc840b ("drm/bridge: ti-sn65dsi83: protect device resources 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 <esben@geanix.com>
Thanks for having sorted out this complicated situation!
Now all patches are approved, so I'll apply them next week if all goes
well. Being one fix and one feature thay'll have to go to different
branches: drm-misc-fixes and drm-misc-next respectively. As I see it, the
two patches are orthogonal, so that shouldn't be a problem.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v5 2/2] drm/bridge: ti-sn65dsi83: Support LVDS Channel B on SN65DSI84
2026-08-31 12:21 [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes Esben Haabendal
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
@ 2026-08-31 12:21 ` Esben Haabendal
2026-09-09 15:18 ` (subset) [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes Luca Ceresoli
2 siblings, 0 replies; 8+ messages in thread
From: Esben Haabendal @ 2026-08-31 12:21 UTC (permalink / raw)
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, linux-kernel
Add support for using SN65DSI84 in single-link mode with output to LVDS
Channel B.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Esben Haabendal <esben@geanix.com>
---
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 @@
* = 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_bridge *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, enum sn65dsi83_model model)
{
struct drm_bridge *panel_bridge;
struct device *dev = ctx->dev;
+ u32 output_port = 2;
int ret;
ret = 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;
ctx->lvds_dual_link = false;
- ctx->lvds_dual_link_even_odd_swap = false;
+ ctx->lvds_channel_swap = false;
if (model != MODEL_SN65DSI83) {
- struct device_node *port2, *port3;
+ struct device_node *port0, *port1, *port2, *port3;
int dual_link;
+ port0 = of_graph_get_port_by_id(dev->of_node, 0);
+ port1 = of_graph_get_port_by_id(dev->of_node, 1);
port2 = of_graph_get_port_by_id(dev->of_node, 2);
port3 = of_graph_get_port_by_id(dev->of_node, 3);
dual_link = drm_of_lvds_get_dual_link_pixel_order(port2, port3);
- of_node_put(port2);
- of_node_put(port3);
if (dual_link == DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) {
- ctx->lvds_dual_link = true;
/* Odd pixels to LVDS Channel A, even pixels to B */
- ctx->lvds_dual_link_even_odd_swap = false;
- } else if (dual_link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {
ctx->lvds_dual_link = true;
+ } else if (dual_link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) {
/* Even pixels to LVDS Channel A, odd pixels to B */
- ctx->lvds_dual_link_even_odd_swap = true;
+ ctx->lvds_dual_link = true;
+ ctx->lvds_channel_swap = 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 = true;
+ output_port = 3;
}
+ of_node_put(port0);
+ of_node_put(port1);
+ of_node_put(port2);
+ of_node_put(port3);
}
- panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 2, 0);
+ panel_bridge = 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 bridge\n");
--
2.55.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: (subset) [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes
2026-08-31 12:21 [PATCH v5 0/2] drm/bridge: ti-sn65dsi83: Various fixes Esben Haabendal
2026-08-31 12:21 ` [PATCH v5 1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Esben Haabendal
2026-08-31 12:21 ` [PATCH v5 2/2] drm/bridge: ti-sn65dsi83: Support LVDS Channel B on SN65DSI84 Esben Haabendal
@ 2026-09-09 15:18 ` Luca Ceresoli
2 siblings, 0 replies; 8+ messages in thread
From: Luca Ceresoli @ 2026-09-09 15:18 UTC (permalink / raw)
To: 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, Esben Haabendal
Cc: dri-devel, linux-kernel, stable
On Mon, 31 Aug 2026 14:21:31 +0200, Esben Haabendal wrote:
> This small series adds support for using SN65DSI84 in single-link mode with
> output to LVDS channel B, and provides a fix for an error-handling
> regression in sn65dsi83_reset_pipe()/sn65dsi83_reset_work().
Applied, thanks!
[1/2] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
commit: 4600b4d1a9ee730d03ddac5ce409cd2730ce8c0c
Best regards,
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 8+ messages in thread