drm/nouveau: Don't grab runtime PM refs for HPD IRQs
In order for suspend/resume reprobing to work, we need to be able to perform sideband communications during suspend/resume, along with runtime PM suspend/resume. In order to do so, we also need to make sure that nouveau doesn't bother grabbing a runtime PM reference to do so, since otherwise we'll start deadlocking runtime PM again. Note that we weren't able to do this before, because of the DP MST helpers processing UP requests from topologies in the same context as drm_dp_mst_hpd_irq() which would have caused us to open ourselves up to receiving hotplug events and deadlocking with runtime suspend/resume. Now that those requests are handled asynchronously, this change should be completely safe. Cc: Juston Li <juston.li@intel.com> Cc: Imre Deak <imre.deak@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Harry Wentland <hwentlan@amd.com> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Ben Skeggs <bskeggs@redhat.com> Reviewed-by: Sean Paul <sean@poorly.run> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20191022023641.8026-10-lyude@redhat.com
This commit is contained in:
Родитель
79413ed4a1
Коммит
09e530657e
|
@ -1130,6 +1130,16 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
|
|||
const char *name = connector->name;
|
||||
struct nouveau_encoder *nv_encoder;
|
||||
int ret;
|
||||
bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG);
|
||||
|
||||
if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
|
||||
NV_DEBUG(drm, "service %s\n", name);
|
||||
drm_dp_cec_irq(&nv_connector->aux);
|
||||
if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP)))
|
||||
nv50_mstm_service(nv_encoder->dp.mstm);
|
||||
|
||||
return NVIF_NOTIFY_KEEP;
|
||||
}
|
||||
|
||||
ret = pm_runtime_get(drm->dev->dev);
|
||||
if (ret == 0) {
|
||||
|
@ -1150,25 +1160,16 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
|
|||
return NVIF_NOTIFY_DROP;
|
||||
}
|
||||
|
||||
if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
|
||||
NV_DEBUG(drm, "service %s\n", name);
|
||||
drm_dp_cec_irq(&nv_connector->aux);
|
||||
if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP)))
|
||||
nv50_mstm_service(nv_encoder->dp.mstm);
|
||||
} else {
|
||||
bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG);
|
||||
|
||||
if (!plugged)
|
||||
drm_dp_cec_unset_edid(&nv_connector->aux);
|
||||
NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
|
||||
if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) {
|
||||
if (!plugged)
|
||||
drm_dp_cec_unset_edid(&nv_connector->aux);
|
||||
NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
|
||||
if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) {
|
||||
if (!plugged)
|
||||
nv50_mstm_remove(nv_encoder->dp.mstm);
|
||||
}
|
||||
|
||||
drm_helper_hpd_irq_event(connector->dev);
|
||||
nv50_mstm_remove(nv_encoder->dp.mstm);
|
||||
}
|
||||
|
||||
drm_helper_hpd_irq_event(connector->dev);
|
||||
|
||||
pm_runtime_mark_last_busy(drm->dev->dev);
|
||||
pm_runtime_put_autosuspend(drm->dev->dev);
|
||||
return NVIF_NOTIFY_KEEP;
|
||||
|
|
Загрузка…
Ссылка в новой задаче