Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> writes: > The majority of runtime-pm operations are bounded and scoped within a > function; these are easy to verify that the wakeref are handled > correctly. We can employ the compiler to help us, and reduce the number > of wakerefs tracked when debugging, by passing around cookies provided > by the various rpm_get functions to their rpm_put counterpart. This > makes the pairing explicit, and given the required wakeref cookie the > compiler can verify that we pass an initialised value to the rpm_put > (quite handy for double checking error paths). > > Signed-off-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> > Cc: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_debugfs.c | 35 ++++++------ > drivers/gpu/drm/i915/i915_drv.h | 2 + > drivers/gpu/drm/i915/i915_gem.c | 4 +- > drivers/gpu/drm/i915/icl_dsi.c | 36 ++++++++----- > drivers/gpu/drm/i915/intel_audio.c | 3 +- > drivers/gpu/drm/i915/intel_cdclk.c | 10 ++-- > drivers/gpu/drm/i915/intel_crt.c | 25 +++++---- > drivers/gpu/drm/i915/intel_csr.c | 25 +++++++-- > drivers/gpu/drm/i915/intel_ddi.c | 36 ++++++++----- > drivers/gpu/drm/i915/intel_display.c | 68 ++++++++++++++--------- > drivers/gpu/drm/i915/intel_dp.c | 38 +++++++------ > drivers/gpu/drm/i915/intel_dpll_mgr.c | 66 +++++++++++++++-------- > drivers/gpu/drm/i915/intel_drv.h | 17 ++++-- > drivers/gpu/drm/i915/intel_dsi.h | 1 + > drivers/gpu/drm/i915/intel_hdmi.c | 18 ++++--- > drivers/gpu/drm/i915/intel_i2c.c | 20 +++---- > drivers/gpu/drm/i915/intel_lvds.c | 8 +-- > drivers/gpu/drm/i915/intel_pipe_crc.c | 6 ++- > drivers/gpu/drm/i915/intel_pm.c | 6 ++- > drivers/gpu/drm/i915/intel_runtime_pm.c | 71 ++++++++++++++++--------- > drivers/gpu/drm/i915/intel_sprite.c | 24 ++++++--- > drivers/gpu/drm/i915/intel_vdsc.c | 4 +- > drivers/gpu/drm/i915/vlv_dsi.c | 14 +++-- > 23 files changed, 347 insertions(+), 190 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c > index 34cbd9a20583..b7dcacf2a5d3 100644 > --- a/drivers/gpu/drm/i915/i915_debugfs.c > +++ b/drivers/gpu/drm/i915/i915_debugfs.c > @@ -626,10 +626,12 @@ static void gen8_display_interrupt_info(struct seq_file *m) > > for_each_pipe(dev_priv, pipe) { > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > > power_domain = POWER_DOMAIN_PIPE(pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, > - power_domain)) { > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + power_domain); > + if (!wakeref) { > seq_printf(m, "Pipe %c power disabled\n", > pipe_name(pipe)); > continue; > @@ -644,7 +646,7 @@ static void gen8_display_interrupt_info(struct seq_file *m) > pipe_name(pipe), > I915_READ(GEN8_DE_PIPE_IER(pipe))); > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > } > > seq_printf(m, "Display Engine port interrupt mask:\t%08x\n", > @@ -680,6 +682,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data) > wakeref = intel_runtime_pm_get(dev_priv); > > if (IS_CHERRYVIEW(dev_priv)) { > + intel_wakeref_t pref; > + In here you are introducing a new, descriptive, power reference for display. But then you drop it after using it twice. And can't seem to find reason for inconsistency. > seq_printf(m, "Master Interrupt Control:\t%08x\n", > I915_READ(GEN8_MASTER_IRQ)); > > @@ -695,8 +699,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data) > enum intel_display_power_domain power_domain; > > power_domain = POWER_DOMAIN_PIPE(pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, > - power_domain)) { > + pref = intel_display_power_get_if_enabled(dev_priv, > + power_domain); > + if (!pref) { > seq_printf(m, "Pipe %c power disabled\n", > pipe_name(pipe)); > continue; > @@ -706,17 +711,17 @@ static int i915_interrupt_info(struct seq_file *m, void *data) > pipe_name(pipe), > I915_READ(PIPESTAT(pipe))); > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, pref); > } > > - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > + pref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > seq_printf(m, "Port hotplug:\t%08x\n", > I915_READ(PORT_HOTPLUG_EN)); > seq_printf(m, "DPFLIPSTAT:\t%08x\n", > I915_READ(VLV_DPFLIPSTAT)); > seq_printf(m, "DPINVGTT:\t%08x\n", > I915_READ(DPINVGTT)); > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, pref); > > for (i = 0; i < 4; i++) { > seq_printf(m, "GT Interrupt IMR %d:\t%08x\n", > @@ -779,10 +784,12 @@ static int i915_interrupt_info(struct seq_file *m, void *data) > I915_READ(VLV_IMR)); > for_each_pipe(dev_priv, pipe) { > enum intel_display_power_domain power_domain; > + intel_wakeref_t pref; > > power_domain = POWER_DOMAIN_PIPE(pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, > - power_domain)) { > + pref = intel_display_power_get_if_enabled(dev_priv, > + power_domain); > + if (!pref) { > seq_printf(m, "Pipe %c power disabled\n", > pipe_name(pipe)); > continue; > @@ -791,7 +798,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) > seq_printf(m, "Pipe %c stat:\t%08x\n", > pipe_name(pipe), > I915_READ(PIPESTAT(pipe))); > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, pref); > } > > seq_printf(m, "Master IER:\t%08x\n", > @@ -1709,8 +1716,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) > intel_wakeref_t wakeref; > bool sr_enabled = false; > > - wakeref = intel_runtime_pm_get(dev_priv); > - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > > if (INTEL_GEN(dev_priv) >= 9) > /* no global SR status; inspect per-plane WM */; > @@ -1726,8 +1732,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) > else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) > sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN; > > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > - intel_runtime_pm_put(dev_priv, wakeref); > + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); > > seq_printf(m, "self-refresh: %s\n", enableddisabled(sr_enabled)); > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index f0a405604b75..44c1b21febba 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -344,6 +344,7 @@ struct intel_csr { > uint32_t mmiodata[8]; > uint32_t dc_state; > uint32_t allowed_dc_mask; > + intel_wakeref_t wakeref; > }; > > enum i915_cache_level { > @@ -1982,6 +1983,7 @@ struct drm_i915_private { > * is a slight delay before we do so. > */ > intel_wakeref_t awake; > + intel_wakeref_t power; This prolly explains the prefs above :) > > /** > * The number of times we have woken up. > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c > index 67fd119bdad8..5ed1c8576525 100644 > --- a/drivers/gpu/drm/i915/i915_gem.c > +++ b/drivers/gpu/drm/i915/i915_gem.c > @@ -176,7 +176,7 @@ static u32 __i915_gem_park(struct drm_i915_private *i915) > if (INTEL_GEN(i915) >= 6) > gen6_rps_idle(i915); > > - intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ); > + intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, i915->gt.power); > > intel_runtime_pm_put(i915, wakeref); > > @@ -221,7 +221,7 @@ void i915_gem_unpark(struct drm_i915_private *i915) > * Work around it by grabbing a GT IRQ power domain whilst there is any > * GT activity, preventing any DC state transitions. > */ > - intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ); > + i915->gt.power = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ); > > if (unlikely(++i915->gt.epoch == 0)) /* keep 0 as invalid */ > i915->gt.epoch = 1; > diff --git a/drivers/gpu/drm/i915/icl_dsi.c b/drivers/gpu/drm/i915/icl_dsi.c > index 4dd793b78996..f3a5f03646ce 100644 > --- a/drivers/gpu/drm/i915/icl_dsi.c > +++ b/drivers/gpu/drm/i915/icl_dsi.c > @@ -337,9 +337,11 @@ static void gen11_dsi_enable_io_power(struct intel_encoder *encoder) > } > > for_each_dsi_port(port, intel_dsi->ports) { > - intel_display_power_get(dev_priv, port == PORT_A ? > - POWER_DOMAIN_PORT_DDI_A_IO : > - POWER_DOMAIN_PORT_DDI_B_IO); > + intel_dsi->io_wakeref[port] = > + intel_display_power_get(dev_priv, > + port == PORT_A ? > + POWER_DOMAIN_PORT_DDI_A_IO : > + POWER_DOMAIN_PORT_DDI_B_IO); > } > } > > @@ -1125,10 +1127,18 @@ static void gen11_dsi_disable_io_power(struct intel_encoder *encoder) > enum port port; > u32 tmp; > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PORT_DDI_A_IO); > - > - if (intel_dsi->dual_link) > - intel_display_power_put(dev_priv, POWER_DOMAIN_PORT_DDI_B_IO); > + for_each_dsi_port(port, intel_dsi->ports) { > + intel_wakeref_t wakeref; > + > + wakeref = fetch_and_zero(&intel_dsi->io_wakeref[port]); > + if (wakeref) { > + intel_display_power_put(dev_priv, > + port == PORT_A ? > + POWER_DOMAIN_PORT_DDI_A_IO : > + POWER_DOMAIN_PORT_DDI_B_IO, > + wakeref); > + } > + } Ok, well. I have been trying to figure out what really is going on here. First it seems that you fix a bug. We take refs for each dsi port but only release once special casing 'dual_link' without this patch. Second, all the hw access is before getting the refs, looking suspicious. > > /* set mode to DDI */ > for_each_dsi_port(port, intel_dsi->ports) { > @@ -1229,13 +1239,15 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); > - u32 tmp; > - enum port port; > enum transcoder dsi_trans; > + intel_wakeref_t wakeref; > + enum port port; > bool ret = false; > + u32 tmp; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > for_each_dsi_port(port, intel_dsi->ports) { > @@ -1260,7 +1272,7 @@ static bool gen11_dsi_get_hw_state(struct intel_encoder *encoder, > ret = tmp & PIPECONF_ENABLE; > } > out: > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > return ret; > } > > diff --git a/drivers/gpu/drm/i915/intel_audio.c b/drivers/gpu/drm/i915/intel_audio.c > index 202a58cf2d9f..de26cd0a5497 100644 > --- a/drivers/gpu/drm/i915/intel_audio.c > +++ b/drivers/gpu/drm/i915/intel_audio.c > @@ -748,7 +748,8 @@ static void i915_audio_component_get_power(struct device *kdev) > > static void i915_audio_component_put_power(struct device *kdev) > { > - intel_display_power_put(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO); > + intel_display_power_put_unchecked(kdev_to_i915(kdev), > + POWER_DOMAIN_AUDIO); > } > > static void i915_audio_component_codec_wake_override(struct device *kdev, > diff --git a/drivers/gpu/drm/i915/intel_cdclk.c b/drivers/gpu/drm/i915/intel_cdclk.c > index 2021e484a287..73cb7250118e 100644 > --- a/drivers/gpu/drm/i915/intel_cdclk.c > +++ b/drivers/gpu/drm/i915/intel_cdclk.c > @@ -520,6 +520,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, > { > int cdclk = cdclk_state->cdclk; > u32 val, cmd = cdclk_state->voltage_level; > + intel_wakeref_t wakeref; > > switch (cdclk) { > case 400000: > @@ -539,7 +540,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, > * a system suspend. So grab the PIPE-A domain, which covers > * the HW blocks needed for the following programming. > */ > - intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); > > mutex_lock(&dev_priv->pcu_lock); > val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); > @@ -593,7 +594,7 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv, > > vlv_program_pfi_credits(dev_priv); > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A, wakeref); > } > > static void chv_set_cdclk(struct drm_i915_private *dev_priv, > @@ -601,6 +602,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, > { > int cdclk = cdclk_state->cdclk; > u32 val, cmd = cdclk_state->voltage_level; > + intel_wakeref_t wakeref; > > switch (cdclk) { > case 333333: > @@ -619,7 +621,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, > * a system suspend. So grab the PIPE-A domain, which covers > * the HW blocks needed for the following programming. > */ > - intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A); > > mutex_lock(&dev_priv->pcu_lock); > val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); > @@ -637,7 +639,7 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv, > > vlv_program_pfi_credits(dev_priv); > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A, wakeref); > } > > static int bdw_calc_cdclk(int min_cdclk) > diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c > index 951e9bae6921..33bd2addcbdd 100644 > --- a/drivers/gpu/drm/i915/intel_crt.c > +++ b/drivers/gpu/drm/i915/intel_crt.c > @@ -83,15 +83,17 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_crt *crt = intel_encoder_to_crt(encoder); > + intel_wakeref_t wakeref; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > ret = intel_crt_port_enabled(dev_priv, crt->adpa_reg, pipe); > > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return ret; > } > @@ -776,6 +778,7 @@ intel_crt_detect(struct drm_connector *connector, > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_crt *crt = intel_attached_crt(connector); > struct intel_encoder *intel_encoder = &crt->base; > + intel_wakeref_t wakeref; > int status, ret; > struct intel_load_detect_pipe tmp; > > @@ -784,7 +787,8 @@ intel_crt_detect(struct drm_connector *connector, > force); > > if (i915_modparams.load_detect_test) { > - intel_display_power_get(dev_priv, intel_encoder->power_domain); > + wakeref = intel_display_power_get(dev_priv, > + intel_encoder->power_domain); > goto load_detect; > } > > @@ -792,7 +796,8 @@ intel_crt_detect(struct drm_connector *connector, > if (dmi_check_system(intel_spurious_crt_detect)) > return connector_status_disconnected; > > - intel_display_power_get(dev_priv, intel_encoder->power_domain); > + wakeref = intel_display_power_get(dev_priv, > + intel_encoder->power_domain); > > if (I915_HAS_HOTPLUG(dev_priv)) { > /* We can not rely on the HPD pin always being correctly wired > @@ -847,7 +852,7 @@ intel_crt_detect(struct drm_connector *connector, > } > > out: > - intel_display_power_put(dev_priv, intel_encoder->power_domain); > + intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); > return status; > } > > @@ -857,10 +862,12 @@ static int intel_crt_get_modes(struct drm_connector *connector) > struct drm_i915_private *dev_priv = to_i915(dev); > struct intel_crt *crt = intel_attached_crt(connector); > struct intel_encoder *intel_encoder = &crt->base; > - int ret; > + intel_wakeref_t wakeref; > struct i2c_adapter *i2c; > + int ret; > > - intel_display_power_get(dev_priv, intel_encoder->power_domain); > + wakeref = intel_display_power_get(dev_priv, > + intel_encoder->power_domain); > > i2c = intel_gmbus_get_adapter(dev_priv, dev_priv->vbt.crt_ddc_pin); > ret = intel_crt_ddc_get_modes(connector, i2c); > @@ -872,7 +879,7 @@ static int intel_crt_get_modes(struct drm_connector *connector) > ret = intel_crt_ddc_get_modes(connector, i2c); > > out: > - intel_display_power_put(dev_priv, intel_encoder->power_domain); > + intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_csr.c b/drivers/gpu/drm/i915/intel_csr.c > index a516697bf57d..ea5fb64d33dd 100644 > --- a/drivers/gpu/drm/i915/intel_csr.c > +++ b/drivers/gpu/drm/i915/intel_csr.c > @@ -409,6 +409,21 @@ static uint32_t *parse_csr_fw(struct drm_i915_private *dev_priv, > return memcpy(dmc_payload, &fw->data[readcount], nbytes); > } > > +static void intel_csr_runtime_pm_get(struct drm_i915_private *dev_priv) > +{ > + WARN_ON(dev_priv->csr.wakeref); > + dev_priv->csr.wakeref = > + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > +} > + > +static void intel_csr_runtime_pm_put(struct drm_i915_private *dev_priv) > +{ > + intel_wakeref_t wakeref __maybe_unused = > + fetch_and_zero(&dev_priv->csr.wakeref); > + > + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); > +} > + > static void csr_load_work_fn(struct work_struct *work) > { > struct drm_i915_private *dev_priv; > @@ -424,8 +439,7 @@ static void csr_load_work_fn(struct work_struct *work) > > if (dev_priv->csr.dmc_payload) { > intel_csr_load_program(dev_priv); > - > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_csr_runtime_pm_put(dev_priv); > > DRM_INFO("Finished loading DMC firmware %s (v%u.%u)\n", > dev_priv->csr.fw_path, > @@ -467,7 +481,7 @@ void intel_csr_ucode_init(struct drm_i915_private *dev_priv) > * suspend as runtime suspend *requires* a working CSR for whatever > * reason. > */ > - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > + intel_csr_runtime_pm_get(dev_priv); > > if (INTEL_GEN(dev_priv) >= 12) { > /* Allow to load fw via parameter using the last known size */ > @@ -538,7 +552,7 @@ void intel_csr_ucode_suspend(struct drm_i915_private *dev_priv) > > /* Drop the reference held in case DMC isn't loaded. */ > if (!dev_priv->csr.dmc_payload) > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_csr_runtime_pm_put(dev_priv); > } > > /** > @@ -558,7 +572,7 @@ void intel_csr_ucode_resume(struct drm_i915_private *dev_priv) > * loaded. > */ > if (!dev_priv->csr.dmc_payload) > - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > + intel_csr_runtime_pm_get(dev_priv); > } > > /** > @@ -574,6 +588,7 @@ void intel_csr_ucode_fini(struct drm_i915_private *dev_priv) > return; > > intel_csr_ucode_suspend(dev_priv); > + WARN_ON(dev_priv->csr.wakeref); > > kfree(dev_priv->csr.dmc_payload); > } > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c > index 2d6ed990a232..7f3cd055de50 100644 > --- a/drivers/gpu/drm/i915/intel_ddi.c > +++ b/drivers/gpu/drm/i915/intel_ddi.c > @@ -1860,12 +1860,14 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, > { > struct drm_device *dev = intel_encoder->base.dev; > struct drm_i915_private *dev_priv = to_i915(dev); > + intel_wakeref_t wakeref; > enum pipe pipe = 0; > int ret = 0; > uint32_t tmp; > > - if (WARN_ON(!intel_display_power_get_if_enabled(dev_priv, > - intel_encoder->power_domain))) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + intel_encoder->power_domain); > + if (WARN_ON(!wakeref)) > return -ENXIO; > > if (WARN_ON(!intel_encoder->get_hw_state(intel_encoder, &pipe))) { > @@ -1880,7 +1882,7 @@ int intel_ddi_toggle_hdcp_signalling(struct intel_encoder *intel_encoder, > tmp &= ~TRANS_DDI_HDCP_SIGNALLING; > I915_WRITE(TRANS_DDI_FUNC_CTL(pipe), tmp); > out: > - intel_display_power_put(dev_priv, intel_encoder->power_domain); > + intel_display_power_put(dev_priv, intel_encoder->power_domain, wakeref); > return ret; > } > > @@ -1891,13 +1893,15 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) > struct intel_encoder *encoder = intel_connector->encoder; > int type = intel_connector->base.connector_type; > enum port port = encoder->port; > - enum pipe pipe = 0; > enum transcoder cpu_transcoder; > + intel_wakeref_t wakeref; > + enum pipe pipe = 0; > uint32_t tmp; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > if (!encoder->get_hw_state(encoder, &pipe)) { > @@ -1939,7 +1943,7 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) > } > > out: > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return ret; > } > @@ -1950,6 +1954,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, > struct drm_device *dev = encoder->base.dev; > struct drm_i915_private *dev_priv = to_i915(dev); > enum port port = encoder->port; > + intel_wakeref_t wakeref; > enum pipe p; > u32 tmp; > u8 mst_pipe_mask; > @@ -1957,8 +1962,9 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, > *pipe_mask = 0; > *is_dp_mst = false; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return; > > tmp = I915_READ(DDI_BUF_CTL(port)); > @@ -2029,7 +2035,7 @@ static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder, > "(PHY_CTL %08x)\n", port_name(port), tmp); > } > > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > } > > bool intel_ddi_get_hw_state(struct intel_encoder *encoder, > @@ -3286,7 +3292,8 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder, > intel_edp_panel_vdd_on(intel_dp); > intel_edp_panel_off(intel_dp); > > - intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); > + intel_display_power_put_unchecked(dev_priv, > + dig_port->ddi_io_power_domain); > > intel_ddi_clk_disable(encoder); > } > @@ -3306,7 +3313,8 @@ static void intel_ddi_post_disable_hdmi(struct intel_encoder *encoder, > > intel_disable_ddi_buf(encoder, old_crtc_state); > > - intel_display_power_put(dev_priv, dig_port->ddi_io_power_domain); > + intel_display_power_put_unchecked(dev_priv, > + dig_port->ddi_io_power_domain); > > intel_ddi_clk_disable(encoder); > > @@ -3626,8 +3634,8 @@ intel_ddi_post_pll_disable(struct intel_encoder *encoder, > > if (intel_crtc_has_dp_encoder(crtc_state) || > intel_port_is_tc(dev_priv, encoder->port)) > - intel_display_power_put(dev_priv, > - intel_ddi_main_link_aux_domain(dig_port)); > + intel_display_power_put_unchecked(dev_priv, > + intel_ddi_main_link_aux_domain(dig_port)); > } > > void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index b0b8f9ffd873..36c56d1637b8 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -1197,17 +1197,19 @@ void assert_pipe(struct drm_i915_private *dev_priv, > enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, > pipe); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > > /* we keep both pipes enabled on 830 */ > if (IS_I830(dev_priv)) > state = true; > > power_domain = POWER_DOMAIN_TRANSCODER(cpu_transcoder); > - if (intel_display_power_get_if_enabled(dev_priv, power_domain)) { > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (wakeref) { > u32 val = I915_READ(PIPECONF(cpu_transcoder)); > cur_state = !!(val & PIPECONF_ENABLE); > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > } else { > cur_state = false; > } > @@ -3412,6 +3414,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; > + intel_wakeref_t wakeref; > bool ret; > u32 val; > > @@ -3421,7 +3424,8 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, > * display power wells. > */ > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > val = I915_READ(DSPCNTR(i9xx_plane)); > @@ -3434,7 +3438,7 @@ static bool i9xx_plane_get_hw_state(struct intel_plane *plane, > *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> > DISPPLANE_SEL_PIPE_SHIFT; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -6107,7 +6111,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv, > enum intel_display_power_domain domain; > > for_each_power_domain(domain, domains) > - intel_display_power_put(dev_priv, domain); > + intel_display_power_put_unchecked(dev_priv, domain); > } > > static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config, > @@ -6354,7 +6358,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc, > > domains = intel_crtc->enabled_power_domains; > for_each_power_domain(domain, domains) > - intel_display_power_put(dev_priv, domain); > + intel_display_power_put_unchecked(dev_priv, domain); > intel_crtc->enabled_power_domains = 0; > > dev_priv->active_crtcs &= ~(1 << intel_crtc->pipe); > @@ -7966,11 +7970,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, > { > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > uint32_t tmp; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(crtc->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; > @@ -8071,7 +8077,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, > ret = true; > > out: > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -9038,11 +9044,13 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, > struct drm_device *dev = crtc->base.dev; > struct drm_i915_private *dev_priv = to_i915(dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > uint32_t tmp; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(crtc->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB; > @@ -9125,7 +9133,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc, > ret = true; > > out: > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -9734,7 +9742,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, > > out: > for_each_power_domain(power_domain, power_domain_mask) > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put_unchecked(dev_priv, power_domain); > > return active; > } > @@ -9984,17 +9992,19 @@ static bool i845_cursor_get_hw_state(struct intel_plane *plane, > { > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(PIPE_A); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > ret = I915_READ(CURCNTR(PIPE_A)) & CURSOR_ENABLE; > > *pipe = PIPE_A; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -10217,6 +10227,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, > { > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > bool ret; > u32 val; > > @@ -10226,7 +10237,8 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, > * display power wells. > */ > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > val = I915_READ(CURCNTR(plane->pipe)); > @@ -10239,7 +10251,7 @@ static bool i9xx_cursor_get_hw_state(struct intel_plane *plane, > *pipe = (val & MCURSOR_PIPE_SELECT_MASK) >> > MCURSOR_PIPE_SELECT_SHIFT; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -12950,6 +12962,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) > struct drm_crtc *crtc; > struct intel_crtc *intel_crtc; > u64 put_domains[I915_MAX_PIPES] = {}; > + intel_wakeref_t wakeref = 0; > int i; > > intel_atomic_commit_fence_wait(intel_state); > @@ -12957,7 +12970,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) > drm_atomic_helper_wait_for_dependencies(state); > > if (intel_state->modeset) > - intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET); > > for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { > old_intel_crtc_state = to_intel_crtc_state(old_crtc_state); > @@ -13094,7 +13107,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) > * the culprit. > */ > intel_uncore_arm_unclaimed_mmio_detection(dev_priv); > - intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET); > + intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref); > } > > /* > @@ -15496,19 +15509,25 @@ void i915_redisable_vga_power_on(struct drm_i915_private *dev_priv) > > void i915_redisable_vga(struct drm_i915_private *dev_priv) > { > - /* This function can be called both from intel_modeset_setup_hw_state or > + intel_wakeref_t wakeref; > + > + /* > + * This function can be called both from intel_modeset_setup_hw_state or > * at a very early point in our resume sequence, where the power well > * structures are not yet restored. Since this function is at a very > * paranoid "someone might have enabled VGA while we were not looking" > * level, just check if the power well is enabled instead of trying to > * follow the "don't touch the power well if we don't need it" policy > - * the rest of the driver uses. */ > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_VGA)) > + * the rest of the driver uses. > + */ > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_VGA); > + if (!wakeref) > return; > > i915_redisable_vga_power_on(dev_priv); > > - intel_display_power_put(dev_priv, POWER_DOMAIN_VGA); > + intel_display_power_put(dev_priv, POWER_DOMAIN_VGA, wakeref); > } > > /* FIXME read out full plane state for all planes */ > @@ -15808,12 +15827,13 @@ intel_modeset_setup_hw_state(struct drm_device *dev, > struct drm_modeset_acquire_ctx *ctx) > { > struct drm_i915_private *dev_priv = to_i915(dev); > - struct intel_crtc *crtc; > struct intel_crtc_state *crtc_state; > struct intel_encoder *encoder; > + struct intel_crtc *crtc; Not that I mind but I don't understand the reasoning behind the change of order on this and on few other places in this patch. > + intel_wakeref_t wakeref; > int i; > > - intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); > > intel_early_display_was(dev_priv); > intel_modeset_readout_hw_state(dev); > @@ -15883,7 +15903,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev, > modeset_put_power_domains(dev_priv, put_domains); > } > > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref); > > intel_fbc_init_pipe_state(dev_priv); > } > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index d3cd40e656fe..fc85fd77a661 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -621,8 +621,8 @@ static void pps_unlock(struct intel_dp *intel_dp) > > mutex_unlock(&dev_priv->pps_mutex); > > - intel_display_power_put(dev_priv, > - intel_aux_power_domain(dp_to_dig_port(intel_dp))); > + intel_display_power_put_unchecked(dev_priv, > + intel_aux_power_domain(dp_to_dig_port(intel_dp))); > } > > static void > @@ -2511,8 +2511,8 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) > if ((pp & PANEL_POWER_ON) == 0) > intel_dp->panel_power_off_time = ktime_get_boottime(); > > - intel_display_power_put(dev_priv, > - intel_aux_power_domain(intel_dig_port)); > + intel_display_power_put_unchecked(dev_priv, > + intel_aux_power_domain(intel_dig_port)); > } > > static void edp_panel_vdd_work(struct work_struct *__work) > @@ -2657,7 +2657,7 @@ static void edp_panel_off(struct intel_dp *intel_dp) > intel_dp->panel_power_off_time = ktime_get_boottime(); > > /* We got a reference when we enabled the VDD. */ > - intel_display_power_put(dev_priv, intel_aux_power_domain(dig_port)); > + intel_display_power_put_unchecked(dev_priv, intel_aux_power_domain(dig_port)); > } > > void intel_edp_panel_off(struct intel_dp *intel_dp) > @@ -2983,16 +2983,18 @@ static bool intel_dp_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + intel_wakeref_t wakeref; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > ret = intel_dp_port_enabled(dev_priv, intel_dp->output_reg, > encoder->port, pipe); > > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return ret; > } > @@ -5365,12 +5367,13 @@ intel_dp_detect(struct drm_connector *connector, > enum drm_connector_status status; > enum intel_display_power_domain aux_domain = > intel_aux_power_domain(dig_port); > + intel_wakeref_t wakeref; > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > WARN_ON(!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex)); > > - intel_display_power_get(dev_priv, aux_domain); > + wakeref = intel_display_power_get(dev_priv, aux_domain); > > /* Can't disconnect eDP */ > if (intel_dp_is_edp(intel_dp)) > @@ -5436,7 +5439,7 @@ intel_dp_detect(struct drm_connector *connector, > > ret = intel_dp_retrain_link(encoder, ctx); > if (ret) { > - intel_display_power_put(dev_priv, aux_domain); > + intel_display_power_put(dev_priv, aux_domain, wakeref); > return ret; > } > } > @@ -5460,7 +5463,7 @@ intel_dp_detect(struct drm_connector *connector, > if (status != connector_status_connected && !intel_dp->is_mst) > intel_dp_unset_edid(intel_dp); > > - intel_display_power_put(dev_priv, aux_domain); > + intel_display_power_put(dev_priv, aux_domain, wakeref); > return status; > } > > @@ -5473,6 +5476,7 @@ intel_dp_force(struct drm_connector *connector) > struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); > enum intel_display_power_domain aux_domain = > intel_aux_power_domain(dig_port); > + intel_wakeref_t wakeref; > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > @@ -5481,11 +5485,11 @@ intel_dp_force(struct drm_connector *connector) > if (connector->status != connector_status_connected) > return; > > - intel_display_power_get(dev_priv, aux_domain); > + wakeref = intel_display_power_get(dev_priv, aux_domain); > > intel_dp_set_edid(intel_dp); > > - intel_display_power_put(dev_priv, aux_domain); > + intel_display_power_put(dev_priv, aux_domain, wakeref); > } > > static int intel_dp_get_modes(struct drm_connector *connector) > @@ -5931,6 +5935,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > struct intel_dp *intel_dp = &intel_dig_port->dp; > struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); > enum irqreturn ret = IRQ_NONE; > + intel_wakeref_t wakeref; > > if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { > /* > @@ -5953,8 +5958,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > return IRQ_NONE; > } > > - intel_display_power_get(dev_priv, > - intel_aux_power_domain(intel_dig_port)); > + wakeref = intel_display_power_get(dev_priv, > + intel_aux_power_domain(intel_dig_port)); > > if (intel_dp->is_mst) { > if (intel_dp_check_mst_status(intel_dp) == -EINVAL) { > @@ -5984,7 +5989,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) > > put_power: > intel_display_power_put(dev_priv, > - intel_aux_power_domain(intel_dig_port)); > + intel_aux_power_domain(intel_dig_port), > + wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_dpll_mgr.c b/drivers/gpu/drm/i915/intel_dpll_mgr.c > index d513ca875c67..04870e960537 100644 > --- a/drivers/gpu/drm/i915/intel_dpll_mgr.c > +++ b/drivers/gpu/drm/i915/intel_dpll_mgr.c > @@ -345,9 +345,12 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_dpll_hw_state *hw_state) > { > const enum intel_dpll_id id = pll->info->id; > + intel_wakeref_t wakeref; > uint32_t val; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > val = I915_READ(PCH_DPLL(id)); > @@ -355,7 +358,7 @@ static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, > hw_state->fp0 = I915_READ(PCH_FP0(id)); > hw_state->fp1 = I915_READ(PCH_FP1(id)); > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return val & DPLL_VCO_ENABLE; > } > @@ -509,15 +512,18 @@ static bool hsw_ddi_wrpll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_dpll_hw_state *hw_state) > { > const enum intel_dpll_id id = pll->info->id; > + intel_wakeref_t wakeref; > uint32_t val; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > val = I915_READ(WRPLL_CTL(id)); > hw_state->wrpll = val; > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return val & WRPLL_PLL_ENABLE; > } > @@ -526,15 +532,18 @@ static bool hsw_ddi_spll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_shared_dpll *pll, > struct intel_dpll_hw_state *hw_state) > { > + intel_wakeref_t wakeref; > uint32_t val; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > val = I915_READ(SPLL_CTL); > hw_state->spll = val; > > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return val & SPLL_PLL_ENABLE; > } > @@ -989,9 +998,12 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > uint32_t val; > const struct skl_dpll_regs *regs = skl_dpll_regs; > const enum intel_dpll_id id = pll->info->id; > + intel_wakeref_t wakeref; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > ret = false; > @@ -1011,7 +1023,7 @@ static bool skl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > ret = true; > > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return ret; > } > @@ -1020,12 +1032,15 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_shared_dpll *pll, > struct intel_dpll_hw_state *hw_state) > { > - uint32_t val; > const struct skl_dpll_regs *regs = skl_dpll_regs; > const enum intel_dpll_id id = pll->info->id; > + intel_wakeref_t wakeref; > + uint32_t val; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > ret = false; > @@ -1041,7 +1056,7 @@ static bool skl_ddi_dpll0_get_hw_state(struct drm_i915_private *dev_priv, > ret = true; > > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return ret; > } > @@ -1579,14 +1594,17 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_dpll_hw_state *hw_state) > { > enum port port = (enum port)pll->info->id; /* 1:1 port->PLL mapping */ > - uint32_t val; > - bool ret; > + intel_wakeref_t wakeref; > enum dpio_phy phy; > enum dpio_channel ch; > + uint32_t val; > + bool ret; > > bxt_port_to_phy_channel(dev_priv, port, &phy, &ch); > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > ret = false; > @@ -1643,7 +1661,7 @@ static bool bxt_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > ret = true; > > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return ret; > } > @@ -2091,10 +2109,13 @@ static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_dpll_hw_state *hw_state) > { > const enum intel_dpll_id id = pll->info->id; > + intel_wakeref_t wakeref; > uint32_t val; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > ret = false; > @@ -2113,7 +2134,7 @@ static bool cnl_ddi_pll_get_hw_state(struct drm_i915_private *dev_priv, > ret = true; > > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > > return ret; > } > @@ -2950,11 +2971,14 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv, > struct intel_dpll_hw_state *hw_state) > { > const enum intel_dpll_id id = pll->info->id; > - uint32_t val; > - enum port port; > + intel_wakeref_t wakeref; > bool ret = false; > + enum port port; > + uint32_t val; > > - if (!intel_display_power_get_if_enabled(dev_priv, POWER_DOMAIN_PLLS)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + POWER_DOMAIN_PLLS); > + if (!wakeref) > return false; > > val = I915_READ(icl_pll_id_to_enable_reg(id)); > @@ -3007,7 +3031,7 @@ static bool icl_pll_get_hw_state(struct drm_i915_private *dev_priv, > > ret = true; > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_PLLS, wakeref); > return ret; > } > > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 93c86b19700e..6fa1e6ff0e28 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -2118,12 +2118,21 @@ bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv, > enum intel_display_power_domain domain); > bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv, > enum intel_display_power_domain domain); > -void intel_display_power_get(struct drm_i915_private *dev_priv, > - enum intel_display_power_domain domain); > -bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, > +intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, > enum intel_display_power_domain domain); > +intel_wakeref_t > +intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain); > +void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain); > +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) > void intel_display_power_put(struct drm_i915_private *dev_priv, > - enum intel_display_power_domain domain); > + enum intel_display_power_domain domain, > + intel_wakeref_t wakeref); > +#else > +#define intel_display_power_put(i915, domain, wakeref) \ > + intel_display_power_put_unchecked(i915, domain) > +#endif > void icl_dbuf_slices_update(struct drm_i915_private *dev_priv, > u8 req_slices); > > diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h > index fc7a09049f81..df3d390e25fe 100644 > --- a/drivers/gpu/drm/i915/intel_dsi.h > +++ b/drivers/gpu/drm/i915/intel_dsi.h > @@ -39,6 +39,7 @@ struct intel_dsi { > struct intel_encoder base; > > struct intel_dsi_host *dsi_hosts[I915_MAX_PORTS]; > + intel_wakeref_t io_wakeref[I915_MAX_PORTS]; > > /* GPIO Desc for CRC based Panel control */ > struct gpio_desc *gpio_panel; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c > index 14a0c28fe7c1..14727ac06f67 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1190,15 +1190,17 @@ static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); > + intel_wakeref_t wakeref; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe); > > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return ret; > } > @@ -1895,11 +1897,12 @@ intel_hdmi_set_edid(struct drm_connector *connector) > { > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > + intel_wakeref_t wakeref; > struct edid *edid; > bool connected = false; > struct i2c_adapter *i2c; > > - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > > i2c = intel_gmbus_get_adapter(dev_priv, intel_hdmi->ddc_bus); > > @@ -1914,7 +1917,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) > > intel_hdmi_dp_dual_mode_detect(connector, edid != NULL); > > - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); > > to_intel_connector(connector)->detect_edid = edid; > if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { > @@ -1939,11 +1942,12 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > struct drm_i915_private *dev_priv = to_i915(connector->dev); > struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); > struct intel_encoder *encoder = &hdmi_to_dig_port(intel_hdmi)->base; > + intel_wakeref_t wakeref; > > DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", > connector->base.id, connector->name); > > - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > > if (IS_ICELAKE(dev_priv) && > !intel_digital_port_connected(encoder)) > @@ -1955,7 +1959,7 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) > status = connector_status_connected; > > out: > - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); > > if (status != connector_status_connected) > cec_notifier_phys_addr_invalidate(intel_hdmi->cec_notifier); > diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c > index c6159aff9dc8..4f6dc8c94634 100644 > --- a/drivers/gpu/drm/i915/intel_i2c.c > +++ b/drivers/gpu/drm/i915/intel_i2c.c > @@ -697,12 +697,13 @@ do_gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num, > static int > gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) > { > - struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus, > - adapter); > + struct intel_gmbus *bus = > + container_of(adapter, struct intel_gmbus, adapter); > struct drm_i915_private *dev_priv = bus->dev_priv; > + intel_wakeref_t wakeref; > int ret; > > - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > > if (bus->force_bit) { > ret = i2c_bit_algo.master_xfer(adapter, msgs, num); > @@ -714,17 +715,16 @@ gmbus_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) > bus->force_bit |= GMBUS_FORCE_BIT_RETRY; > } > > - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); > > return ret; > } > > int intel_gmbus_output_aksv(struct i2c_adapter *adapter) > { > - struct intel_gmbus *bus = container_of(adapter, struct intel_gmbus, > - adapter); > + struct intel_gmbus *bus = > + container_of(adapter, struct intel_gmbus, adapter); > struct drm_i915_private *dev_priv = bus->dev_priv; > - int ret; > u8 cmd = DRM_HDCP_DDC_AKSV; > u8 buf[DRM_HDCP_KSV_LEN] = { 0 }; > struct i2c_msg msgs[] = { > @@ -741,8 +741,10 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) > .buf = buf, > } > }; > + intel_wakeref_t wakeref; > + int ret; > > - intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS); > mutex_lock(&dev_priv->gmbus_mutex); > > /* > @@ -753,7 +755,7 @@ int intel_gmbus_output_aksv(struct i2c_adapter *adapter) > ret = do_gmbus_xfer(adapter, msgs, ARRAY_SIZE(msgs), GMBUS_AKSV_SELECT); > > mutex_unlock(&dev_priv->gmbus_mutex); > - intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS); > + intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c > index 6adcc8d037bf..b01aacb5d73d 100644 > --- a/drivers/gpu/drm/i915/intel_lvds.c > +++ b/drivers/gpu/drm/i915/intel_lvds.c > @@ -94,15 +94,17 @@ static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); > + intel_wakeref_t wakeref; > bool ret; > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > ret = intel_lvds_port_enabled(dev_priv, lvds_encoder->reg, pipe); > > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c > index bdabcfab8090..56d614b02302 100644 > --- a/drivers/gpu/drm/i915/intel_pipe_crc.c > +++ b/drivers/gpu/drm/i915/intel_pipe_crc.c > @@ -589,6 +589,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name) > struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[crtc->index]; > enum intel_display_power_domain power_domain; > enum intel_pipe_crc_source source; > + intel_wakeref_t wakeref; > u32 val = 0; /* shut up gcc */ > int ret = 0; > > @@ -598,7 +599,8 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name) > } > > power_domain = POWER_DOMAIN_PIPE(crtc->index); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) { > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) { > DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n"); > return -EIO; > } > @@ -624,7 +626,7 @@ int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name) > pipe_crc->skipped = 0; > > out: > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c > index 83b01cde8113..ab7257720c7e 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -3989,10 +3989,12 @@ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, > struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); > enum intel_display_power_domain power_domain; > enum pipe pipe = crtc->pipe; > + intel_wakeref_t wakeref; > enum plane_id plane_id; > > power_domain = POWER_DOMAIN_PIPE(pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return; > > for_each_plane_id_on_crtc(crtc, plane_id) > @@ -4001,7 +4003,7 @@ void skl_pipe_ddb_get_hw_state(struct intel_crtc *crtc, > &ddb_y[plane_id], > &ddb_uv[plane_id]); > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > } > > void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv, > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c > index f585ef742efe..fd2fc10dd1e4 100644 > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c > @@ -1867,18 +1867,19 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv, > * Any power domain reference obtained by this function must have a symmetric > * call to intel_display_power_put() to release the reference again. > */ > -void intel_display_power_get(struct drm_i915_private *dev_priv, > - enum intel_display_power_domain domain) > +intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain) > { > struct i915_power_domains *power_domains = &dev_priv->power_domains; > - > - intel_runtime_pm_get(dev_priv); > + intel_wakeref_t wakeref = intel_runtime_pm_get(dev_priv); > > mutex_lock(&power_domains->lock); > > __intel_display_power_get_domain(dev_priv, domain); > > mutex_unlock(&power_domains->lock); > + > + return wakeref; > } > > /** > @@ -1893,13 +1894,16 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, > * Any power domain reference obtained by this function must have a symmetric > * call to intel_display_power_put() to release the reference again. > */ > -bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, > - enum intel_display_power_domain domain) > +intel_wakeref_t > +intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain) > { > struct i915_power_domains *power_domains = &dev_priv->power_domains; > + intel_wakeref_t wakeref; > bool is_enabled; > > - if (!intel_runtime_pm_get_if_in_use(dev_priv)) > + wakeref = intel_runtime_pm_get_if_in_use(dev_priv); > + if (!wakeref) > return false; > > mutex_lock(&power_domains->lock); > @@ -1913,23 +1917,16 @@ bool intel_display_power_get_if_enabled(struct drm_i915_private *dev_priv, > > mutex_unlock(&power_domains->lock); > > - if (!is_enabled) > - intel_runtime_pm_put_unchecked(dev_priv); > + if (!is_enabled) { > + intel_runtime_pm_put(dev_priv, wakeref); > + wakeref = 0; > + } > > - return is_enabled; > + return wakeref; > } > > -/** > - * intel_display_power_put - release a power domain reference > - * @dev_priv: i915 device instance > - * @domain: power domain to reference > - * > - * This function drops the power domain reference obtained by > - * intel_display_power_get() and might power down the corresponding hardware > - * block right away if this is the last reference. > - */ > -void intel_display_power_put(struct drm_i915_private *dev_priv, > - enum intel_display_power_domain domain) > +static void __intel_display_power_put(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain) > { > struct i915_power_domains *power_domains; > struct i915_power_well *power_well; > @@ -1947,10 +1944,34 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, > intel_power_well_put(dev_priv, power_well); > > mutex_unlock(&power_domains->lock); > +} > > +/** > + * intel_display_power_put - release a power domain reference +unchecked? or is this in wrong place. And the perf oa_config unrelated changes are gone. Good. -Mika > + * @dev_priv: i915 device instance > + * @domain: power domain to reference > + * > + * This function drops the power domain reference obtained by > + * intel_display_power_get() and might power down the corresponding hardware > + * block right away if this is the last reference. > + */ > +void intel_display_power_put_unchecked(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain) > +{ > + __intel_display_power_put(dev_priv, domain); > intel_runtime_pm_put_unchecked(dev_priv); > } > > +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) > +void intel_display_power_put(struct drm_i915_private *dev_priv, > + enum intel_display_power_domain domain, > + intel_wakeref_t wakeref) > +{ > + __intel_display_power_put(dev_priv, domain); > + intel_runtime_pm_put(dev_priv, wakeref); > +} > +#endif > + > #define I830_PIPES_POWER_DOMAINS ( \ > BIT_ULL(POWER_DOMAIN_PIPE_A) | \ > BIT_ULL(POWER_DOMAIN_PIPE_B) | \ > @@ -4060,7 +4081,7 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv) > > /* Remove the refcount we took to keep power well support disabled. */ > if (!i915_modparams.disable_power_well) > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); > > intel_power_domains_verify_state(dev_priv); > } > @@ -4079,7 +4100,7 @@ void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv) > */ > void intel_power_domains_enable(struct drm_i915_private *dev_priv) > { > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); > > intel_power_domains_verify_state(dev_priv); > } > @@ -4114,7 +4135,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, > { > struct i915_power_domains *power_domains = &dev_priv->power_domains; > > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); > > /* > * In case of suspend-to-idle (aka S0ix) on a DMC platform without DC9 > @@ -4135,7 +4156,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, > * power wells if power domains must be deinitialized for suspend. > */ > if (!i915_modparams.disable_power_well) { > - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); > + intel_display_power_put_unchecked(dev_priv, POWER_DOMAIN_INIT); > intel_power_domains_verify_state(dev_priv); > } > > diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c > index 8f3982c03925..87a06fcca284 100644 > --- a/drivers/gpu/drm/i915/intel_sprite.c > +++ b/drivers/gpu/drm/i915/intel_sprite.c > @@ -618,17 +618,19 @@ skl_plane_get_hw_state(struct intel_plane *plane, > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > enum plane_id plane_id = plane->id; > + intel_wakeref_t wakeref; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE; > > *pipe = plane->pipe; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -882,17 +884,19 @@ vlv_plane_get_hw_state(struct intel_plane *plane, > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > enum plane_id plane_id = plane->id; > + intel_wakeref_t wakeref; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE; > > *pipe = plane->pipe; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -1051,17 +1055,19 @@ ivb_plane_get_hw_state(struct intel_plane *plane, > { > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > ret = I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE; > > *pipe = plane->pipe; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > @@ -1217,17 +1223,19 @@ g4x_plane_get_hw_state(struct intel_plane *plane, > { > struct drm_i915_private *dev_priv = to_i915(plane->base.dev); > enum intel_display_power_domain power_domain; > + intel_wakeref_t wakeref; > bool ret; > > power_domain = POWER_DOMAIN_PIPE(plane->pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return false; > > ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE; > > *pipe = plane->pipe; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return ret; > } > diff --git a/drivers/gpu/drm/i915/intel_vdsc.c b/drivers/gpu/drm/i915/intel_vdsc.c > index 48537827616f..23abf03736e7 100644 > --- a/drivers/gpu/drm/i915/intel_vdsc.c > +++ b/drivers/gpu/drm/i915/intel_vdsc.c > @@ -1082,6 +1082,6 @@ void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state) > I915_WRITE(dss_ctl2_reg, dss_ctl2_val); > > /* Disable Power wells for VDSC/joining */ > - intel_display_power_put(dev_priv, > - intel_dsc_power_domain(old_crtc_state)); > + intel_display_power_put_unchecked(dev_priv, > + intel_dsc_power_domain(old_crtc_state)); > } > diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c > index bb1287020f80..d116fead8514 100644 > --- a/drivers/gpu/drm/i915/vlv_dsi.c > +++ b/drivers/gpu/drm/i915/vlv_dsi.c > @@ -959,13 +959,15 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, > { > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); > struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); > + intel_wakeref_t wakeref; > enum port port; > bool active = false; > > DRM_DEBUG_KMS("\n"); > > - if (!intel_display_power_get_if_enabled(dev_priv, > - encoder->power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, > + encoder->power_domain); > + if (!wakeref) > return false; > > /* > @@ -1021,7 +1023,7 @@ static bool intel_dsi_get_hw_state(struct intel_encoder *encoder, > } > > out_put_power: > - intel_display_power_put(dev_priv, encoder->power_domain); > + intel_display_power_put(dev_priv, encoder->power_domain, wakeref); > > return active; > } > @@ -1574,6 +1576,7 @@ vlv_dsi_get_hw_panel_orientation(struct intel_connector *connector) > enum drm_panel_orientation orientation; > struct intel_plane *plane; > struct intel_crtc *crtc; > + intel_wakeref_t wakeref; > enum pipe pipe; > u32 val; > > @@ -1584,7 +1587,8 @@ vlv_dsi_get_hw_panel_orientation(struct intel_connector *connector) > plane = to_intel_plane(crtc->base.primary); > > power_domain = POWER_DOMAIN_PIPE(pipe); > - if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain); > + if (!wakeref) > return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; > > val = I915_READ(DSPCNTR(plane->i9xx_plane)); > @@ -1596,7 +1600,7 @@ vlv_dsi_get_hw_panel_orientation(struct intel_connector *connector) > else > orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; > > - intel_display_power_put(dev_priv, power_domain); > + intel_display_power_put(dev_priv, power_domain, wakeref); > > return orientation; > } > -- > 2.20.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx