Skip to content

Commit 8c4ccc4

Browse files
committed
drm/probe-helper: Grab mode_config.mutex in poll_init/enable
So on first looks this seems superflous since drivers should ensure correct ordering to not make this a problem. Otoh ordering constraints between hdp, fbdev load and enabling polling are already tricky on some hardware and it helps to be more robust. But the real goal is to just shut up a locking WARN_ON I'd like to add, which means init code gets some additional locks just for uniformity. v2: Also grab the lock for the public poll_enable, not just poll_init which is used for resume, with the same justification. Reviewed-by: Maarten Lankhorst <[email protected]> Signed-off-by: Daniel Vetter <[email protected]>
1 parent 6295d60 commit 8c4ccc4

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

drivers/gpu/drm/drm_probe_helper.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
9393
return 1;
9494
}
9595

96+
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
97+
static void __drm_kms_helper_poll_enable(struct drm_device *dev)
98+
{
99+
bool poll = false;
100+
struct drm_connector *connector;
101+
102+
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
103+
104+
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
105+
return;
106+
107+
drm_for_each_connector(connector, dev) {
108+
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
109+
DRM_CONNECTOR_POLL_DISCONNECT))
110+
poll = true;
111+
}
112+
113+
if (poll)
114+
schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
115+
}
116+
96117
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
97118
uint32_t maxX, uint32_t maxY, bool merge_type_bits)
98119
{
@@ -153,7 +174,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
153174

154175
/* Re-enable polling in case the global poll config changed. */
155176
if (drm_kms_helper_poll != dev->mode_config.poll_running)
156-
drm_kms_helper_poll_enable(dev);
177+
__drm_kms_helper_poll_enable(dev);
157178

158179
dev->mode_config.poll_running = drm_kms_helper_poll;
159180

@@ -295,7 +316,6 @@ void drm_kms_helper_hotplug_event(struct drm_device *dev)
295316
}
296317
EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
297318

298-
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
299319
static void output_poll_execute(struct work_struct *work)
300320
{
301321
struct delayed_work *delayed_work = to_delayed_work(work);
@@ -407,20 +427,9 @@ EXPORT_SYMBOL(drm_kms_helper_poll_disable);
407427
*/
408428
void drm_kms_helper_poll_enable(struct drm_device *dev)
409429
{
410-
bool poll = false;
411-
struct drm_connector *connector;
412-
413-
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
414-
return;
415-
416-
drm_for_each_connector(connector, dev) {
417-
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
418-
DRM_CONNECTOR_POLL_DISCONNECT))
419-
poll = true;
420-
}
421-
422-
if (poll)
423-
schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
430+
mutex_lock(&dev->mode_config.mutex);
431+
__drm_kms_helper_poll_enable(dev);
432+
mutex_unlock(&dev->mode_config.mutex);
424433
}
425434
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
426435

0 commit comments

Comments
 (0)