drm/i915: Ensure proper HDA suspend/resume ordering with a device link
authorImre Deak <imre.deak@intel.com>
Tue, 23 Oct 2018 14:43:10 +0000 (17:43 +0300)
committerImre Deak <imre.deak@intel.com>
Thu, 25 Oct 2018 12:41:23 +0000 (15:41 +0300)
In order to ensure that our system suspend and resume callbacks are
called in the correct order wrt. those of the HDA driver add a device
link to the HDA driver during audio component binding time. With i915 as
the supplier and HDA as the consumer the PM framework will guarantee
the HDA->i915 suspend (and shutdown) and i915->HDA resume order.

Atm, the lack of this ordering is not a problem, since all the i915
suspend/resume steps that need to be ordered wrt. the HDA driver's
suspend/resume steps are separated out to the i915
suspend_late/resume_early hooks. That will change in a follow-up
patchset where we'll need this ordering guarantee for steps that are in
the i915 suspend/resume hooks (and which can't be moved to
suspend_late/resume_early for other reasons). So this patch is a
preparation for that follow-up patchset.

The change also allows us to move towards removing the i915
suspend_late/resume_early hooks alltogether.

Since we only need to ensure the ordering during suspend/resume and not
during driver probing create the link with DL_FLAG_STATELESS. Since the
probe time ordering has to be optional we use the component framework
for that.

Similarly for runtime PM we depend on the audio driver getting/putting
an i915 runtime PM reference whenever it needs it (along with the proper
i915 display power domain) via the audio component ops get_power /
put_power hooks. So we create the device link without
DL_FLAG_PM_RUNTIME.

v2: (Ville)
- Add a note to the commit message about not using the device link
  runtime PM ordering.
- Handle the error return from device_link_add().

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181023144310.8272-1-imre.deak@intel.com
drivers/gpu/drm/i915/intel_audio.c

index 769f3f5866611174cbabeca5e4d1fbb0711b9b86..b2c656a46be628fc326a2bd90bc832853c6dc0c4 100644 (file)
@@ -912,6 +912,9 @@ static int i915_audio_component_bind(struct device *i915_kdev,
        if (WARN_ON(acomp->base.ops || acomp->base.dev))
                return -EEXIST;
 
+       if (WARN_ON(!device_link_add(hda_kdev, i915_kdev, DL_FLAG_STATELESS)))
+               return -ENOMEM;
+
        drm_modeset_lock_all(&dev_priv->drm);
        acomp->base.ops = &i915_audio_component_ops;
        acomp->base.dev = i915_kdev;
@@ -935,6 +938,8 @@ static void i915_audio_component_unbind(struct device *i915_kdev,
        acomp->base.dev = NULL;
        dev_priv->audio_component = NULL;
        drm_modeset_unlock_all(&dev_priv->drm);
+
+       device_link_remove(hda_kdev, i915_kdev);
 }
 
 static const struct component_ops i915_audio_component_bind_ops = {