Hello maintainers,
This series addresses a defect observed on certain hardware platforms using Linux kernel 6.1.147 with the i915 driver. The issue concerns hot plug detection (HPD) logic, leading to unreliable or missed detection events on affected hardware. This is happening on some specific devices.
### Background
Issue: On Simatic IPC227E, we observed unreliable or missing hot plug detection events, while on Simatic IPC227G (otherwise similar platform), expected hot plug behavior was maintained. Affected kernel: This patch series is intended for the Linux 6.1.y stable tree only (tested on 6.1.147) Most of the tests were conducted on 6.1.147 (manual/standalone kernel build, CIP/Isar context). Root cause analysis: I do not have access to hardware signal traces or scope data to conclusively prove the root cause at electrical level. My understanding is based on observed driver behavior and logs. Therefore my assumption as to the real cause is that on IPC227G, HPD IRQ storms are apparently not occurring, so the standard HPD IRQ-based detection works as expected. On IPC227E, frequent HPD interrupts trigger the i915 driver’s storm detection logic, causing it to switch to polling mode. Therefore polling does not resume correctly, leading to the hotplug issue this series addresses. Device IPC227E's behavior triggers this kernel edge case, likely due to slight variations in signal integrity, electrical margins, or internal component timing. Device IPC227G, functions as expected, possibly due to cleaner electrical signaling or more optimal timing characteristics, thus avoiding the triggering condition. Conclusion: This points to a hardware-software interaction where kernel code assumes nicer signaling or margins than IPC227E is able to provide, exposing logic gaps not visible on more robust hardware.
### Patches
Patches 1-4: - Partial backports of upstream commits; only the relevant logic or fixes are applied, with other code omitted due to downstream divergence. - Applied minimal merging without exhaustive backport of all intermediate upstream changes. Patch 5: - Contains cherry-picked logic plus context/compatibility amendments as needed. Ensures that the driver builds. - Together these fixes greatly improve reliability of hotplug detection on both devices, with no regression detected in our setups.
Thank you for your review, Nicusor Huhulea
This patch series contains the following changes:
Dmitry Baryshkov (2): drm/probe_helper: extract two helper functions drm/probe-helper: enable and disable HPD on connectors
Imre Deak (2): drm/i915: Fix HPD polling, reenabling the output poll work as needed drm: Add an HPD poll helper to reschedule the poll work
Nicusor Huhulea (1): drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
drivers/gpu/drm/drm_probe_helper.c | 127 ++++++++++++++----- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 +- include/drm/drm_modeset_helper_vtables.h | 22 ++++ include/drm/drm_probe_helper.h | 1 + 4 files changed, 122 insertions(+), 32 deletions(-)
From: Imre Deak imre.deak@intel.com
commit 50452f2f76852322620b63e62922b85e955abe94 upstream.
While this commit is not a direct cherry-pick, the critical fix(two lines) was adapted and applied.
After the commit in the Fixes: line below, HPD polling stopped working on i915, since after that change calling drm_kms_helper_poll_enable() doesn't restart drm_mode_config::output_poll_work if the work was stopped (no connectors needing polling) and enabling polling for a connector (during runtime suspend or detecting an HPD IRQ storm).
After the above change calling drm_kms_helper_poll_enable() is a nop after it's been called already and polling for some connectors was disabled/re-enabled.
Fix this by calling drm_kms_helper_poll_reschedule() added in the previous patch instead, which reschedules the work whenever expected.
Fixes: d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled") Cc: stable@vger.kernel.org # 6.4+ Cc: Dmitry Baryshkov dmitry.baryshkov@linaro.org Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jouni Högander jouni.hogander@intel.com Signed-off-by: Imre Deak imre.deak@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230822113015.41224-2-imre.de... Signed-off-by: Nicusor Huhulea nicusor.huhulea@siemens.com --- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index f7a2f485b177..6ba2d7b0cd1b 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -208,7 +208,7 @@ intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
/* Enable polling and queue hotplug re-enabling. */ if (hpd_disabled) { - drm_kms_helper_poll_enable(dev); + drm_kms_helper_poll_reschedule(&dev_priv->drm); mod_delayed_work(system_wq, &dev_priv->display.hotplug.reenable_work, msecs_to_jiffies(HPD_STORM_REENABLE_DELAY)); } @@ -638,7 +638,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) drm_connector_list_iter_end(&conn_iter);
if (enabled) - drm_kms_helper_poll_enable(dev); + drm_kms_helper_poll_reschedule(&dev_priv->drm);
mutex_unlock(&dev->mode_config.mutex);
From: Imre Deak imre.deak@intel.com
commit fe2352fd64029918174de4b460dfe6df0c6911cd upstream
This is not a clean cherry-pick due to code divergence.
Add a helper to reschedule drm_mode_config::output_poll_work after polling has been enabled for a connector (and needing a reschedule, since previously polling was disabled for all connectors and hence output_poll_work was not running).
This is needed by the next patch fixing HPD polling on i915.
Cc: stable@vger.kernel.org # 6.4+ Cc: Dmitry Baryshkov dmitry.baryshkov@linaro.org Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jouni Högander jouni.hogander@intel.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Signed-off-by: Imre Deak imre.deak@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20230822113015.41224-1-imre.de... Signed-off-by: Nicusor Huhulea nicusor.huhulea@siemens.com --- drivers/gpu/drm/drm_probe_helper.c | 74 +++++++++++++++++++----------- include/drm/drm_probe_helper.h | 1 + 2 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..787f6699971f 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -224,6 +224,26 @@ drm_connector_mode_valid(struct drm_connector *connector, }
#define DRM_OUTPUT_POLL_PERIOD (10*HZ) +static void reschedule_output_poll_work(struct drm_device *dev) +{ + unsigned long delay = DRM_OUTPUT_POLL_PERIOD; + + if (dev->mode_config.delayed_event) + /* + * FIXME: + * + * Use short (1s) delay to handle the initial delayed event. + * This delay should not be needed, but Optimus/nouveau will + * fail in a mysterious way if the delayed event is handled as + * soon as possible like it is done in + * drm_helper_probe_single_connector_modes() in case the poll + * was enabled before. + */ + delay = HZ; + + schedule_delayed_work(&dev->mode_config.output_poll_work, delay); +} + /** * drm_kms_helper_poll_enable - re-enable output polling. * @dev: drm_device @@ -244,43 +264,45 @@ drm_connector_mode_valid(struct drm_connector *connector, */ void drm_kms_helper_poll_enable(struct drm_device *dev) { - bool poll = false; + struct drm_connector *connector; struct drm_connector_list_iter conn_iter; - unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || !drm_kms_helper_poll || dev->mode_config.poll_running) return;
- drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(connector, &conn_iter) { - if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT)) - poll = true; - } - drm_connector_list_iter_end(&conn_iter); + if (drm_kms_helper_enable_hpd(dev) || + dev->mode_config.delayed_event) + reschedule_output_poll_work(dev);
- if (dev->mode_config.delayed_event) { - /* - * FIXME: - * - * Use short (1s) delay to handle the initial delayed event. - * This delay should not be needed, but Optimus/nouveau will - * fail in a mysterious way if the delayed event is handled as - * soon as possible like it is done in - * drm_helper_probe_single_connector_modes() in case the poll - * was enabled before. - */ - poll = true; - delay = HZ; - } - - if (poll) - schedule_delayed_work(&dev->mode_config.output_poll_work, delay); + dev->mode_config.poll_running = true; } EXPORT_SYMBOL(drm_kms_helper_poll_enable);
+/** + * drm_kms_helper_poll_reschedule - reschedule the output polling work + * @dev: drm_device + * + * This function reschedules the output polling work, after polling for a + * connector has been enabled. + * + * Drivers must call this helper after enabling polling for a connector by + * setting %DRM_CONNECTOR_POLL_CONNECT / %DRM_CONNECTOR_POLL_DISCONNECT flags + * in drm_connector::polled. Note that after disabling polling by clearing these + * flags for a connector will stop the output polling work automatically if + * the polling is disabled for all other connectors as well. + * + * The function can be called only after polling has been enabled by calling + * drm_kms_helper_poll_init() / drm_kms_helper_poll_enable(). + */ +void drm_kms_helper_poll_reschedule(struct drm_device *dev) +{ + if (dev->mode_config.poll_running) + reschedule_output_poll_work(dev); +} +EXPORT_SYMBOL(drm_kms_helper_poll_reschedule); + static enum drm_connector_status drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force) { diff --git a/include/drm/drm_probe_helper.h b/include/drm/drm_probe_helper.h index 5880daa14624..429a85f38036 100644 --- a/include/drm/drm_probe_helper.h +++ b/include/drm/drm_probe_helper.h @@ -25,6 +25,7 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector);
void drm_kms_helper_poll_disable(struct drm_device *dev); void drm_kms_helper_poll_enable(struct drm_device *dev); +void drm_kms_helper_poll_reschedule(struct drm_device *dev); bool drm_kms_helper_is_poll_worker(void);
enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc,
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
commit cbf143b282c64e59559cc8351c0b5b1ab4bbdcbe upstream
This is not a direct cherry-pick of the upstream commit. Only the helper functions required as dependencies for "drm/i915: Fix HPD polling, reenabling the output poll work as needed" were extracted from the original commit. The rest of the code was not applied, as the codebase has diverged significantly.
This partial adaptation ensures that the required helpers are available for the dependent fix, while minimizing changes to the existing code.
Extract drm_kms_helper_enable_hpd() and drm_kms_helper_disable_hpd(), two helpers that enable and disable HPD handling on all device's connectors.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20230124104548.3234554-1-dmitr... Signed-off-by: Nicusor Huhulea nicusor.huhulea@siemens.com --- drivers/gpu/drm/drm_probe_helper.c | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 787f6699971f..938649e3a282 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -244,6 +244,45 @@ static void reschedule_output_poll_work(struct drm_device *dev) schedule_delayed_work(&dev->mode_config.output_poll_work, delay); }
+static void drm_kms_helper_disable_hpd(struct drm_device *dev) +{ + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->disable_hpd) + funcs->disable_hpd(connector); + } + drm_connector_list_iter_end(&conn_iter); +} + +static bool drm_kms_helper_enable_hpd(struct drm_device *dev) +{ + bool poll = false; + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + const struct drm_connector_helper_funcs *funcs = + connector->helper_private; + + if (funcs && funcs->enable_hpd) + funcs->enable_hpd(connector); + + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT)) + poll = true; + } + drm_connector_list_iter_end(&conn_iter); + + return poll; +} + /** * drm_kms_helper_poll_enable - re-enable output polling. * @dev: drm_device
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
commit c8268795c9a9cc7be50f78d4502fad83a2a4f8df upstream
This is not a direct cherry-pick of the upstream commit. Only the helper functions required as dependencies for "drm/i915: Fix HPD polling, reenabling the output poll work as needed" were extracted from the original commit. The rest of the code was not applied, as the codebase has diverged significantly from upstream.
This partial adaptation ensures that the required drm_connector_helper_funcs are available for the dependent fix, while minimizing changes to the existing code.
Introduce two drm_connector_helper_funcs: enable_hpd() and disable_hpd(). They are called by drm_kms_helper_poll_enable() and drm_kms_helper_poll_disable() (and thus drm_kms_helper_poll_init() and drm_kms_helper_poll_fini()) respectively.
This allows DRM drivers to rely on drm_kms_helper_poll for enabling and disabling HPD detection rather than doing that manually.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://patchwork.freedesktop.org/patch/msgid/20221102180705.459294-3-dmitry... Signed-off-by: Nicusor Huhulea nicusor.huhulea@siemens.com --- include/drm/drm_modeset_helper_vtables.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index 6f19cf5c210e..54f4848a655a 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1144,6 +1144,28 @@ struct drm_connector_helper_funcs { */ void (*cleanup_writeback_job)(struct drm_writeback_connector *connector, struct drm_writeback_job *job); + + /** + * @enable_hpd: + * + * Enable hot-plug detection for the connector. + * + * This operation is optional. + * + * This callback is used by the drm_kms_helper_poll_enable() helpers. + */ + void (*enable_hpd)(struct drm_connector *connector); + + /** + * @disable_hpd: + * + * Disable hot-plug detection for the connector. + * + * This operation is optional. + * + * This callback is used by the drm_kms_helper_poll_disable() helpers. + */ + void (*disable_hpd)(struct drm_connector *connector); };
/**
This collects and adapts several upstream fixes to make i915 and related DRM subsystem build and function. The upstream fix HPD polling("drm/i915: Fix HPD polling, reenabling the output poll work as needed") and its dependencies could not be directly backported due to extensive code differences.
Upstream commits: drm/i915: Fix HPD polling, reenabling the output poll work as needed(commit 50452f2f76852322620b63e62922b85e955abe9) drm: Add an HPD poll helper to reschedule the poll work(commit fe2352fd64029918174de4b460dfe6df0c6911cd) drm/probe_helper: extract two helper functions(commit cbf143b282c64e59559cc8351c0b5b1ab4bbdcbe) drm/probe-helper: enable and disable HPD on connectors(commit c8268795c9a9cc7be50f78d4502fad83a2a4f8df) ...
Due to significant codebase divergence and numerous dependencies, it was not possible to cherry-pick these commits cleanly. Instead, this will resolve compile-time errors and fixes the hot plug mechanism. Developed with uspstream as a guideline, with the goal of addressing the defect while maintaining the stability.
Auxiliary fixes in upstream commits were not ported here as this would require substantial work and dependency tracking.
Cc: stable@vger.kernel.org # 6.1.y Cc: dri-devel@lists.freedesktop.org Cc: Imre Deak imre.deak@intel.com Signed-off-by: Nicusor Huhulea nicusor.huhulea@siemens.com --- drivers/gpu/drm/drm_probe_helper.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 938649e3a282..9dc7505f20ff 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -304,8 +304,6 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev) void drm_kms_helper_poll_enable(struct drm_device *dev) {
- struct drm_connector *connector; - struct drm_connector_list_iter conn_iter;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || !drm_kms_helper_poll || dev->mode_config.poll_running) @@ -779,8 +777,11 @@ static void output_poll_execute(struct work_struct *work) changed = dev->mode_config.delayed_event; dev->mode_config.delayed_event = false;
- if (!drm_kms_helper_poll) + if (!drm_kms_helper_poll && dev->mode_config.poll_running) { + drm_kms_helper_disable_hpd(dev); + dev->mode_config.poll_running = false; goto out; + }
if (!mutex_trylock(&dev->mode_config.mutex)) { repoll = true; @@ -897,9 +898,14 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); void drm_kms_helper_poll_disable(struct drm_device *dev) { if (drm_WARN_ON(dev, !dev->mode_config.poll_enabled)) - return; + pr_warn("%s: called with poll_enabled = false\n", __func__); + + if (dev->mode_config.poll_running) + drm_kms_helper_disable_hpd(dev);
cancel_delayed_work_sync(&dev->mode_config.output_poll_work); + + dev->mode_config.poll_running = false; } EXPORT_SYMBOL(drm_kms_helper_poll_disable);
Hi Nicusor,
thanks for the report and the root causing effort. The patchset itself has a few issues:
- commit cfd48ad8c4a9 ("drm/i915: Fix HPD polling, reenabling the output poll work as needed") you backport fixes d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled"), but this fixed commit is not part of the 6.1.y stable tree which you are targeting.
Similarly commit d33a54e3991d fixes c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors"), which is not part of 6.1.y either.
This means the issue commit cfd48ad8c4a9 is fixing is not present in the 6.1.y tree, as the changes introducing that issue are not present in that tree either.
- The compile errors the patches in your patchset introduce would prevent bisection, so fixing up these compile errors only at the end of the patchset is not ok; the tree should compile without errors at each patch/commit.
Looking at v6.1.y and the patchset I suspect the actual issue is the
commit 4ad8d57d902f ("drm: Check output polling initialized before disabling") backport in v6.1.y, which had the
- if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) + if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || + !drm_kms_helper_poll || dev->mode_config.poll_running)
change, not part of the original
commit 5abffb66d12b ("drm: Check output polling initialized before disabling"). i.e. the original patch didn't add the check for dev->mode_config.poll_running. So could you try on top of v6.1.147 (w/o the changes in the patchset you posted):
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..a515b78f839e 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -250,7 +250,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || - !drm_kms_helper_poll || dev->mode_config.poll_running) + !drm_kms_helper_poll) return;
drm_connector_list_iter_begin(dev, &conn_iter);
If this doesn't resolve the issue, I think we need to figure out the actual root cause, for that could you please open at a ticket at
https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/new
attaching a dmesg log booting v6.1.147 and if possible also the latest drm-tip kernel with the drm.debug=0xe kernel parameter?
Thanks, Imre
On Wed, Jul 30, 2025 at 07:11:01PM +0300, Nicusor Huhulea wrote:
Hello maintainers,
This series addresses a defect observed on certain hardware platforms using Linux kernel 6.1.147 with the i915 driver. The issue concerns hot plug detection (HPD) logic, leading to unreliable or missed detection events on affected hardware. This is happening on some specific devices.
### Background
Issue: On Simatic IPC227E, we observed unreliable or missing hot plug detection events, while on Simatic IPC227G (otherwise similar platform), expected hot plug behavior was maintained. Affected kernel: This patch series is intended for the Linux 6.1.y stable tree only (tested on 6.1.147) Most of the tests were conducted on 6.1.147 (manual/standalone kernel build, CIP/Isar context). Root cause analysis: I do not have access to hardware signal traces or scope data to conclusively prove the root cause at electrical level. My understanding is based on observed driver behavior and logs. Therefore my assumption as to the real cause is that on IPC227G, HPD IRQ storms are apparently not occurring, so the standard HPD IRQ-based detection works as expected. On IPC227E, frequent HPD interrupts trigger the i915 driver’s storm detection logic, causing it to switch to polling mode. Therefore polling does not resume correctly, leading to the hotplug issue this series addresses. Device IPC227E's behavior triggers this kernel edge case, likely due to slight variations in signal integrity, electrical margins, or internal component timing. Device IPC227G, functions as expected, possibly due to cleaner electrical signaling or more optimal timing characteristics, thus avoiding the triggering condition. Conclusion: This points to a hardware-software interaction where kernel code assumes nicer signaling or margins than IPC227E is able to provide, exposing logic gaps not visible on more robust hardware.
### Patches
Patches 1-4: - Partial backports of upstream commits; only the relevant logic or fixes are applied, with other code omitted due to downstream divergence. - Applied minimal merging without exhaustive backport of all intermediate upstream changes. Patch 5: - Contains cherry-picked logic plus context/compatibility amendments as needed. Ensures that the driver builds. - Together these fixes greatly improve reliability of hotplug detection on both devices, with no regression detected in our setups.
Thank you for your review, Nicusor Huhulea
This patch series contains the following changes:
Dmitry Baryshkov (2): drm/probe_helper: extract two helper functions drm/probe-helper: enable and disable HPD on connectors
Imre Deak (2): drm/i915: Fix HPD polling, reenabling the output poll work as needed drm: Add an HPD poll helper to reschedule the poll work
Nicusor Huhulea (1): drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
drivers/gpu/drm/drm_probe_helper.c | 127 ++++++++++++++----- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 +- include/drm/drm_modeset_helper_vtables.h | 22 ++++ include/drm/drm_probe_helper.h | 1 + 4 files changed, 122 insertions(+), 32 deletions(-)
-- 2.39.2
-----Original Message----- From: Imre Deak imre.deak@intel.com Sent: Wednesday, July 30, 2025 11:02 PM To: Huhulea, Nicusor Liviu (FT FDS CES LX PBU 1) nicusor.huhulea@siemens.com Cc: stable@vger.kernel.org; dri-devel@lists.freedesktop.org; intel- gfx@lists.freedesktop.org; cip-dev@lists.cip-project.org; jouni.hogander@intel.com; neil.armstrong@linaro.org; jani.nikula@linux.intel.com; maarten.lankhorst@linux.intel.com; mripard@kernel.org; tzimmermann@suse.de; airlied@gmail.com; daniel@ffwll.ch; joonas.lahtinen@linux.intel.com; rodrigo.vivi@intel.com; tvrtko.ursulin@linux.intel.com; laurentiu.palcu@oss.nxp.com; Hombourger, Cedric (FT FDS CES LX) cedric.hombourger@siemens.com; Bobade, Shrikant Krishnarao (FT FDS CES LX PBU 1) shrikant.bobade@siemens.com Subject: Re: [PATCH 0/5] drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
Hi Nicusor,
thanks for the report and the root causing effort. The patchset itself has a few issues:
- commit cfd48ad8c4a9 ("drm/i915: Fix HPD polling, reenabling the output
poll work as needed") you backport fixes d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled"), but this fixed commit is not part of the 6.1.y stable tree which you are targeting.
Similarly commit d33a54e3991d fixes c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors"), which is not part of 6.1.y either.
This means the issue commit cfd48ad8c4a9 is fixing is not present in the 6.1.y tree, as the changes introducing that issue are not present in that tree either.
- The compile errors the patches in your patchset introduce would
prevent bisection, so fixing up these compile errors only at the end of the patchset is not ok; the tree should compile without errors at each patch/commit.
Looking at v6.1.y and the patchset I suspect the actual issue is the
commit 4ad8d57d902f ("drm: Check output polling initialized before disabling") backport in v6.1.y, which had the
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
change, not part of the original
commit 5abffb66d12b ("drm: Check output polling initialized before disabling"). i.e. the original patch didn't add the check for dev->mode_config.poll_running. So could you try on top of v6.1.147 (w/o the changes in the patchset you posted):
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..a515b78f839e 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -250,7 +250,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
!drm_kms_helper_poll) return; drm_connector_list_iter_begin(dev, &conn_iter);
Thank you for your thorough explanation, especially regarding the bisecting issue. I hadn't anticipated that by fixing compile errors only at the end of the series, I would make bisection unreliable.
I have tested your idea/fix and it works. HPD polling works reliably on both devices. I can see the polling in logs when display cable is not connected.
Since this fix is mostly your solution, would you prefer to submit yourself, or would you like me to resubmit it as a v2 and credit you appropriately ?
If this doesn't resolve the issue, I think we need to figure out the actual root cause, for that could you please open at a ticket at
https://gitlab.freed/ esktop.org%2Fdrm%2Fi915%2Fkernel%2F- %2Fissues%2Fnew&data=05%7C02%7Cnicusor.huhulea%40siemens.com%7Cd78 e534c4c604c981c9108ddcfa41f44%7C38ae3bcd95794fd4addab42e1495d55a%7C1 %7C0%7C638895025993788215%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1h cGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyf Q%3D%3D%7C0%7C%7C%7C&sdata=nss8VV88cJo9qDB5YSlr1OKAYXMo6epa HcR1p355Lns%3D&reserved=0
attaching a dmesg log booting v6.1.147 and if possible also the latest drm-tip kernel with the drm.debug=0xe kernel parameter?
Thanks, Imre
On Wed, Jul 30, 2025 at 07:11:01PM +0300, Nicusor Huhulea wrote:
Hello maintainers,
This series addresses a defect observed on certain hardware platforms using Linux kernel 6.1.147 with the i915 driver. The issue concerns hot plug
detection (HPD) logic, leading to unreliable or missed detection events on affected hardware. This is happening on some specific devices.
### Background
Issue: On Simatic IPC227E, we observed unreliable or missing hot plug detection
events, while on Simatic IPC227G (otherwise similar platform), expected hot plug behavior was maintained.
Affected kernel: This patch series is intended for the Linux 6.1.y stable tree only (tested on
6.1.147)
Most of the tests were conducted on 6.1.147 (manual/standalone kernel build,
CIP/Isar context).
Root cause analysis: I do not have access to hardware signal traces or scope data to conclusively
prove the root cause at electrical level. My understanding is based on observed driver behavior and logs.
Therefore my assumption as to the real cause is that on IPC227G, HPD IRQ
storms are apparently not occurring, so the standard HPD IRQ-based detection works as expected. On IPC227E,
frequent HPD interrupts trigger the i915 driver's storm detection logic, causing
it to switch to polling mode. Therefore polling does not resume correctly, leading to the hotplug
issue this series addresses. Device IPC227E's behavior triggers this kernel
edge case, likely due to slight variations in signal integrity, electrical margins, or internal component timing.
Device IPC227G, functions as expected, possibly due to cleaner electrical
signaling or more optimal timing characteristics, thus avoiding the triggering condition.
Conclusion: This points to a hardware-software interaction where kernel code assumes
nicer signaling or margins than IPC227E is able to provide, exposing logic gaps not visible on more robust hardware.
### Patches
Patches 1-4: - Partial backports of upstream commits; only the relevant logic or fixes are
applied, with other code omitted due to downstream divergence.
- Applied minimal merging without exhaustive backport of all intermediate
upstream changes.
Patch 5: - Contains cherry-picked logic plus context/compatibility amendments as
needed. Ensures that the driver builds.
- Together these fixes greatly improve reliability of hotplug detection on both
devices, with no regression detected in our setups.
Thank you for your review, Nicusor Huhulea
This patch series contains the following changes:
Dmitry Baryshkov (2): drm/probe_helper: extract two helper functions drm/probe-helper: enable and disable HPD on connectors
Imre Deak (2): drm/i915: Fix HPD polling, reenabling the output poll work as needed drm: Add an HPD poll helper to reschedule the poll work
Nicusor Huhulea (1): drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
drivers/gpu/drm/drm_probe_helper.c | 127 ++++++++++++++----- drivers/gpu/drm/i915/display/intel_hotplug.c | 4 +- include/drm/drm_modeset_helper_vtables.h | 22 ++++ include/drm/drm_probe_helper.h | 1 + 4 files changed, 122 insertions(+), 32 deletions(-)
-- 2.39.2
Hi Greg and Shradha,
could you please check the comment below about the 4ad8d57d902f backport commit in the v6.1.y stable tree and if you agree with the reasoning why it has an issue, then suggest a way to resolve it?
Also, AFAICS, other stable trees are not affected, since the original 5abffb66d12bcac commit got only backported to the above v6.1.y tree, but please confirm this.
On Fri, Aug 01, 2025 at 02:37:04PM +0000, nicusor.huhulea@siemens.com wrote:
-----Original Message----- From: Imre Deak imre.deak@intel.com Sent: Wednesday, July 30, 2025 11:02 PM To: Nicusor Liviu Huhulea (FT FDS CES LX PBU 1) nicusor.huhulea@siemens.com Cc: stable@vger.kernel.org; dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; cip-dev@lists.cip-project.org; jouni.hogander@intel.com; neil.armstrong@linaro.org; jani.nikula@linux.intel.com; maarten.lankhorst@linux.intel.com; mripard@kernel.org; tzimmermann@suse.de; airlied@gmail.com; daniel@ffwll.ch; joonas.lahtinen@linux.intel.com; rodrigo.vivi@intel.com; tvrtko.ursulin@linux.intel.com; laurentiu.palcu@oss.nxp.com; Cedric Hombourger (FT FDS CES LX) cedric.hombourger@siemens.com; Shrikant Krishnarao Bobade (FT FDS CES LX PBU 1) shrikant.bobade@siemens.com Subject: Re: [PATCH 0/5] drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
Hi Nicusor,
thanks for the report and the root causing effort. The patchset itself has a few issues:
commit cfd48ad8c4a9 ("drm/i915: Fix HPD polling, reenabling the output poll work as needed") you backport fixes d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled"), but this fixed commit is not part of the 6.1.y stable tree which you are targeting.
Similarly commit d33a54e3991d fixes c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors"), which is not part of 6.1.y either.
This means the issue commit cfd48ad8c4a9 is fixing is not present in the 6.1.y tree, as the changes introducing that issue are not present in that tree either.
The compile errors the patches in your patchset introduce would prevent bisection, so fixing up these compile errors only at the end of the patchset is not ok; the tree should compile without errors at each patch/commit.
Looking at v6.1.y and the patchset I suspect the actual issue is the
commit 4ad8d57d902f ("drm: Check output polling initialized before disabling") backport in v6.1.y, which had the
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
change, not part of the original
commit 5abffb66d12b ("drm: Check output polling initialized before disabling"). i.e. the original patch didn't add the check for dev->mode_config.poll_running. So could you try on top of v6.1.147 (w/o the changes in the patchset you posted):
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..a515b78f839e 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -250,7 +250,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
!drm_kms_helper_poll) return; drm_connector_list_iter_begin(dev, &conn_iter);
Thank you for your thorough explanation, especially regarding the bisecting issue. I hadn't anticipated that by fixing compile errors only at the end of the series, I would make bisection unreliable.
I have tested your idea/fix and it works. HPD polling works reliably on both devices. I can see the polling in logs when display cable is not connected.
Since this fix is mostly your solution, would you prefer to submit yourself, or would you like me to resubmit it as a v2 and credit you appropriately ?
Thanks again Nicusor for the effort to root cause this and for all the tests.
Greg, Shradha, as described above I think in the 4ad8d57d902f backport commit in v6.1.y it was incorrect to add the
dev->mode_config.poll_running
condition, as the original 5abffb66d12b commit was not the one adding this, in that commit that condition was only part of the diff context. OTOH, adding the check for this condition causes an issue in the i915 driver's IRQ storm handling in the v6.1.y stable tree: after dev->mode_config.poll_running gets set (during the first connector detection in drm_helper_probe_single_connector_modes()), the
drm_kms_helper_poll_enable()
call in intel_hpd_irq_storm_switch_to_polling() will not any more schedule the output_poll_work as expected. Thus after an IRQ storm, the HPD IRQs get disabled, but the HPD polling will not run and so the HPD detection will not work as Nicusor described above.
If you agree with the above and the above proposed solution to remove the dev->mode_config.poll_running check from the v6.1.y tree, then what would be Greg the correct way to do this?
Thanks, Imre
On Fri, Aug 01, 2025 at 06:26:04PM +0300, Imre Deak wrote:
Hi Greg and Shradha,
could you please check the comment below about the 4ad8d57d902f backport commit in the v6.1.y stable tree and if you agree with the reasoning why it has an issue, then suggest a way to resolve it?
Also, AFAICS, other stable trees are not affected, since the original 5abffb66d12bcac commit got only backported to the above v6.1.y tree, but please confirm this.
On Fri, Aug 01, 2025 at 02:37:04PM +0000, nicusor.huhulea@siemens.com wrote:
-----Original Message----- From: Imre Deak imre.deak@intel.com Sent: Wednesday, July 30, 2025 11:02 PM To: Nicusor Liviu Huhulea (FT FDS CES LX PBU 1) nicusor.huhulea@siemens.com Cc: stable@vger.kernel.org; dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; cip-dev@lists.cip-project.org; jouni.hogander@intel.com; neil.armstrong@linaro.org; jani.nikula@linux.intel.com; maarten.lankhorst@linux.intel.com; mripard@kernel.org; tzimmermann@suse.de; airlied@gmail.com; daniel@ffwll.ch; joonas.lahtinen@linux.intel.com; rodrigo.vivi@intel.com; tvrtko.ursulin@linux.intel.com; laurentiu.palcu@oss.nxp.com; Cedric Hombourger (FT FDS CES LX) cedric.hombourger@siemens.com; Shrikant Krishnarao Bobade (FT FDS CES LX PBU 1) shrikant.bobade@siemens.com Subject: Re: [PATCH 0/5] drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
Hi Nicusor,
thanks for the report and the root causing effort. The patchset itself has a few issues:
commit cfd48ad8c4a9 ("drm/i915: Fix HPD polling, reenabling the output poll work as needed") you backport fixes d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled"), but this fixed commit is not part of the 6.1.y stable tree which you are targeting.
Similarly commit d33a54e3991d fixes c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors"), which is not part of 6.1.y either.
This means the issue commit cfd48ad8c4a9 is fixing is not present in the 6.1.y tree, as the changes introducing that issue are not present in that tree either.
The compile errors the patches in your patchset introduce would prevent bisection, so fixing up these compile errors only at the end of the patchset is not ok; the tree should compile without errors at each patch/commit.
Looking at v6.1.y and the patchset I suspect the actual issue is the
commit 4ad8d57d902f ("drm: Check output polling initialized before disabling") backport in v6.1.y, which had the
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
change, not part of the original
commit 5abffb66d12b ("drm: Check output polling initialized before disabling"). i.e. the original patch didn't add the check for dev->mode_config.poll_running. So could you try on top of v6.1.147 (w/o the changes in the patchset you posted):
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..a515b78f839e 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -250,7 +250,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
!drm_kms_helper_poll) return; drm_connector_list_iter_begin(dev, &conn_iter);
Thank you for your thorough explanation, especially regarding the bisecting issue. I hadn't anticipated that by fixing compile errors only at the end of the series, I would make bisection unreliable.
I have tested your idea/fix and it works. HPD polling works reliably on both devices. I can see the polling in logs when display cable is not connected.
Since this fix is mostly your solution, would you prefer to submit yourself, or would you like me to resubmit it as a v2 and credit you appropriately ?
Thanks again Nicusor for the effort to root cause this and for all the tests.
Greg, Shradha, as described above I think in the 4ad8d57d902f backport commit in v6.1.y it was incorrect to add the
dev->mode_config.poll_running
condition, as the original 5abffb66d12b commit was not the one adding this, in that commit that condition was only part of the diff context. OTOH, adding the check for this condition causes an issue in the i915 driver's IRQ storm handling in the v6.1.y stable tree: after dev->mode_config.poll_running gets set (during the first connector detection in drm_helper_probe_single_connector_modes()), the
drm_kms_helper_poll_enable()
call in intel_hpd_irq_storm_switch_to_polling() will not any more schedule the output_poll_work as expected. Thus after an IRQ storm, the HPD IRQs get disabled, but the HPD polling will not run and so the HPD detection will not work as Nicusor described above.
If you agree with the above and the above proposed solution to remove the dev->mode_config.poll_running check from the v6.1.y tree, then what would be Greg the correct way to do this?
Send whatever fix is needed please.
On Sat, Aug 02, 2025 at 08:38:36AM +0100, Greg Kroah-Hartman wrote:
On Fri, Aug 01, 2025 at 06:26:04PM +0300, Imre Deak wrote:
Hi Greg and Shradha,
could you please check the comment below about the 4ad8d57d902f backport commit in the v6.1.y stable tree and if you agree with the reasoning why it has an issue, then suggest a way to resolve it?
Also, AFAICS, other stable trees are not affected, since the original 5abffb66d12bcac commit got only backported to the above v6.1.y tree, but please confirm this.
On Fri, Aug 01, 2025 at 02:37:04PM +0000, nicusor.huhulea@siemens.com wrote:
-----Original Message----- From: Imre Deak imre.deak@intel.com Sent: Wednesday, July 30, 2025 11:02 PM To: Nicusor Liviu Huhulea (FT FDS CES LX PBU 1) nicusor.huhulea@siemens.com Cc: stable@vger.kernel.org; dri-devel@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; cip-dev@lists.cip-project.org; jouni.hogander@intel.com; neil.armstrong@linaro.org; jani.nikula@linux.intel.com; maarten.lankhorst@linux.intel.com; mripard@kernel.org; tzimmermann@suse.de; airlied@gmail.com; daniel@ffwll.ch; joonas.lahtinen@linux.intel.com; rodrigo.vivi@intel.com; tvrtko.ursulin@linux.intel.com; laurentiu.palcu@oss.nxp.com; Cedric Hombourger (FT FDS CES LX) cedric.hombourger@siemens.com; Shrikant Krishnarao Bobade (FT FDS CES LX PBU 1) shrikant.bobade@siemens.com Subject: Re: [PATCH 0/5] drm/i915: fixes for i915 Hot Plug Detection and build/runtime issues
Hi Nicusor,
thanks for the report and the root causing effort. The patchset itself has a few issues:
commit cfd48ad8c4a9 ("drm/i915: Fix HPD polling, reenabling the output poll work as needed") you backport fixes d33a54e3991d ("drm/probe_helper: sort out poll_running vs poll_enabled"), but this fixed commit is not part of the 6.1.y stable tree which you are targeting.
Similarly commit d33a54e3991d fixes c8268795c9a9 ("drm/probe-helper: enable and disable HPD on connectors"), which is not part of 6.1.y either.
This means the issue commit cfd48ad8c4a9 is fixing is not present in the 6.1.y tree, as the changes introducing that issue are not present in that tree either.
The compile errors the patches in your patchset introduce would prevent bisection, so fixing up these compile errors only at the end of the patchset is not ok; the tree should compile without errors at each patch/commit.
Looking at v6.1.y and the patchset I suspect the actual issue is the
commit 4ad8d57d902f ("drm: Check output polling initialized before disabling") backport in v6.1.y, which had the
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
change, not part of the original
commit 5abffb66d12b ("drm: Check output polling initialized before disabling"). i.e. the original patch didn't add the check for dev->mode_config.poll_running. So could you try on top of v6.1.147 (w/o the changes in the patchset you posted):
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 0e5eadc6d44d..a515b78f839e 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -250,7 +250,7 @@ void drm_kms_helper_poll_enable(struct drm_device *dev) unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
!drm_kms_helper_poll || dev->mode_config.poll_running)
!drm_kms_helper_poll) return; drm_connector_list_iter_begin(dev, &conn_iter);
Thank you for your thorough explanation, especially regarding the bisecting issue. I hadn't anticipated that by fixing compile errors only at the end of the series, I would make bisection unreliable.
I have tested your idea/fix and it works. HPD polling works reliably on both devices. I can see the polling in logs when display cable is not connected.
Since this fix is mostly your solution, would you prefer to submit yourself, or would you like me to resubmit it as a v2 and credit you appropriately ?
Thanks again Nicusor for the effort to root cause this and for all the tests.
Greg, Shradha, as described above I think in the 4ad8d57d902f backport commit in v6.1.y it was incorrect to add the
dev->mode_config.poll_running
condition, as the original 5abffb66d12b commit was not the one adding this, in that commit that condition was only part of the diff context. OTOH, adding the check for this condition causes an issue in the i915 driver's IRQ storm handling in the v6.1.y stable tree: after dev->mode_config.poll_running gets set (during the first connector detection in drm_helper_probe_single_connector_modes()), the
drm_kms_helper_poll_enable()
call in intel_hpd_irq_storm_switch_to_polling() will not any more schedule the output_poll_work as expected. Thus after an IRQ storm, the HPD IRQs get disabled, but the HPD polling will not run and so the HPD detection will not work as Nicusor described above.
If you agree with the above and the above proposed solution to remove the dev->mode_config.poll_running check from the v6.1.y tree, then what would be Greg the correct way to do this?
Send whatever fix is needed please.
Ok. Nicusor could you please send a patch with the above diff removing the dev->mode_config.poll_running check to stable@vger.kernel.org, also CCing Shradha? You could also add a Link: line to this email thread. The patch description should mention that it is a fix for the v6.1.y stable tree for commit 4ad8d57d902f in that tree, give a concise explanation of the issue with the commit itself based on the above and describe the problem you observed it causes (vs. that the patch fixes this problem based on your tests)?
Thanks, Imre
linux-stable-mirror@lists.linaro.org