From 9409486075b9ba02eb10497dd2a7d9cfa859fbfe Mon Sep 17 00:00:00 2001 From: jsg Date: Mon, 15 Apr 2024 01:46:03 +0000 Subject: [PATCH] drm: Check output polling initialized before disabling From Shradha Gupta 3d1b47e3a935abd4f258a945db87e7267ff4079c in linux-6.6.y/6.6.27 5abffb66d12bcac84bf7b66389c571b8bb6e82bd in mainline linux --- sys/dev/pci/drm/drm_modeset_helper.c | 19 ++++++++++++++++--- sys/dev/pci/drm/drm_probe_helper.c | 13 +++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/sys/dev/pci/drm/drm_modeset_helper.c b/sys/dev/pci/drm/drm_modeset_helper.c index f858dfedf2c..2c582020cb4 100644 --- a/sys/dev/pci/drm/drm_modeset_helper.c +++ b/sys/dev/pci/drm/drm_modeset_helper.c @@ -193,13 +193,22 @@ int drm_mode_config_helper_suspend(struct drm_device *dev) if (!dev) return 0; + /* + * Don't disable polling if it was never initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_disable(dev); - drm_kms_helper_poll_disable(dev); drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1); state = drm_atomic_helper_suspend(dev); if (IS_ERR(state)) { drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); - drm_kms_helper_poll_enable(dev); + /* + * Don't enable polling if it was never initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_enable(dev); + return PTR_ERR(state); } @@ -239,7 +248,11 @@ int drm_mode_config_helper_resume(struct drm_device *dev) dev->mode_config.suspend_state = NULL; drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0); - drm_kms_helper_poll_enable(dev); + /* + * Don't enable polling if it is not initialized + */ + if (dev->mode_config.poll_enabled) + drm_kms_helper_poll_enable(dev); return ret; } diff --git a/sys/dev/pci/drm/drm_probe_helper.c b/sys/dev/pci/drm/drm_probe_helper.c index 169df0488e6..fd7deaa754d 100644 --- a/sys/dev/pci/drm/drm_probe_helper.c +++ b/sys/dev/pci/drm/drm_probe_helper.c @@ -293,14 +293,17 @@ static void reschedule_output_poll_work(struct drm_device *dev) * Drivers can call this helper from their device resume implementation. It is * not an error to call this even when output polling isn't enabled. * + * If device polling was never initialized before, this call will trigger a + * warning and return. + * * Note that calls to enable and disable polling must be strictly ordered, which * is automatically the case when they're only call from suspend/resume * callbacks. */ void drm_kms_helper_poll_enable(struct drm_device *dev) { - if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll || - dev->mode_config.poll_running) + if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) || + !drm_kms_helper_poll || dev->mode_config.poll_running) return; if (drm_kms_helper_enable_hpd(dev) || @@ -881,12 +884,18 @@ EXPORT_SYMBOL(drm_kms_helper_is_poll_worker); * not an error to call this even when output polling isn't enabled or already * disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable(). * + * If however, the polling was never initialized, this call will trigger a + * warning and return + * * Note that calls to enable and disable polling must be strictly ordered, which * is automatically the case when they're only call from suspend/resume * callbacks. */ void drm_kms_helper_poll_disable(struct drm_device *dev) { + if (drm_WARN_ON(dev, !dev->mode_config.poll_enabled)) + return; + if (dev->mode_config.poll_running) drm_kms_helper_disable_hpd(dev); -- 2.20.1