refactor(core): display driver suspend API improvement
What changed, and why it matters
This is a code cleanup change that moves decision-making about how deeply to put the screen to sleep out of the display driver and into a higher-level suspend module. It does not add or remove security protections; it only reorganizes which piece of code decides whether to keep the display partly alive for touch-wakeup or to fully shut it down. The behavior should be equivalent to before.
No security action required. Treat as a normal refactoring review; verify that suspend/resume behavior remains functionally equivalent on hardware with and without USE_TOUCH_WAKEUP.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors the display suspend/resume API by removing the touch_wakeup_enabled boolean parameter from display_suspend() and display_resume(). The branching between light-suspend and full deinit is moved from display_driver.c to suspend_io.c. display_resume() now internally detects whether the driver was fully deinitialized and either performs a light resume or a full reinit. This is an architectural layering change; the same two code paths are preserved, just relocated. There is no evidence of a vulnerability being fixed or introduced.
Changed components
core/embed/io/display/inc/io/display.hcore/embed/io/display/ltdc_dsi/display_driver.ccore/embed/io/suspend/stm32u5/suspend_io.cInspect captured patch +24 / −48
diff --git a/core/embed/io/display/inc/io/display.h b/core/embed/io/display/inc/io/display.h
index 683eb6dc..7454fad8 100644
--- a/core/embed/io/display/inc/io/display.h
+++ b/core/embed/io/display/inc/io/display.h
@@ -80,18 +80,14 @@ typedef struct {
// Suspends the display driver.
//
// Saves the current display state into `wakeup_params`.
-// `touch_wakeup_enabled` controls whether a light-suspend (keep panel powered
-// for touch wakeup) or a full deinit is performed.
-void display_suspend(display_wakeup_params_t *wakeup_params,
- bool touch_wakeup_enabled);
+void display_suspend(display_wakeup_params_t *wakeup_params);
// Resumes the display driver.
//
-// Restores the display state from `wakeup_params`.
-// `touch_wakeup_enabled` must match the value passed to `display_suspend()`;
-// it selects the matching light-resume or full reinit path.
-void display_resume(const display_wakeup_params_t *wakeup_params,
- bool touch_wakeup_enabled);
+// Restores the display state from `wakeup_params`. Handles both the
+// light-suspend case (driver still initialized) and the full-deinit
+// case (driver was fully deinitialized during suspend).
+void display_resume(const display_wakeup_params_t *wakeup_params);
#endif // USE_SUSPEND
// Allows unprivileged access to the display framebuffer from
diff --git a/core/embed/io/display/ltdc_dsi/display_driver.c b/core/embed/io/display/ltdc_dsi/display_driver.c
index 0fd0c370..ea13c6a1 100644
--- a/core/embed/io/display/ltdc_dsi/display_driver.c
+++ b/core/embed/io/display/ltdc_dsi/display_driver.c
@@ -633,21 +633,12 @@ void display_refresh_rate_config(void) {
#endif // REFRESH_RATE_SCALING_SUPPORTED
#ifdef USE_SUSPEND
-void display_suspend(display_wakeup_params_t *wakeup_params,
- bool touch_wakeup_enabled) {
-#ifdef USE_TOUCH_WAKEUP
- if (!touch_wakeup_enabled) {
- wakeup_params->backlight_level = display_get_backlight();
- display_deinit(DISPLAY_RESET_CONTENT);
- return;
- }
-
+void display_suspend(display_wakeup_params_t *wakeup_params) {
display_driver_t *drv = &g_display_driver;
memset(wakeup_params, 0, sizeof(display_wakeup_params_t));
if (!drv->initialized) {
- // The driver isn't initialized, wrong control flow applied
return;
}
@@ -662,26 +653,18 @@ void display_suspend(display_wakeup_params_t *wakeup_params,
}
memcpy(wakeup_params, &drv->wakeup_params, sizeof(display_wakeup_params_t));
-#else
- UNUSED(touch_wakeup_enabled);
- wakeup_params->backlight_level = display_get_backlight();
- display_deinit(DISPLAY_RESET_CONTENT);
-#endif // USE_TOUCH_WAKEUP
}
-void display_resume(const display_wakeup_params_t *wakeup_params,
- bool touch_wakeup_enabled) {
-#ifdef USE_TOUCH_WAKEUP
- if (!touch_wakeup_enabled) {
- display_init(DISPLAY_RESET_CONTENT);
- display_set_backlight(wakeup_params->backlight_level);
- return;
- }
-
+void display_resume(const display_wakeup_params_t *wakeup_params) {
display_driver_t *drv = &g_display_driver;
if (!drv->initialized) {
- // The driver isn't initialized, wrong control flow applied
+ if (!display_init(DISPLAY_RESET_CONTENT)) {
+ return;
+ }
+ if (!display_set_backlight(wakeup_params->backlight_level)) {
+ goto cleanup;
+ }
return;
}
@@ -705,11 +688,6 @@ void display_resume(const display_wakeup_params_t *wakeup_params,
cleanup:
display_deinit(DISPLAY_RESET_CONTENT);
return;
-#else
- UNUSED(touch_wakeup_enabled);
- display_init(DISPLAY_RESET_CONTENT);
- display_set_backlight(wakeup_params->backlight_level);
-#endif // USE_TOUCH_WAKEUP
}
#endif // USE_SUSPEND
diff --git a/core/embed/io/suspend/stm32u5/suspend_io.c b/core/embed/io/suspend/stm32u5/suspend_io.c
index fd3986ab..75a64ba8 100644
--- a/core/embed/io/suspend/stm32u5/suspend_io.c
+++ b/core/embed/io/suspend/stm32u5/suspend_io.c
@@ -78,11 +78,17 @@ void suspend_drivers_phase1(power_save_wakeup_params_t *wakeup_params) {
#endif
#ifdef USE_DISPLAY
#ifdef USE_TOUCH_WAKEUP
- display_suspend(&wakeup_params->display, touch_wakeup_get_enabled());
+ bool touch_wakeup_enabled = touch_wakeup_get_enabled();
#else
- display_suspend(&wakeup_params->display, false);
-#endif
-#endif
+ bool touch_wakeup_enabled = false;
+#endif
+ if (touch_wakeup_enabled) {
+ display_suspend(&wakeup_params->display);
+ } else {
+ wakeup_params->display.backlight_level = display_get_backlight();
+ display_deinit(DISPLAY_RESET_CONTENT);
+ }
+#endif // USE_DISPLAY
}
void suspend_drivers_phase2(void) {
@@ -98,11 +104,7 @@ void suspend_drivers_phase2(void) {
// Reinitialize all drivers that were stopped earlier
void resume_drivers(const power_save_wakeup_params_t *wakeup_params) {
#ifdef USE_DISPLAY
-#ifdef USE_TOUCH_WAKEUP
- display_resume(&wakeup_params->display, touch_wakeup_get_enabled());
-#else
- display_resume(&wakeup_params->display, false);
-#endif
+ display_resume(&wakeup_params->display);
#endif
#ifdef USE_TOUCH
touch_resume();
Why this scored 12/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.