]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm: renesas: rz-du: mipi_dsi: fix kernel panic when rebooting for some panels
authorHugo Villeneuve <hvilleneuve@dimonoff.com>
Mon, 12 Jan 2026 15:43:18 +0000 (10:43 -0500)
committerBiju Das <biju.das.jz@bp.renesas.com>
Fri, 16 Jan 2026 07:49:51 +0000 (07:49 +0000)
Since commit 56de5e305d4b ("clk: renesas: r9a07g044: Add MSTOP for RZ/G2L")
we may get the following kernel panic, for some panels, when rebooting:

  systemd-shutdown[1]: Rebooting.
  Call trace:
   ...
   do_serror+0x28/0x68
   el1h_64_error_handler+0x34/0x50
   el1h_64_error+0x6c/0x70
   rzg2l_mipi_dsi_host_transfer+0x114/0x458 (P)
   mipi_dsi_device_transfer+0x44/0x58
   mipi_dsi_dcs_set_display_off_multi+0x9c/0xc4
   ili9881c_unprepare+0x38/0x88
   drm_panel_unprepare+0xbc/0x108

This happens for panels that need to send MIPI-DSI commands in their
unprepare() callback. Since the MIPI-DSI interface is stopped at that
point, rzg2l_mipi_dsi_host_transfer() triggers the kernel panic.

Fix by moving rzg2l_mipi_dsi_stop() to new callback function
rzg2l_mipi_dsi_atomic_post_disable().

With this change we now have the correct power-down/stop sequence:

  systemd-shutdown[1]: Rebooting.
  rzg2l-mipi-dsi 10850000.dsi: rzg2l_mipi_dsi_atomic_disable(): entry
  ili9881c-dsi 10850000.dsi.0: ili9881c_unprepare(): entry
  rzg2l-mipi-dsi 10850000.dsi: rzg2l_mipi_dsi_atomic_post_disable(): entry
  reboot: Restarting system

Suggested-by: Biju Das <biju.das.jz@bp.renesas.com>
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Tested-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://patch.msgid.link/20260112154333.655352-1-hugo@hugovil.com
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c

index 5edd45424562e06ee6c1ec47e626e07136d3266c..f74a0aa85ba832d2f57b9971c678043408c671f4 100644 (file)
@@ -1068,6 +1068,13 @@ static void rzg2l_mipi_dsi_atomic_disable(struct drm_bridge *bridge,
 
        rzg2l_mipi_dsi_stop_video(dsi);
        rzg2l_mipi_dsi_stop_hs_clock(dsi);
+}
+
+static void rzg2l_mipi_dsi_atomic_post_disable(struct drm_bridge *bridge,
+                                              struct drm_atomic_state *state)
+{
+       struct rzg2l_mipi_dsi *dsi = bridge_to_rzg2l_mipi_dsi(bridge);
+
        rzg2l_mipi_dsi_stop(dsi);
 }
 
@@ -1103,6 +1110,7 @@ static const struct drm_bridge_funcs rzg2l_mipi_dsi_bridge_ops = {
        .atomic_pre_enable = rzg2l_mipi_dsi_atomic_pre_enable,
        .atomic_enable = rzg2l_mipi_dsi_atomic_enable,
        .atomic_disable = rzg2l_mipi_dsi_atomic_disable,
+       .atomic_post_disable = rzg2l_mipi_dsi_atomic_post_disable,
        .mode_valid = rzg2l_mipi_dsi_bridge_mode_valid,
 };