]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/i915: Markup paired operations on display power domains
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 14 Jan 2019 14:21:24 +0000 (14:21 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 14 Jan 2019 16:18:30 +0000 (16:18 +0000)
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@chris-wilson.co.uk>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190114142129.24398-16-chris@chris-wilson.co.uk
23 files changed:
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/icl_dsi.c
drivers/gpu/drm/i915/intel_audio.c
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_csr.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_dpll_mgr.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_dsi.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_i2c.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_pipe_crc.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/i915/intel_runtime_pm.c
drivers/gpu/drm/i915/intel_sprite.c
drivers/gpu/drm/i915/intel_vdsc.c
drivers/gpu/drm/i915/vlv_dsi.c

index 1c7913b40bb719084f550d8eb92094eabb8946ac..e846608ee6aa6b916dfd144730a42f75ae1a1203 100644 (file)
@@ -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;
+
                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));
 
index b6d0cd890a19671e3d356baef551677bb043cd64..0aedbb88eb5b0f5b14b6bd256d0f0a8ba65b3603 100644 (file)
@@ -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;
 
                /**
                 * The number of times we have woken up.
index f5e2456c4f73097cb841a49834bd764a0a9deed0..abbca28f4cff9a4201f9e9813bef9ac802d67b17 100644 (file)
@@ -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;
index 4dd793b789962873a3523222336ba7a5d99a0677..f3a5f03646ce8029f36e012234e65f1af6ac4a20 100644 (file)
@@ -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);
+               }
+       }
 
        /* 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;
 }
 
index 202a58cf2d9f3016fa740062ab55cf2127b28515..de26cd0a54979672aadec40c1738e207da5a6afd 100644 (file)
@@ -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,
index 2021e484a2872dfeec109d580ee3fc9f26070577..73cb7250118ebda1316b95fd0aeffcce43a6ce4a 100644 (file)
@@ -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)
index 951e9bae6921992a8cfc12fda26b1595690fb250..33bd2addcbdd929a2cbba4ee898de0f55ade3a7d 100644 (file)
@@ -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 @@ load_detect:
        }
 
 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;
 }
index a516697bf57dfc8d63434b95d3f15aaaff748c21..ea5fb64d33ddafa31062dc62ee8f606c8d63c681 100644 (file)
@@ -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);
 }
index 2d6ed990a2327d2e1cad08517ec125e7f55b1c12..7f3cd055de5071813c65a0771803977777f62f4e 100644 (file)
@@ -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 @@ out:
                                  "(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)
index b0b8f9ffd873e105c675f709bd951dd3915d34fe..36c56d1637b8cdf883c2a1c407eb39750494a842 100644 (file)
@@ -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;
+       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);
 }
index d3cd40e656fe14ac01c1bcf0cf4405893f35480b..fc85fd77a661447ca410da18ca996b724b90a906 100644 (file)
@@ -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 @@ out:
        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;
 }
index d513ca875c67693cf508c389367febdd3ae320d0..04870e960537c6486c250bb4e99cbe189acb99f8 100644 (file)
@@ -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;
 }
 
index 71377ec49a10b37abf09171c140e2491c247b7d7..5e5ceec7c0048b404272e99daad3a19c40017ff2 100644 (file)
@@ -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);
 
index fc7a09049f819dbebb9481a943a221f66419388d..df3d390e25febc5e6157d6772197368092ecfcba 100644 (file)
@@ -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;
index 14a0c28fe7c12c0158ade16952219b072b92edb0..14727ac06f67592265f63ab71120d100823c078e 100644 (file)
@@ -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);
index c6159aff9dc8d288c8d7b3a1bf7f88bbaa0d35ed..4f6dc8c94634e543fcc3cddef733ed7160c19304 100644 (file)
@@ -697,12 +697,13 @@ out:
 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;
 }
index 6adcc8d037bff2a0efa76c50aef1d8f379f49355..b01aacb5d73de09aae9e8d1ff9f6386261942451 100644 (file)
@@ -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;
 }
index bdabcfab8090f75a8262e47ee9d05ec15b9aa25e..56d614b0230230989f53d4ac6721fe86f1a0df61 100644 (file)
@@ -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;
 }
index 83b01cde8113ddc17619bfa352a3f227b2cae407..ab7257720c7edf5b7b6631b236b20928a62364ea 100644 (file)
@@ -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,
index c29577d7a35a36987ee00781d39e01923f5111b4..6aeceab37000121ff174d1c4af988fc5994f6ac3 100644 (file)
@@ -1855,18 +1855,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;
 }
 
 /**
@@ -1881,13 +1882,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);
@@ -1901,23 +1905,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;
@@ -1935,10 +1932,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
+ * @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) |          \
@@ -4048,7 +4069,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);
 }
@@ -4067,7 +4088,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);
 }
@@ -4102,7 +4123,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
@@ -4123,7 +4144,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);
        }
 
index 8f3982c03925a63cc51c6202853c94e1aeaaea85..87a06fcca284dbf746e851be540d81f51e80e877 100644 (file)
@@ -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;
 }
index 48537827616fa9a9700e5fad06a0942af1bf9200..23abf03736e7262cba70668e7eba9217fbeb3a75 100644 (file)
@@ -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));
 }
index bb1287020f80abb099a1ad5b50dd239f5c97db71..d116fead8514ac30aec3b9380cc91740e81e4a68 100644 (file)
@@ -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;
 }