[PATCH 2/4] drm/panel: kingdisplay-kd097d04: Use mipi_dsi_*_multi(); fix minor bugs

From: Akash Sukhavasi

Date: Tue Oct 13 2026 - 00:37:03 EST


The mipi_dsi_dcs_*() and mipi_dsi_generic_write() functions used by
this driver are deprecated in favour of their _multi() counterparts,
as noted in Documentation/gpu/todo.rst. The _multi() variants record
the first error in a context structure and skip subsequent calls once
an error is set, removing the need to check the return value after
each command. They also log failures internally, making the per-call
dev_err() calls redundant.

Convert prepare(), disable(), and unprepare() to use the _multi()
equivalents.

In prepare(), use mipi_dsi_msleep() and mipi_dsi_usleep_range() instead
of plain msleep()/usleep_range() for delays between DSI commands, so
they are skipped on prior error since the function will clean up via the
existing poweroff label anyway.

In unprepare(), keep plain msleep() since the hardware delay must execute
regardless of any prior DSI error. This also fixes a bug where a failure
in enter_sleep_mode would return early, skipping the T15 delay, GPIO
deassertion, and regulator disable, leaving the panel stuck in a
prepared state. Because drm_panel_unprepare() does not clear
panel->prepared when the callback returns an error, drm_panel_prepare()
would return early on the next call, leaving the panel unable to be
re-initialised.

For the same reason, stop returning the regulator_disable() error from
unprepare(). Returning it would leave the panel in the same stuck state.

Signed-off-by: Akash Sukhavasi <akash.sukhavasi@xxxxxxxxx>
---
Compile tested only, no hardware available. checkpatch and a W=1
build are clean.
---
drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c | 53 ++++++++--------------
1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
index 893af9b16756..bc25ce1ce4a7 100644
--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
+++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c
@@ -180,11 +180,10 @@ struct kingdisplay_panel *to_kingdisplay_panel(struct drm_panel *panel)
static int kingdisplay_panel_disable(struct drm_panel *panel)
{
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
- int err;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = kingdisplay->link };

- err = mipi_dsi_dcs_set_display_off(kingdisplay->link);
- if (err < 0)
- dev_err(panel->dev, "failed to set display off: %d\n", err);
+ /* Set display off; error does not prevent disable */
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);

return 0;
}
@@ -192,22 +191,16 @@ static int kingdisplay_panel_disable(struct drm_panel *panel)
static int kingdisplay_panel_unprepare(struct drm_panel *panel)
{
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
- int err;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = kingdisplay->link };

- err = mipi_dsi_dcs_enter_sleep_mode(kingdisplay->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
- return err;
- }
+ /* Enter sleep mode; error does not prevent power-off */
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);

/* T15: 120ms */
msleep(120);

gpiod_set_value_cansleep(kingdisplay->enable_gpio, 0);
-
- err = regulator_disable(kingdisplay->supply);
- if (err < 0)
- return err;
+ regulator_disable(kingdisplay->supply);

return 0;
}
@@ -215,6 +208,7 @@ static int kingdisplay_panel_unprepare(struct drm_panel *panel)
static int kingdisplay_panel_prepare(struct drm_panel *panel)
{
struct kingdisplay_panel *kingdisplay = to_kingdisplay_panel(panel);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = kingdisplay->link };
int err, regulator_err;
unsigned int i;

@@ -232,33 +226,22 @@ static int kingdisplay_panel_prepare(struct drm_panel *panel)
/* T4: 15ms */
usleep_range(15000, 16000);

- for (i = 0; i < ARRAY_SIZE(init_code); i++) {
- err = mipi_dsi_generic_write(kingdisplay->link, &init_code[i],
- sizeof(struct kingdisplay_panel_cmd));
- if (err < 0) {
- dev_err(panel->dev, "failed write init cmds: %d\n", err);
- goto poweroff;
- }
- }
-
- err = mipi_dsi_dcs_exit_sleep_mode(kingdisplay->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
- goto poweroff;
- }
+ for (i = 0; i < ARRAY_SIZE(init_code); i++)
+ mipi_dsi_generic_write_multi(&dsi_ctx, &init_code[i],
+ sizeof(struct kingdisplay_panel_cmd));

+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
/* T6: 120ms */
- msleep(120);
+ mipi_dsi_msleep(&dsi_ctx, 120);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ /* T7: 10ms */
+ mipi_dsi_usleep_range(&dsi_ctx, 10000, 11000);

- err = mipi_dsi_dcs_set_display_on(kingdisplay->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to set display on: %d\n", err);
+ if (dsi_ctx.accum_err) {
+ err = dsi_ctx.accum_err;
goto poweroff;
}

- /* T7: 10ms */
- usleep_range(10000, 11000);
-
return 0;

poweroff:

--
2.56.0