Atm, during system resume, the driver updates the display connector information required by the opregion video extensions during system resume, on platforms both with and without display being present. On !HAS_DISPLAY platforms this will result in the crash with the stack trace below, since the driver's connector state is not initialized on those. Bspec doesn't specify when each of the opregion functionality is supported (depending on the presence of display), however we can presume that none of the video extensions, nor the ACPI _DSM functions are supported on !HAS_DISPLAY platforms; accordingly skip the corresponding opregion/ACPI setup on those (also matching the Windows driver in this). Keep sending the opregion notification about suspending/resuming the whole adapter (vs. the display only which is a separate power state notification) on all platforms, similarly to runtime suspend/resume. This fixes the following: Oops: 0000 [#1] PREEMPT SMP NOPTI CPU: 4 PID: 1443 Comm: kworker/u40:55 Tainted: G U 6.2.0-rc8+ #58 Hardware name: LENOVO 82VB/LNVNB161216, BIOS KMCN09WW 04/26/2022 Workqueue: events_unbound async_run_entry_fn RIP: 0010:drm_connector_list_iter_next+0x4f/0xb0 Call Trace: <TASK> intel_acpi_device_id_update+0x80/0x160 [i915] intel_opregion_resume+0x2f/0x1e0 [i915] ? dg2_init_clock_gating+0x49/0xf0 [i915] i915_drm_resume+0x137/0x190 [i915] ? __pfx_pci_pm_resume+0x10/0x10 dpm_run_callback+0x47/0x150 Cc: iczero <iczero@xxxxxxxxxxxxxx> Reported-and-tested-by: iczero <iczero@xxxxxxxxxxxxxx> References: https://gitlab.freedesktop.org/drm/intel/-/issues/8015 Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_opregion.c | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index b8dce0576512a..bbcc2142d7df5 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -1159,13 +1159,10 @@ void intel_opregion_register(struct drm_i915_private *i915) intel_opregion_resume(i915); } -void intel_opregion_resume(struct drm_i915_private *i915) +static void intel_opregion_resume_display(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->display.opregion; - if (!opregion->header) - return; - if (opregion->acpi) { intel_didl_outputs(i915); intel_setup_cadls(i915); @@ -1186,19 +1183,25 @@ void intel_opregion_resume(struct drm_i915_private *i915) /* Some platforms abuse the _DSM to enable MUX */ intel_dsm_get_bios_data_funcs_supported(i915); +} + +void intel_opregion_resume(struct drm_i915_private *i915) +{ + struct intel_opregion *opregion = &i915->display.opregion; + + if (!opregion->header) + return; + + if (HAS_DISPLAY(i915)) + intel_opregion_resume_display(i915); intel_opregion_notify_adapter(i915, PCI_D0); } -void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state) +static void intel_opregion_suspend_display(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->display.opregion; - if (!opregion->header) - return; - - intel_opregion_notify_adapter(i915, state); - if (opregion->asle) opregion->asle->ardy = ASLE_ARDY_NOT_READY; @@ -1208,6 +1211,19 @@ void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state) opregion->acpi->drdy = 0; } +void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state) +{ + struct intel_opregion *opregion = &i915->display.opregion; + + if (!opregion->header) + return; + + intel_opregion_notify_adapter(i915, state); + + if (HAS_DISPLAY(i915)) + intel_opregion_suspend_display(i915); +} + void intel_opregion_unregister(struct drm_i915_private *i915) { struct intel_opregion *opregion = &i915->display.opregion; -- 2.37.1