[PATCH RESEND 3/3] drm/verisilicon: stop to reuse atomic_disable for invisible planes
From: Icenowy Zheng
Date: Fri Oct 30 2026 - 09:36:01 EST
When a plane is configured to be invisible, the atomic_update
implementation currently just calls the atomic_disable function.
However these two functions behave differently when disabling planes:
atomic_update disables the plane specified in the NEW state, but
atomic_disable disables the plane specified in the OLD state, so this
shortcut may lead to NULL dereference if the old state doesn't have a
CRTC bound.
Fixes: dbf21777caa8 ("drm: verisilicon: add a driver for Verisilicon display controllers")
Fixes: 8c4ae2189125 ("drm: verisilicon: add support for cursor planes")
Signed-off-by: Icenowy Zheng <zhengxingda@xxxxxxxxxxx>
---
drivers/gpu/drm/verisilicon/vs_cursor_plane.c | 17 +++++++++++------
drivers/gpu/drm/verisilicon/vs_primary_plane.c | 15 ++++++++++-----
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/verisilicon/vs_cursor_plane.c b/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
index da456dced88aa..725921ac25d48 100644
--- a/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_cursor_plane.c
@@ -98,6 +98,15 @@ static void vs_cursor_plane_commit(struct vs_dc *dc, unsigned int output)
VSDC_CURSOR_CONFIG_IMG_UPDATE);
}
+static void vs_cursor_plane_disable(struct vs_dc *dc, unsigned int output)
+{
+ regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output),
+ VSDC_CURSOR_CONFIG_FMT_MASK,
+ VSDC_CURSOR_CONFIG_FMT_OFF);
+
+ vs_cursor_plane_commit(dc, output);
+}
+
static void vs_cursor_plane_atomic_enable(struct drm_plane *plane,
struct drm_atomic_commit *atomic_state)
{
@@ -125,11 +134,7 @@ static void vs_cursor_plane_atomic_disable(struct drm_plane *plane,
unsigned int output = vcrtc->id;
struct vs_dc *dc = vcrtc->dc;
- regmap_update_bits(dc->regs, VSDC_CURSOR_CONFIG(output),
- VSDC_CURSOR_CONFIG_FMT_MASK,
- VSDC_CURSOR_CONFIG_FMT_OFF);
-
- vs_cursor_plane_commit(dc, output);
+ vs_cursor_plane_disable(dc, output);
}
static void vs_cursor_plane_atomic_update(struct drm_plane *plane,
@@ -145,7 +150,7 @@ static void vs_cursor_plane_atomic_update(struct drm_plane *plane,
dma_addr_t dma_addr;
if (!state->visible) {
- vs_cursor_plane_atomic_disable(plane, atomic_state);
+ vs_cursor_plane_disable(dc, output);
return;
}
diff --git a/drivers/gpu/drm/verisilicon/vs_primary_plane.c b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
index d5563c3b825c3..594d56bf32410 100644
--- a/drivers/gpu/drm/verisilicon/vs_primary_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_primary_plane.c
@@ -59,6 +59,14 @@ static void vs_primary_plane_commit(struct vs_dc *dc, unsigned int output)
VSDC_FB_CONFIG_EX_COMMIT);
}
+static void vs_primary_plane_disable(struct vs_dc *dc, unsigned int output)
+{
+ regmap_clear_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
+ VSDC_FB_CONFIG_EX_FB_EN);
+
+ vs_primary_plane_commit(dc, output);
+}
+
static void vs_primary_plane_atomic_enable(struct drm_plane *plane,
struct drm_atomic_commit *atomic_state)
{
@@ -88,10 +96,7 @@ static void vs_primary_plane_atomic_disable(struct drm_plane *plane,
unsigned int output = vcrtc->id;
struct vs_dc *dc = vcrtc->dc;
- regmap_clear_bits(dc->regs, VSDC_FB_CONFIG_EX(output),
- VSDC_FB_CONFIG_EX_FB_EN);
-
- vs_primary_plane_commit(dc, output);
+ vs_primary_plane_disable(dc, output);
}
static void vs_primary_plane_atomic_update(struct drm_plane *plane,
@@ -108,7 +113,7 @@ static void vs_primary_plane_atomic_update(struct drm_plane *plane,
dma_addr_t dma_addr;
if (!state->visible) {
- vs_primary_plane_atomic_disable(plane, atomic_state);
+ vs_primary_plane_disable(dc, output);
return;
}
--
2.56.0