[PATCH v3] drm/panel: tdo-tl070wsh30: Use mipi_dsi_*_multi(); fix minor bugs

From: Akash Sukhavasi

Date: Thu Jul 30 2026 - 20:15:37 EST


The mipi_dsi_dcs_*() functions used by this driver are deprecated in
favor of their _multi() counterparts, as noted in
Documentation/gpu/todo.rst. The _multi() variants record the first
error in a context structure and skip every later call once an error
is set, so the return value no longer has to be checked after each
command. They also log their own failures, which makes the per-call
dev_err() calls redundant.

Convert prepare() and unprepare(). prepare() uses mipi_dsi_msleep()
for the delays between DSI commands. unprepare() uses plain
usleep_range() so the delays run unconditionally after the
accumulated error is cleared. The delays in the GPIO reset sequence
stay as plain msleep() and usleep_range(), since they run before any
DSI transaction.

unprepare() now disables the regulator unconditionally and returns 0.
Previously a failure of set_display_off() was logged and the sequence
continued, while a failure of enter_sleep_mode() returned early,
leaving the regulator enabled and the panel unable to be brought back
up, since drm_panel_unprepare() skips panel->prepared = false on
error. The accumulated error from set_display_off() is cleared so
that the delay and enter_sleep_mode() are still attempted, preserving
the original fall-through behavior. Both drm_panel_prepare() and
drm_panel_unprepare() return void, so the error was never propagated
to a caller in any case.

Signed-off-by: Akash Sukhavasi <akash.sukhavasi@xxxxxxxxx>
---
Changes in v3:
- Update subject line to reflect the minor bugfixes, per Doug's review.
- Pack blank lines in both functions per Doug's review.
- Preserve the original fall-through behavior in unprepare(): clear
accum_err after set_display_off() so the delay and enter_sleep_mode()
are still attempted even if display off fails.
- Link to v2: https://lore.kernel.org/r/20260727-mipi-dsi-tl070wsh30-multi-v2-1-f47b937631d3@xxxxxxxxx

Compile tested only, no hardware available. checkpatch and a W=1 build
are clean.

Changes in v2:
- unprepare() disables the regulator unconditionally and returns 0,
per Sashiko's review on v1. Returning an error left panel->prepared
set, so the panel could not be prepared again.
- Link to v1: https://lore.kernel.org/r/20260725-mipi-dsi-tl070wsh30-multi-v1-1-69160b83982e@xxxxxxxxx
---
drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c | 40 +++++++++-------------------
1 file changed, 12 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
index 13cfe252a838..fa961abdd2d7 100644
--- a/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
+++ b/drivers/gpu/drm/panel/panel-tdo-tl070wsh30.c
@@ -35,6 +35,7 @@ struct tdo_tl070wsh30_panel *to_tdo_tl070wsh30_panel(struct drm_panel *panel)
static int tdo_tl070wsh30_panel_prepare(struct drm_panel *panel)
{
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = to_tdo_tl070wsh30_panel(panel);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = tdo_tl070wsh30->link };
int err;

err = regulator_enable(tdo_tl070wsh30->supply);
@@ -51,44 +52,27 @@ static int tdo_tl070wsh30_panel_prepare(struct drm_panel *panel)

msleep(200);

- err = mipi_dsi_dcs_exit_sleep_mode(tdo_tl070wsh30->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
- regulator_disable(tdo_tl070wsh30->supply);
- return err;
- }
-
- msleep(200);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 200);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 20);

- err = mipi_dsi_dcs_set_display_on(tdo_tl070wsh30->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to set display on: %d\n", err);
+ if (dsi_ctx.accum_err)
regulator_disable(tdo_tl070wsh30->supply);
- return err;
- }
-
- msleep(20);

- return 0;
+ return dsi_ctx.accum_err;
}

static int tdo_tl070wsh30_panel_unprepare(struct drm_panel *panel)
{
struct tdo_tl070wsh30_panel *tdo_tl070wsh30 = to_tdo_tl070wsh30_panel(panel);
- int err;
-
- err = mipi_dsi_dcs_set_display_off(tdo_tl070wsh30->link);
- if (err < 0)
- dev_err(panel->dev, "failed to set display off: %d\n", err);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = tdo_tl070wsh30->link };

+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+ /* Reset error to continue power-down sequence even if display off failed */
+ dsi_ctx.accum_err = 0;
usleep_range(10000, 11000);
-
- err = mipi_dsi_dcs_enter_sleep_mode(tdo_tl070wsh30->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
- return err;
- }
-
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
usleep_range(10000, 11000);

regulator_disable(tdo_tl070wsh30->supply);

---
base-commit: e05b559f9cda350d0ab33c44a8c1151ca62d2875
change-id: 20260722-mipi-dsi-tl070wsh30-multi-2095299d5b12

Best regards,
--
Akash Sukhavasi <akash.sukhavasi@xxxxxxxxx>