Re: [PATCH v2] drm/nouveau: don't attempt to schedule hpd_work on headless cards

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 6/8/24 00:09, Vasily Khoruzhick wrote:
If the card doesn't have display hardware, hpd_work and hpd_lock are
left uninitialized which causes BUG when attempting to schedule hpd_work
on runtime PM resume.

Fix it by adding headless flag to DRM and skip any hpd if it's set.

Fixes: ae1aadb1eb8d ("nouveau: don't fail driver load if no display hw present.")
Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/337
Signed-off-by: Vasily Khoruzhick <anarsoul@xxxxxxxxx>

Applied to drm-misc-fixes, thanks!

---
v2: drop extra checks in nouveau_display_hpd_work() and
nouveau_connector_hpd()

  drivers/gpu/drm/nouveau/dispnv04/disp.c   | 2 +-
  drivers/gpu/drm/nouveau/dispnv50/disp.c   | 2 +-
  drivers/gpu/drm/nouveau/nouveau_display.c | 6 +++++-
  drivers/gpu/drm/nouveau/nouveau_drv.h     | 1 +
  4 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c
index 13705c5f1497..4b7497a8755c 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c
@@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
  	if (nv_two_heads(dev))
  		NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
- if (!runtime)
+	if (!runtime && !drm->headless)
  		cancel_work_sync(&drm->hpd_work);
if (!suspend)
diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c
index 88728a0b2c25..674dc567e179 100644
--- a/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend)
  			nv50_mstm_fini(nouveau_encoder(encoder));
  	}
- if (!runtime)
+	if (!runtime && !drm->headless)
  		cancel_work_sync(&drm->hpd_work);
  }
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index aed5d5b51b43..d4725a968827 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev)
  {
  	struct nouveau_drm *drm = nouveau_drm(dev);
+ if (drm->headless)
+		return;
+
  	spin_lock_irq(&drm->hpd_lock);
  	drm->hpd_pending = ~0;
  	spin_unlock_irq(&drm->hpd_lock);
@@ -635,7 +638,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
  	}
  	drm_connector_list_iter_end(&conn_iter);
- if (!runtime)
+	if (!runtime && !drm->headless)
  		cancel_work_sync(&drm->hpd_work);
drm_kms_helper_poll_disable(dev);
@@ -729,6 +732,7 @@ nouveau_display_create(struct drm_device *dev)
  		/* no display hw */
  		if (ret == -ENODEV) {
  			ret = 0;
+			drm->headless = true;
  			goto disp_create_err;
  		}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index e239c6bf4afa..25fca98a20bc 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -276,6 +276,7 @@ struct nouveau_drm {
  	/* modesetting */
  	struct nvbios vbios;
  	struct nouveau_display *display;
+	bool headless;
  	struct work_struct hpd_work;
  	spinlock_t hpd_lock;
  	u32 hpd_pending;




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux