Skip to content

Commit fe0f1e3

Browse files
committed
drm/i915: Shut down displays gracefully on reboot
Implement the pci .shutdown() hook in order to quiesce the hardware prior to reboot. The main purpose here is to turn all displays off. Some displays/other drivers tend to get confused if the state after reboot isn't exactly as they expected. One specific example was the Dell UP2414Q in MST mode. It would require me to pull the power cord after a reboot or else it would just not come back to life. Sadly I don't have that at hand anymore so not sure if it's still misbehaving without the graceful shutdown, or if we managed to fix something else since I last tested it. For good measure we do a gem suspend as well, so that we match the suspend flow more closely. Also stopping all DMA and whatnot is probably a good idea for kexec. I would expect that some kind of GT reset happens on normal reboot so probably not totally necessary there. v2: Use the pci .shutdown() hook instead of a reboot notifier (Lukas) Do the gem suspend for kexec (Chris) Cc: Lukas Wunner <[email protected]> Cc: Chris Wilson <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Jani Nikula <[email protected]> Reviewed-by: Chris Wilson <[email protected]>
1 parent 67807f5 commit fe0f1e3

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

drivers/gpu/drm/i915/i915_drv.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,22 @@ static void intel_suspend_encoders(struct drm_i915_private *dev_priv)
10371037
drm_modeset_unlock_all(dev);
10381038
}
10391039

1040+
void i915_driver_shutdown(struct drm_i915_private *i915)
1041+
{
1042+
i915_gem_suspend(i915);
1043+
1044+
drm_kms_helper_poll_disable(&i915->drm);
1045+
1046+
drm_atomic_helper_shutdown(&i915->drm);
1047+
1048+
intel_dp_mst_suspend(i915);
1049+
1050+
intel_runtime_pm_disable_interrupts(i915);
1051+
intel_hpd_cancel_work(i915);
1052+
1053+
intel_suspend_encoders(i915);
1054+
}
1055+
10401056
static bool suspend_to_idle(struct drm_i915_private *dev_priv)
10411057
{
10421058
#if IS_ENABLED(CONFIG_ACPI_SLEEP)

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ extern const struct dev_pm_ops i915_pm_ops;
17791779

17801780
int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
17811781
void i915_driver_remove(struct drm_i915_private *i915);
1782+
void i915_driver_shutdown(struct drm_i915_private *i915);
17821783

17831784
int i915_resume_switcheroo(struct drm_i915_private *i915);
17841785
int i915_suspend_switcheroo(struct drm_i915_private *i915, pm_message_t state);

drivers/gpu/drm/i915/i915_pci.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,11 +1090,19 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10901090
return 0;
10911091
}
10921092

1093+
static void i915_pci_shutdown(struct pci_dev *pdev)
1094+
{
1095+
struct drm_i915_private *i915 = pci_get_drvdata(pdev);
1096+
1097+
i915_driver_shutdown(i915);
1098+
}
1099+
10931100
static struct pci_driver i915_pci_driver = {
10941101
.name = DRIVER_NAME,
10951102
.id_table = pciidlist,
10961103
.probe = i915_pci_probe,
10971104
.remove = i915_pci_remove,
1105+
.shutdown = i915_pci_shutdown,
10981106
.driver.pm = &i915_pm_ops,
10991107
};
11001108

0 commit comments

Comments
 (0)