[PATCH 3/4] drm/panel: innolux-p079zca: Use mipi_dsi_*_multi(); fix minor bugs
From: Akash Sukhavasi
Date: Tue Oct 13 2026 - 00:37:11 EST
The mipi_dsi_dcs_*() 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() 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 delays must
execute regardless of any prior DSI error. The original code logged a
set_display_off() failure and still attempted enter_sleep_mode(), so
clear accum_err after set_display_off_multi() to keep that behaviour.
This also fixes a bug where a failure in enter_sleep_mode would return
early, skipping the sleep-mode delay, GPIO deassertion, power-down
delay, and regulator teardown, 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_bulk_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-innolux-p079zca.c | 43 ++++++++++-----------------
1 file changed, 16 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
index 80afeeab9475..8da2f9b2ddde 100644
--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c
+++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c
@@ -54,17 +54,13 @@ static inline struct innolux_panel *to_innolux_panel(struct drm_panel *panel)
static int innolux_panel_unprepare(struct drm_panel *panel)
{
struct innolux_panel *innolux = to_innolux_panel(panel);
- int err;
-
- err = mipi_dsi_dcs_set_display_off(innolux->link);
- if (err < 0)
- dev_err(panel->dev, "failed to set display off: %d\n", err);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = innolux->link };
- err = mipi_dsi_dcs_enter_sleep_mode(innolux->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
- return err;
- }
+ 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;
+ /* Enter sleep mode; error does not prevent power-off */
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
if (innolux->desc->sleep_mode_delay)
msleep(innolux->desc->sleep_mode_delay);
@@ -74,10 +70,8 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
if (innolux->desc->power_down_delay)
msleep(innolux->desc->power_down_delay);
- err = regulator_bulk_disable(innolux->desc->num_supplies,
- innolux->supplies);
- if (err < 0)
- return err;
+ regulator_bulk_disable(innolux->desc->num_supplies,
+ innolux->supplies);
return 0;
}
@@ -85,6 +79,7 @@ static int innolux_panel_unprepare(struct drm_panel *panel)
static int innolux_panel_prepare(struct drm_panel *panel)
{
struct innolux_panel *innolux = to_innolux_panel(panel);
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = innolux->link };
int err;
gpiod_set_value_cansleep(innolux->enable_gpio, 0);
@@ -108,24 +103,18 @@ static int innolux_panel_prepare(struct drm_panel *panel)
goto poweroff;
}
- err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);
- if (err < 0) {
- dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
- goto poweroff;
- }
-
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
/* T6: 120ms - 1000ms*/
- msleep(120);
+ mipi_dsi_msleep(&dsi_ctx, 120);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ /* T7: 5ms */
+ mipi_dsi_usleep_range(&dsi_ctx, 5000, 6000);
- err = mipi_dsi_dcs_set_display_on(innolux->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: 5ms */
- usleep_range(5000, 6000);
-
return 0;
poweroff:
--
2.56.0