Commit b96a2253 authored by Vasily Khoruzhick's avatar Vasily Khoruzhick Committed by Danilo Krummrich

drm/nouveau: don't attempt to schedule hpd_work on headless cards

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: ae1aadb1 ("nouveau: don't fail driver load if no display hw present.")
Link: https://gitlab.freedesktop.org/drm/nouveau/-/issues/337Signed-off-by: default avatarVasily Khoruzhick <anarsoul@gmail.com>
Reviewed-by: default avatarBen Skeggs <bskeggs@nvidia.com>
Signed-off-by: default avatarDanilo Krummrich <dakr@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240607221032.25918-1-anarsoul@gmail.com
parent 31849bf0
...@@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend) ...@@ -68,7 +68,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
if (nv_two_heads(dev)) if (nv_two_heads(dev))
NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0); NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
if (!runtime) if (!runtime && !drm->headless)
cancel_work_sync(&drm->hpd_work); cancel_work_sync(&drm->hpd_work);
if (!suspend) if (!suspend)
......
...@@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend) ...@@ -2680,7 +2680,7 @@ nv50_display_fini(struct drm_device *dev, bool runtime, bool suspend)
nv50_mstm_fini(nouveau_encoder(encoder)); nv50_mstm_fini(nouveau_encoder(encoder));
} }
if (!runtime) if (!runtime && !drm->headless)
cancel_work_sync(&drm->hpd_work); cancel_work_sync(&drm->hpd_work);
} }
......
...@@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev) ...@@ -450,6 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev)
{ {
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
if (drm->headless)
return;
spin_lock_irq(&drm->hpd_lock); spin_lock_irq(&drm->hpd_lock);
drm->hpd_pending = ~0; drm->hpd_pending = ~0;
spin_unlock_irq(&drm->hpd_lock); spin_unlock_irq(&drm->hpd_lock);
...@@ -635,7 +638,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) ...@@ -635,7 +638,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
} }
drm_connector_list_iter_end(&conn_iter); drm_connector_list_iter_end(&conn_iter);
if (!runtime) if (!runtime && !drm->headless)
cancel_work_sync(&drm->hpd_work); cancel_work_sync(&drm->hpd_work);
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
...@@ -729,6 +732,7 @@ nouveau_display_create(struct drm_device *dev) ...@@ -729,6 +732,7 @@ nouveau_display_create(struct drm_device *dev)
/* no display hw */ /* no display hw */
if (ret == -ENODEV) { if (ret == -ENODEV) {
ret = 0; ret = 0;
drm->headless = true;
goto disp_create_err; goto disp_create_err;
} }
......
...@@ -276,6 +276,7 @@ struct nouveau_drm { ...@@ -276,6 +276,7 @@ struct nouveau_drm {
/* modesetting */ /* modesetting */
struct nvbios vbios; struct nvbios vbios;
struct nouveau_display *display; struct nouveau_display *display;
bool headless;
struct work_struct hpd_work; struct work_struct hpd_work;
spinlock_t hpd_lock; spinlock_t hpd_lock;
u32 hpd_pending; u32 hpd_pending;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment