drm/i915: Stop calling intel_opregion unregister/register in suspend/resume
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 30 Oct 2018 11:05:54 +0000 (11:05 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Tue, 30 Oct 2018 11:52:54 +0000 (11:52 +0000)
If we reduce the suspend function for intel_opregion to do the minimum
required, the resume function can also do the simple task of notifier
the ACPI bios that we are back. This avoid some nasty restrictions on
the likes of register_acpi_notifier() that are not allowed during the
early phase of resume.

v2: Keep the order of acpi notify vs turning off ardy/drdy the same.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Acked-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181030110554.4111-1-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_opregion.c
drivers/gpu/drm/i915/intel_opregion.h

index 1ad13da61d7aec6861f307a2e736ee7f6fea32f6..f6416b1d3452f88c05cc9a0fa0ff28fa24e957ed 100644 (file)
@@ -1921,9 +1921,7 @@ static int i915_drm_suspend(struct drm_device *dev)
        i915_save_state(dev_priv);
 
        opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold;
-       intel_opregion_notify_adapter(dev_priv, opregion_target_state);
-
-       intel_opregion_unregister(dev_priv);
+       intel_opregion_suspend(dev_priv, opregion_target_state);
 
        intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true);
 
@@ -2042,7 +2040,6 @@ static int i915_drm_resume(struct drm_device *dev)
 
        i915_restore_state(dev_priv);
        intel_pps_unlock_regs_wa(dev_priv);
-       intel_opregion_setup(dev_priv);
 
        intel_init_pch_refclk(dev_priv);
 
@@ -2084,12 +2081,10 @@ static int i915_drm_resume(struct drm_device *dev)
         * */
        intel_hpd_init(dev_priv);
 
-       intel_opregion_register(dev_priv);
+       intel_opregion_resume(dev_priv);
 
        intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false);
 
-       intel_opregion_notify_adapter(dev_priv, PCI_D0);
-
        intel_power_domains_enable(dev_priv);
 
        enable_rpm_wakeref_asserts(dev_priv);
index e034b4166d322f8182a9f31bcfb1cd224c686214..b8f106d9ecf8b1be6286b2dfaeac1c5188629528 100644 (file)
@@ -773,70 +773,6 @@ static void intel_setup_cadls(struct drm_i915_private *dev_priv)
                opregion->acpi->cadl[i] = 0;
 }
 
-void intel_opregion_register(struct drm_i915_private *dev_priv)
-{
-       struct intel_opregion *opregion = &dev_priv->opregion;
-
-       if (!opregion->header)
-               return;
-
-       if (opregion->acpi) {
-               intel_didl_outputs(dev_priv);
-               intel_setup_cadls(dev_priv);
-
-               /* Notify BIOS we are ready to handle ACPI video ext notifs.
-                * Right now, all the events are handled by the ACPI video module.
-                * We don't actually need to do anything with them. */
-               opregion->acpi->csts = 0;
-               opregion->acpi->drdy = 1;
-
-               opregion->acpi_notifier.notifier_call = intel_opregion_video_event;
-               register_acpi_notifier(&opregion->acpi_notifier);
-       }
-
-       if (opregion->asle) {
-               opregion->asle->tche = ASLE_TCHE_BLC_EN;
-               opregion->asle->ardy = ASLE_ARDY_READY;
-       }
-}
-
-void intel_opregion_unregister(struct drm_i915_private *dev_priv)
-{
-       struct intel_opregion *opregion = &dev_priv->opregion;
-
-       if (!opregion->header)
-               return;
-
-       if (opregion->asle)
-               opregion->asle->ardy = ASLE_ARDY_NOT_READY;
-
-       cancel_work_sync(&dev_priv->opregion.asle_work);
-
-       if (opregion->acpi) {
-               opregion->acpi->drdy = 0;
-
-               unregister_acpi_notifier(&opregion->acpi_notifier);
-               opregion->acpi_notifier.notifier_call = NULL;
-       }
-
-       /* just clear all opregion memory pointers now */
-       memunmap(opregion->header);
-       if (opregion->rvda) {
-               memunmap(opregion->rvda);
-               opregion->rvda = NULL;
-       }
-       if (opregion->vbt_firmware) {
-               kfree(opregion->vbt_firmware);
-               opregion->vbt_firmware = NULL;
-       }
-       opregion->header = NULL;
-       opregion->acpi = NULL;
-       opregion->swsci = NULL;
-       opregion->asle = NULL;
-       opregion->vbt = NULL;
-       opregion->lid_state = NULL;
-}
-
 static void swsci_setup(struct drm_i915_private *dev_priv)
 {
        struct intel_opregion *opregion = &dev_priv->opregion;
@@ -1115,3 +1051,97 @@ intel_opregion_get_panel_type(struct drm_i915_private *dev_priv)
 
        return ret - 1;
 }
+
+void intel_opregion_register(struct drm_i915_private *i915)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       if (!opregion->header)
+               return;
+
+       if (opregion->acpi) {
+               opregion->acpi_notifier.notifier_call =
+                       intel_opregion_video_event;
+               register_acpi_notifier(&opregion->acpi_notifier);
+       }
+
+       intel_opregion_resume(i915);
+}
+
+void intel_opregion_resume(struct drm_i915_private *i915)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       if (!opregion->header)
+               return;
+
+       if (opregion->acpi) {
+               intel_didl_outputs(i915);
+               intel_setup_cadls(i915);
+
+               /*
+                * Notify BIOS we are ready to handle ACPI video ext notifs.
+                * Right now, all the events are handled by the ACPI video
+                * module. We don't actually need to do anything with them.
+                */
+               opregion->acpi->csts = 0;
+               opregion->acpi->drdy = 1;
+       }
+
+       if (opregion->asle) {
+               opregion->asle->tche = ASLE_TCHE_BLC_EN;
+               opregion->asle->ardy = ASLE_ARDY_READY;
+       }
+
+       intel_opregion_notify_adapter(i915, PCI_D0);
+}
+
+void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       if (!opregion->header)
+               return;
+
+       intel_opregion_notify_adapter(i915, state);
+
+       if (opregion->asle)
+               opregion->asle->ardy = ASLE_ARDY_NOT_READY;
+
+       cancel_work_sync(&i915->opregion.asle_work);
+
+       if (opregion->acpi)
+               opregion->acpi->drdy = 0;
+}
+
+void intel_opregion_unregister(struct drm_i915_private *i915)
+{
+       struct intel_opregion *opregion = &i915->opregion;
+
+       intel_opregion_suspend(i915, PCI_D1);
+
+       if (!opregion->header)
+               return;
+
+       if (opregion->acpi_notifier.notifier_call) {
+               unregister_acpi_notifier(&opregion->acpi_notifier);
+               opregion->acpi_notifier.notifier_call = NULL;
+       }
+
+       /* just clear all opregion memory pointers now */
+       memunmap(opregion->header);
+       if (opregion->rvda) {
+               memunmap(opregion->rvda);
+               opregion->rvda = NULL;
+       }
+       if (opregion->vbt_firmware) {
+               kfree(opregion->vbt_firmware);
+               opregion->vbt_firmware = NULL;
+       }
+       opregion->header = NULL;
+       opregion->acpi = NULL;
+       opregion->swsci = NULL;
+       opregion->asle = NULL;
+       opregion->vbt = NULL;
+       opregion->lid_state = NULL;
+}
index e8498a8cda3d1c9850f386bb00bfef90622fa12c..d84b6d2d2faee58230a926164443c1f14ffe06b5 100644 (file)
@@ -57,8 +57,14 @@ struct intel_opregion {
 #ifdef CONFIG_ACPI
 
 int intel_opregion_setup(struct drm_i915_private *dev_priv);
+
 void intel_opregion_register(struct drm_i915_private *dev_priv);
 void intel_opregion_unregister(struct drm_i915_private *dev_priv);
+
+void intel_opregion_resume(struct drm_i915_private *dev_priv);
+void intel_opregion_suspend(struct drm_i915_private *dev_priv,
+                           pci_power_t state);
+
 void intel_opregion_asle_intr(struct drm_i915_private *dev_priv);
 int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
                                  bool enable);
@@ -81,6 +87,15 @@ static inline void intel_opregion_unregister(struct drm_i915_private *dev_priv)
 {
 }
 
+void intel_opregion_resume(struct drm_i915_private *dev_priv)
+{
+}
+
+void intel_opregion_suspend(struct drm_i915_private *dev_priv,
+                           pci_power_t state)
+{
+}
+
 static inline void intel_opregion_asle_intr(struct drm_i915_private *dev_priv)
 {
 }