diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index d4dc8cb45bce..e26ead5b5e58 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -760,27 +760,32 @@ static void output_poll_execute(struct work_struct *work) struct drm_connector *connector; struct drm_connector_list_iter conn_iter; enum drm_connector_status old_status; - bool repoll = false, changed; + bool repoll = false, changed = false; u64 old_epoch_counter; if (!dev->mode_config.poll_enabled) return; - /* Pick up any changes detected by the probe functions. */ - changed = dev->mode_config.delayed_event; - dev->mode_config.delayed_event = false; - if (!drm_kms_helper_poll) { if (dev->mode_config.poll_running) { drm_kms_helper_disable_hpd(dev); dev->mode_config.poll_running = false; } - goto out; + + scoped_guard(mutex, &dev->mode_config.mutex) { + changed = dev->mode_config.delayed_event; + dev->mode_config.delayed_event = false; + } + + if (changed) + drm_kms_helper_hotplug_event(dev); + + return; } if (!mutex_trylock(&dev->mode_config.mutex)) { - repoll = true; - goto out; + schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); + return; } drm_connector_list_iter_begin(dev, &conn_iter); @@ -836,16 +841,23 @@ static void output_poll_execute(struct work_struct *work) connector->base.id, connector->name, old_epoch_counter, connector->epoch_counter); + drm_sysfs_connector_hotplug_event(connector); changed = true; } } drm_connector_list_iter_end(&conn_iter); + /* Pick up any changes detected by the probe functions. */ + if (dev->mode_config.delayed_event) { + dev->mode_config.delayed_event = false; + changed = true; + drm_sysfs_hotplug_event(dev); + } + mutex_unlock(&dev->mode_config.mutex); -out: if (changed) - drm_kms_helper_hotplug_event(dev); + drm_client_dev_hotplug(dev); if (repoll) schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); @@ -1081,9 +1093,9 @@ EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event); */ bool drm_helper_hpd_irq_event(struct drm_device *dev) { - struct drm_connector *connector, *first_changed_connector = NULL; struct drm_connector_list_iter conn_iter; - int changed = 0; + struct drm_connector *connector; + bool changed = false; if (!dev->mode_config.poll_enabled) return false; @@ -1096,24 +1108,15 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) continue; if (check_connector_changed(connector)) { - if (!first_changed_connector) { - drm_connector_get(connector); - first_changed_connector = connector; - } - - changed++; + changed = true; + drm_sysfs_connector_hotplug_event(connector); } } drm_connector_list_iter_end(&conn_iter); mutex_unlock(&dev->mode_config.mutex); - if (changed == 1) - drm_kms_helper_connector_hotplug_event(first_changed_connector); - else if (changed > 0) - drm_kms_helper_hotplug_event(dev); - - if (first_changed_connector) - drm_connector_put(first_changed_connector); + if (changed) + drm_client_dev_hotplug(dev); return changed; }