]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/display: move unordered works to new private workqueue
authorLuca Coelho <luciano.coelho@intel.com>
Fri, 20 Jun 2025 09:15:30 +0000 (12:15 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Thu, 26 Jun 2025 09:22:51 +0000 (12:22 +0300)
Create a new unordered workqueue to be used by the display code
instead of relying on the i915 one.  Then move all the unordered works
used in the display code to use this new queue.

Since this is an unordered workqueue, by definition there can't be any
order dependency with non-display works, so no extra care is needed
in regard to that.

This is part of the effort to isolate the display code from i915.

Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Link: https://lore.kernel.org/r/20250620091632.1256135-1-luciano.coelho@intel.com
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
13 files changed:
drivers/gpu/drm/i915/display/intel_connector.c
drivers/gpu/drm/i915/display/intel_display_core.h
drivers/gpu/drm/i915/display/intel_display_driver.c
drivers/gpu/drm/i915/display/intel_dmc.c
drivers/gpu/drm/i915/display/intel_dmc_wl.c
drivers/gpu/drm/i915/display/intel_drrs.c
drivers/gpu/drm/i915/display/intel_encoder.c
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_hdcp.c
drivers/gpu/drm/i915/display/intel_hotplug.c
drivers/gpu/drm/i915/display/intel_opregion.c
drivers/gpu/drm/i915/display/intel_pps.c
drivers/gpu/drm/i915/display/intel_psr.c

index 2867d76d1a5ea1c8104af63ad7bfc4fe032b948c..42c923f416b326aba770a67f2a375b0a4f948949 100644 (file)
@@ -64,10 +64,10 @@ static void intel_connector_modeset_retry_work_fn(struct work_struct *work)
 
 void intel_connector_queue_modeset_retry_work(struct intel_connector *connector)
 {
-       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_display *display = to_intel_display(connector);
 
        drm_connector_get(&connector->base);
-       if (!queue_work(i915->unordered_wq, &connector->modeset_retry_work))
+       if (!queue_work(display->wq.unordered, &connector->modeset_retry_work))
                drm_connector_put(&connector->base);
 }
 
index 32cb0e59c81ea64a8f30adb90a4c9d13c8deb87d..25b497280086d40317c399a4c356ff7b88c0ece8 100644 (file)
@@ -570,6 +570,9 @@ struct intel_display {
 
                /* hipri wq for commit cleanups */
                struct workqueue_struct *cleanup;
+
+               /* unordered workqueue for all display unordered work */
+               struct workqueue_struct *unordered;
        } wq;
 
        /* Grouping using named structs. Keep sorted. */
index 9058c23dd4875f8ab0bf8508e9b8bd804fe26edd..e26216037e9c3081edd7cab5f198c7656db3525c 100644 (file)
@@ -236,8 +236,6 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
        if (!HAS_DISPLAY(display))
                return 0;
 
-       intel_dmc_init(display);
-
        display->hotplug.dp_wq = alloc_ordered_workqueue("intel-dp", 0);
        if (!display->hotplug.dp_wq) {
                ret = -ENOMEM;
@@ -263,27 +261,35 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
                goto cleanup_wq_flip;
        }
 
+       display->wq.unordered = alloc_workqueue("display_unordered", 0, 0);
+       if (!display->wq.unordered) {
+               ret = -ENOMEM;
+               goto cleanup_wq_cleanup;
+       }
+
+       intel_dmc_init(display);
+
        intel_mode_config_init(display);
 
        ret = intel_cdclk_init(display);
        if (ret)
-               goto cleanup_wq_cleanup;
+               goto cleanup_wq_unordered;
 
        ret = intel_color_init(display);
        if (ret)
-               goto cleanup_wq_cleanup;
+               goto cleanup_wq_unordered;
 
        ret = intel_dbuf_init(display);
        if (ret)
-               goto cleanup_wq_cleanup;
+               goto cleanup_wq_unordered;
 
        ret = intel_bw_init(display);
        if (ret)
-               goto cleanup_wq_cleanup;
+               goto cleanup_wq_unordered;
 
        ret = intel_pmdemand_init(display);
        if (ret)
-               goto cleanup_wq_cleanup;
+               goto cleanup_wq_unordered;
 
        intel_init_quirks(display);
 
@@ -291,6 +297,8 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
 
        return 0;
 
+cleanup_wq_unordered:
+       destroy_workqueue(display->wq.unordered);
 cleanup_wq_cleanup:
        destroy_workqueue(display->wq.cleanup);
 cleanup_wq_flip:
@@ -594,6 +602,7 @@ void intel_display_driver_remove(struct intel_display *display)
        flush_workqueue(display->wq.flip);
        flush_workqueue(display->wq.modeset);
        flush_workqueue(display->wq.cleanup);
+       flush_workqueue(display->wq.unordered);
 
        /*
         * MST topology needs to be suspended so we don't have any calls to
@@ -606,8 +615,6 @@ void intel_display_driver_remove(struct intel_display *display)
 /* part #2: call after irq uninstall */
 void intel_display_driver_remove_noirq(struct intel_display *display)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
-
        if (!HAS_DISPLAY(display))
                return;
 
@@ -622,7 +629,7 @@ void intel_display_driver_remove_noirq(struct intel_display *display)
        intel_unregister_dsm_handler();
 
        /* flush any delayed tasks or pending work */
-       flush_workqueue(i915->unordered_wq);
+       flush_workqueue(display->wq.unordered);
 
        intel_hdcp_component_fini(display);
 
@@ -638,6 +645,7 @@ void intel_display_driver_remove_noirq(struct intel_display *display)
        destroy_workqueue(display->wq.flip);
        destroy_workqueue(display->wq.modeset);
        destroy_workqueue(display->wq.cleanup);
+       destroy_workqueue(display->wq.unordered);
 
        intel_fbc_cleanup(display);
 }
