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 <[email protected]> --- 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
