diff options
author | Dave Airlie <airlied@redhat.com> | 2017-01-26 21:04:08 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-01-26 21:04:08 -0500 |
commit | c4d79c22015564a9d922715434a0ec09d1deee30 (patch) | |
tree | 0244663e07ce8575d6060d0f1dae9d8fef30e829 | |
parent | b0df0b251b25b0bf89ef3e518330fcac300add86 (diff) |
Reinstate "drm/probe-helpers: Drop locking from poll_enable""
This reverts commit 54a07c7bb0da0343734c78212bbe9f3735394962,
and reinstates the original.
[airlied: this might be a bad plan for git].
commit 3846fd9b86001bea171943cc3bb9222cb6da6b42
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Wed Jan 11 10:01:17 2017 +0100
drm/probe-helpers: Drop locking from poll_enable
It was only needed to protect the connector_list walking, see
commit 8c4ccc4ab6f64e859d4ff8d7c02c2ed2e956e07f
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Thu Jul 9 23:44:26 2015 +0200
drm/probe-helper: Grab mode_config.mutex in poll_init/enable
Unfortunately the commit message of that patch fails to mention that
the new locking check was for the connector_list.
But that requirement disappeared in
commit c36a3254f7857f1ad9badbe3578ccc92be541a8e
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Thu Dec 15 16:58:43 2016 +0100
drm: Convert all helpers to drm_connector_list_iter
and so we can drop this again.
This fixes a locking inversion on nouveau, where the rpm code needs to
re-enable. But in other places the rpm_get() calls are nested within
the big modeset locks.
While at it, also improve the kerneldoc for these two functions a
notch.
v2: Update the kerneldoc even more to explain that these functions
can't be called concurrently, or bad things happen (Chris).
-rw-r--r-- | drivers/gpu/drm/drm_probe_helper.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_hotplug.c | 4 | ||||
-rw-r--r-- | include/drm/drm_crtc_helper.h | 1 |
3 files changed, 22 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 79519e4983c7..041a5504780f 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c | |||
@@ -115,25 +115,28 @@ static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) | |||
115 | 115 | ||
116 | #define DRM_OUTPUT_POLL_PERIOD (10*HZ) | 116 | #define DRM_OUTPUT_POLL_PERIOD (10*HZ) |
117 | /** | 117 | /** |
118 | * drm_kms_helper_poll_enable_locked - re-enable output polling. | 118 | * drm_kms_helper_poll_enable - re-enable output polling. |
119 | * @dev: drm_device | 119 | * @dev: drm_device |
120 | * | 120 | * |
121 | * This function re-enables the output polling work without | 121 | * This function re-enables the output polling work, after it has been |
122 | * locking the mode_config mutex. | 122 | * temporarily disabled using drm_kms_helper_poll_disable(), for example over |
123 | * suspend/resume. | ||
123 | * | 124 | * |
124 | * This is like drm_kms_helper_poll_enable() however it is to be | 125 | * Drivers can call this helper from their device resume implementation. It is |
125 | * called from a context where the mode_config mutex is locked | 126 | * an error to call this when the output polling support has not yet been set |
126 | * already. | 127 | * up. |
128 | * | ||
129 | * Note that calls to enable and disable polling must be strictly ordered, which | ||
130 | * is automatically the case when they're only call from suspend/resume | ||
131 | * callbacks. | ||
127 | */ | 132 | */ |
128 | void drm_kms_helper_poll_enable_locked(struct drm_device *dev) | 133 | void drm_kms_helper_poll_enable(struct drm_device *dev) |
129 | { | 134 | { |
130 | bool poll = false; | 135 | bool poll = false; |
131 | struct drm_connector *connector; | 136 | struct drm_connector *connector; |
132 | struct drm_connector_list_iter conn_iter; | 137 | struct drm_connector_list_iter conn_iter; |
133 | unsigned long delay = DRM_OUTPUT_POLL_PERIOD; | 138 | unsigned long delay = DRM_OUTPUT_POLL_PERIOD; |
134 | 139 | ||
135 | WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); | ||
136 | |||
137 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) | 140 | if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) |
138 | return; | 141 | return; |
139 | 142 | ||
@@ -163,7 +166,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev) | |||
163 | if (poll) | 166 | if (poll) |
164 | schedule_delayed_work(&dev->mode_config.output_poll_work, delay); | 167 | schedule_delayed_work(&dev->mode_config.output_poll_work, delay); |
165 | } | 168 | } |
166 | EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked); | 169 | EXPORT_SYMBOL(drm_kms_helper_poll_enable); |
167 | 170 | ||
168 | static enum drm_connector_status | 171 | static enum drm_connector_status |
169 | drm_connector_detect(struct drm_connector *connector, bool force) | 172 | drm_connector_detect(struct drm_connector *connector, bool force) |
@@ -290,7 +293,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
290 | 293 | ||
291 | /* Re-enable polling in case the global poll config changed. */ | 294 | /* Re-enable polling in case the global poll config changed. */ |
292 | if (drm_kms_helper_poll != dev->mode_config.poll_running) | 295 | if (drm_kms_helper_poll != dev->mode_config.poll_running) |
293 | drm_kms_helper_poll_enable_locked(dev); | 296 | drm_kms_helper_poll_enable(dev); |
294 | 297 | ||
295 | dev->mode_config.poll_running = drm_kms_helper_poll; | 298 | dev->mode_config.poll_running = drm_kms_helper_poll; |
296 | 299 | ||
@@ -484,8 +487,12 @@ out: | |||
484 | * This function disables the output polling work. | 487 | * This function disables the output polling work. |
485 | * | 488 | * |
486 | * Drivers can call this helper from their device suspend implementation. It is | 489 | * Drivers can call this helper from their device suspend implementation. It is |
487 | * not an error to call this even when output polling isn't enabled or arlready | 490 | * not an error to call this even when output polling isn't enabled or already |
488 | * disabled. | 491 | * disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable(). |
492 | * | ||
493 | * Note that calls to enable and disable polling must be strictly ordered, which | ||
494 | * is automatically the case when they're only call from suspend/resume | ||
495 | * callbacks. | ||
489 | */ | 496 | */ |
490 | void drm_kms_helper_poll_disable(struct drm_device *dev) | 497 | void drm_kms_helper_poll_disable(struct drm_device *dev) |
491 | { | 498 | { |
@@ -496,24 +503,6 @@ void drm_kms_helper_poll_disable(struct drm_device *dev) | |||
496 | EXPORT_SYMBOL(drm_kms_helper_poll_disable); | 503 | EXPORT_SYMBOL(drm_kms_helper_poll_disable); |
497 | 504 | ||
498 | /** | 505 | /** |
499 | * drm_kms_helper_poll_enable - re-enable output polling. | ||
500 | * @dev: drm_device | ||
501 | * | ||
502 | * This function re-enables the output polling work. | ||
503 | * | ||
504 | * Drivers can call this helper from their device resume implementation. It is | ||
505 | * an error to call this when the output polling support has not yet been set | ||
506 | * up. | ||
507 | */ | ||
508 | void drm_kms_helper_poll_enable(struct drm_device *dev) | ||
509 | { | ||
510 | mutex_lock(&dev->mode_config.mutex); | ||
511 | drm_kms_helper_poll_enable_locked(dev); | ||
512 | mutex_unlock(&dev->mode_config.mutex); | ||
513 | } | ||
514 | EXPORT_SYMBOL(drm_kms_helper_poll_enable); | ||
515 | |||
516 | /** | ||
517 | * drm_kms_helper_poll_init - initialize and enable output polling | 506 | * drm_kms_helper_poll_init - initialize and enable output polling |
518 | * @dev: drm_device | 507 | * @dev: drm_device |
519 | * | 508 | * |
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 3d546c019de0..b62e3f8ad415 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c | |||
@@ -180,7 +180,7 @@ static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv) | |||
180 | 180 | ||
181 | /* Enable polling and queue hotplug re-enabling. */ | 181 | /* Enable polling and queue hotplug re-enabling. */ |
182 | if (hpd_disabled) { | 182 | if (hpd_disabled) { |
183 | drm_kms_helper_poll_enable_locked(dev); | 183 | drm_kms_helper_poll_enable(dev); |
184 | mod_delayed_work(system_wq, &dev_priv->hotplug.reenable_work, | 184 | mod_delayed_work(system_wq, &dev_priv->hotplug.reenable_work, |
185 | msecs_to_jiffies(HPD_STORM_REENABLE_DELAY)); | 185 | msecs_to_jiffies(HPD_STORM_REENABLE_DELAY)); |
186 | } | 186 | } |
@@ -511,7 +511,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) | |||
511 | } | 511 | } |
512 | 512 | ||
513 | if (enabled) | 513 | if (enabled) |
514 | drm_kms_helper_poll_enable_locked(dev); | 514 | drm_kms_helper_poll_enable(dev); |
515 | 515 | ||
516 | mutex_unlock(&dev->mode_config.mutex); | 516 | mutex_unlock(&dev->mode_config.mutex); |
517 | 517 | ||
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 982c299e435a..d026f5017c33 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
@@ -73,6 +73,5 @@ extern void drm_kms_helper_hotplug_event(struct drm_device *dev); | |||
73 | 73 | ||
74 | extern void drm_kms_helper_poll_disable(struct drm_device *dev); | 74 | extern void drm_kms_helper_poll_disable(struct drm_device *dev); |
75 | extern void drm_kms_helper_poll_enable(struct drm_device *dev); | 75 | extern void drm_kms_helper_poll_enable(struct drm_device *dev); |
76 | extern void drm_kms_helper_poll_enable_locked(struct drm_device *dev); | ||
77 | 76 | ||
78 | #endif | 77 | #endif |