index 4572e87d9bfa0bc7e23e8ab30de0cf66229a26a9..14625418a558846c77a0a0f9bffa45875a10be30 100644 (file)
@@ -1298,7 +1298,6 @@ out:
  */
 void intel_dmc_init(struct intel_display *display)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
        struct intel_dmc *dmc;
 
        if (!HAS_DMC(display))
@@ -1341,7 +1340,7 @@ void intel_dmc_init(struct intel_display *display)
        display->dmc.dmc = dmc;
 
        drm_dbg_kms(display->drm, "Loading %s\n", dmc->fw_path);
-       queue_work(i915->unordered_wq, &dmc->work);
+       queue_work(display->wq.unordered, &dmc->work);
 
        return;
 
index 44b3ee5c9be4c2674abc297b97ddbe4e7cbbf758..d8a04a98dd7cab9c06a7af227b5cf14de8aeab1b 100644 (file)
@@ -155,12 +155,11 @@ static const struct intel_dmc_wl_range xe3lpd_dc3co_dmc_ranges[] = {
 
 static void __intel_dmc_wl_release(struct intel_display *display)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
        struct intel_dmc_wl *wl = &display->wl;
 
        WARN_ON(refcount_read(&wl->refcount));
 
-       queue_delayed_work(i915->unordered_wq, &wl->work,
+       queue_delayed_work(display->wq.unordered, &wl->work,
                           msecs_to_jiffies(DMC_WAKELOCK_HOLD_TIME));
 }
 
index 3fa94510458d1b24b9ebbb4db695e4ca912f82f1..3e775bb1b57a939f39ce90a874cbc37ff16397dd 100644 (file)
@@ -123,9 +123,9 @@ static void intel_drrs_set_state(struct intel_crtc *crtc,
 
 static void intel_drrs_schedule_work(struct intel_crtc *crtc)
 {
-       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+       struct intel_display *display = to_intel_display(crtc);
 
-       mod_delayed_work(i915->unordered_wq, &crtc->drrs.work, msecs_to_jiffies(1000));
+       mod_delayed_work(display->wq.unordered, &crtc->drrs.work, msecs_to_jiffies(1000));
 }
 
 static unsigned int intel_drrs_frontbuffer_bits(const struct intel_crtc_state *crtc_state)
index bad452ad979a85f3374c3ac4957643638ec8bd95..283187905d0b3d2cf79721d3ef7ae833ed0c07a9 100644 (file)
@@ -32,9 +32,9 @@ void intel_encoder_link_check_flush_work(struct intel_encoder *encoder)
 
 void intel_encoder_link_check_queue_work(struct intel_encoder *encoder, int delay_ms)
 {
-       struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+       struct intel_display *display = to_i915(encoder->base.dev)->display;
 
-       mod_delayed_work(i915->unordered_wq,
+       mod_delayed_work(display->wq.unordered,
                         &encoder->link_check_work, msecs_to_jiffies(delay_ms));
 }
 
index 5d28a6062db13f31848fecebd9e33b6393587373..6e26cb4c57243ec3d384b35f9aa4a901356e4228 100644 (file)
@@ -2011,7 +2011,7 @@ void intel_fbc_reset_underrun(struct intel_display *display)
 
 static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
 {
-       struct drm_i915_private *i915 = to_i915(fbc->display->drm);
+       struct intel_display *display = fbc->display;
 
        /*
         * There's no guarantee that underrun_detected won't be set to true
@@ -2024,7 +2024,7 @@ static void __intel_fbc_handle_fifo_underrun_irq(struct intel_fbc *fbc)
        if (READ_ONCE(fbc->underrun_detected))
                return;
 
-       queue_work(i915->unordered_wq, &fbc->underrun_work);
+       queue_work(display->wq.unordered, &fbc->underrun_work);
 }
 
 /**
index d5cb8698f00aa79943cdca2ba2e04b497d7c3414..619ccfc3300091a53ab632aec82f471e300b9344 100644 (file)
@@ -1088,7 +1088,6 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
                                    u64 value, bool update_property)
 {
        struct intel_display *display = to_intel_display(connector);
-       struct drm_i915_private *i915 = to_i915(display->drm);
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
        struct intel_hdcp *hdcp = &connector->hdcp;
 
@@ -1109,7 +1108,7 @@ static void intel_hdcp_update_value(struct intel_connector *connector,
        hdcp->value = value;
        if (update_property) {
                drm_connector_get(&connector->base);
-               if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+               if (!queue_work(display->wq.unordered, &hdcp->prop_work))
                        drm_connector_put(&connector->base);
        }
 }
@@ -2236,16 +2235,15 @@ static void intel_hdcp_check_work(struct work_struct *work)
                                               check_work);
        struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
        struct intel_display *display = to_intel_display(connector);
-       struct drm_i915_private *i915 = to_i915(display->drm);
 
        if (drm_connector_is_unregistered(&connector->base))
                return;
 
        if (!intel_hdcp2_check_link(connector))
-               queue_delayed_work(i915->unordered_wq, &hdcp->check_work,
+               queue_delayed_work(display->wq.unordered, &hdcp->check_work,
                                   DRM_HDCP2_CHECK_PERIOD_MS);
        else if (!intel_hdcp_check_link(connector))
-               queue_delayed_work(i915->unordered_wq, &hdcp->check_work,
+               queue_delayed_work(display->wq.unordered, &hdcp->check_work,
                                   DRM_HDCP_CHECK_PERIOD_MS);
 }
 
@@ -2436,7 +2434,6 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
                              const struct drm_connector_state *conn_state)
 {
        struct intel_display *display = to_intel_display(encoder);
-       struct drm_i915_private *i915 = to_i915(display->drm);
        struct intel_connector *connector =
                to_intel_connector(conn_state->connector);
        struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
@@ -2495,7 +2492,7 @@ static int _intel_hdcp_enable(struct intel_atomic_state *state,
        }
 
        if (!ret) {
-               queue_delayed_work(i915->unordered_wq, &hdcp->check_work,
+               queue_delayed_work(display->wq.unordered, &hdcp->check_work,
                                   check_link_interval);
                intel_hdcp_update_value(connector,
                                        DRM_MODE_CONTENT_PROTECTION_ENABLED,
@@ -2566,7 +2563,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                                to_intel_connector(conn_state->connector);
        struct intel_hdcp *hdcp = &connector->hdcp;
        bool content_protection_type_changed, desired_and_not_enabled = false;
-       struct drm_i915_private *i915 = to_i915(connector->base.dev);
+       struct intel_display *display = to_intel_display(connector);
 
        if (!connector->hdcp.shim)
                return;
@@ -2593,7 +2590,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                mutex_lock(&hdcp->mutex);
                hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
                drm_connector_get(&connector->base);
-               if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+               if (!queue_work(display->wq.unordered, &hdcp->prop_work))
                        drm_connector_put(&connector->base);
                mutex_unlock(&hdcp->mutex);
        }
@@ -2611,7 +2608,7 @@ void intel_hdcp_update_pipe(struct intel_atomic_state *state,
                 */
                if (!desired_and_not_enabled && !content_protection_type_changed) {
                        drm_connector_get(&connector->base);
-                       if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+                       if (!queue_work(display->wq.unordered, &hdcp->prop_work))
                                drm_connector_put(&connector->base);
 
                }
@@ -2735,7 +2732,6 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
 {
        struct intel_hdcp *hdcp = &connector->hdcp;
        struct intel_display *display = to_intel_display(connector);
-       struct drm_i915_private *i915 = to_i915(display->drm);
 
        if (!hdcp->shim)
                return;
@@ -2743,7 +2739,7 @@ void intel_hdcp_handle_cp_irq(struct intel_connector *connector)
        atomic_inc(&connector->hdcp.cp_irq_count);
        wake_up_all(&connector->hdcp.cp_irq_queue);
 
-       queue_delayed_work(i915->unordered_wq, &hdcp->check_work, 0);
+       queue_delayed_work(display->wq.unordered, &hdcp->check_work, 0);
 }
 
 static void __intel_hdcp_info(struct seq_file *m, struct intel_connector *connector,
index 901fda434af125161a376a9fcfb22950650d3013..265aa97fcc750ff130630a2f0c019bf7ab274e4b 100644 (file)
@@ -193,40 +193,34 @@ static bool detection_work_enabled(struct intel_display *display)
 static bool
 mod_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
-
        lockdep_assert_held(&display->irq.lock);
 
        if (!detection_work_enabled(display))
                return false;
 
-       return mod_delayed_work(i915->unordered_wq, work, delay);
+       return mod_delayed_work(display->wq.unordered, work, delay);
 }
 
 static bool
 queue_delayed_detection_work(struct intel_display *display, struct delayed_work *work, int delay)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
-
        lockdep_assert_held(&display->irq.lock);
 
        if (!detection_work_enabled(display))
                return false;
 
-       return queue_delayed_work(i915->unordered_wq, work, delay);
+       return queue_delayed_work(display->wq.unordered, work, delay);
 }
 
 static bool
 queue_detection_work(struct intel_display *display, struct work_struct *work)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
-
        lockdep_assert_held(&display->irq.lock);
 
        if (!detection_work_enabled(display))
                return false;
 
-       return queue_work(i915->unordered_wq, work);
+       return queue_work(display->wq.unordered, work);
 }
 
 static void
index 5535cb7994317bcde112419eb5edf147f9927373..2b8538fcfd1dddfafaeaa5024aba580c9567c13f 100644 (file)
@@ -665,11 +665,10 @@ bool intel_opregion_asle_present(struct intel_display *display)
 
 void intel_opregion_asle_intr(struct intel_display *display)
 {
-       struct drm_i915_private *i915 = to_i915(display->drm);
        struct intel_opregion *opregion = display->opregion;
 
        if (opregion && opregion->asle)
-               queue_work(i915->unordered_wq, &opregion->asle_work);
+               queue_work(display->wq.unordered, &opregion->asle_work);
 }
 
 #define ACPI_EV_DISPLAY_SWITCH (1<<0)
index bff81fb5c316a92c42d8137c483c5d0f11825245..6caafa66e7b4b8e3aed2a5d7f6ab7317f0eb5669 100644 (file)
@@ -892,7 +892,6 @@ static void edp_panel_vdd_work(struct work_struct *__work)
 static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
 {
        struct intel_display *display = to_intel_display(intel_dp);
-       struct drm_i915_private *i915 = to_i915(display->drm);
        unsigned long delay;
 
        /*
@@ -908,7 +907,7 @@ static void edp_panel_vdd_schedule_off(struct intel_dp *intel_dp)
         * operations.
         */
        delay = msecs_to_jiffies(intel_dp->pps.panel_power_cycle_delay * 5);
-       queue_delayed_work(i915->unordered_wq,
+       queue_delayed_work(display->wq.unordered,
                           &intel_dp->pps.panel_vdd_work, delay);
 }
 
index 8bee2f592ae7de3d6443b29708e68e03c51e7e6f..f7837e17c59dfa29514af3b4fb7988aaec73dfbf 100644 (file)
@@ -448,7 +448,6 @@ static void psr_event_print(struct intel_display *display,
 void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
 {
        struct intel_display *display = to_intel_display(intel_dp);
-       struct drm_i915_private *dev_priv = to_i915(display->drm);
        enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
        ktime_t time_ns =  ktime_get();
 
@@ -493,7 +492,7 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
                intel_de_rmw(display, psr_imr_reg(display, cpu_transcoder),
                             0, psr_irq_psr_error_bit_get(intel_dp));
 
-               queue_work(dev_priv->unordered_wq, &intel_dp->psr.work);
+               queue_work(display->wq.unordered, &intel_dp->psr.work);
        }
 }
 
@@ -3320,7 +3319,6 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
                       enum fb_op_origin origin)
 {
        struct intel_display *display = to_intel_display(intel_dp);
-       struct drm_i915_private *i915 = to_i915(display->drm);
 
        if (!intel_dp->psr.dc3co_exitline || !intel_dp->psr.sel_update_enabled ||
            !intel_dp->psr.active)
@@ -3335,14 +3333,13 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
                return;
 
        tgl_psr2_enable_dc3co(intel_dp);
-       mod_delayed_work(i915->unordered_wq, &intel_dp->psr.dc3co_work,
+       mod_delayed_work(display->wq.unordered, &intel_dp->psr.dc3co_work,
                         intel_dp->psr.dc3co_exit_delay);
 }
 
 static void _psr_flush_handle(struct intel_dp *intel_dp)
 {
        struct intel_display *display = to_intel_display(intel_dp);
-       struct drm_i915_private *dev_priv = to_i915(display->drm);
 
        if (intel_dp->psr.psr2_sel_fetch_enabled) {
                if (intel_dp->psr.psr2_sel_fetch_cff_enabled) {
@@ -3367,7 +3364,7 @@ static void _psr_flush_handle(struct intel_dp *intel_dp)
 
        if (!intel_dp->psr.psr2_sel_fetch_enabled && !intel_dp->psr.active &&
            !intel_dp->psr.busy_frontbuffer_bits)
-               queue_work(dev_priv->unordered_wq, &intel_dp->psr.work);
+               queue_work(display->wq.unordered, &intel_dp->psr.work);
 }
 
 /**