Skip to content

Commit c67b06f

Browse files
ideakrodrigovivi
authored andcommitted
drm: Add an HPD poll helper to reschedule the poll work
Add a helper to reschedule drm_mode_config::output_poll_work after polling has been enabled for a connector (and needing a reschedule, since previously polling was disabled for all connectors and hence output_poll_work was not running). This is needed by the next patch fixing HPD polling on i915. CC: stable@vger.kernel.org # 6.4+ Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Cc: dri-devel@lists.freedesktop.org Reviewed-by: Jouni Högander <jouni.hogander@intel.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230822113015.41224-1-imre.deak@intel.com (cherry picked from commit fe2352f) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
1 parent f2ac640 commit c67b06f

File tree

2 files changed

+47
-22
lines changed

2 files changed

+47
-22
lines changed

drivers/gpu/drm/drm_probe_helper.c

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,26 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
262262
}
263263

264264
#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
265+
static void reschedule_output_poll_work(struct drm_device *dev)
266+
{
267+
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
268+
269+
if (dev->mode_config.delayed_event)
270+
/*
271+
* FIXME:
272+
*
273+
* Use short (1s) delay to handle the initial delayed event.
274+
* This delay should not be needed, but Optimus/nouveau will
275+
* fail in a mysterious way if the delayed event is handled as
276+
* soon as possible like it is done in
277+
* drm_helper_probe_single_connector_modes() in case the poll
278+
* was enabled before.
279+
*/
280+
delay = HZ;
281+
282+
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
283+
}
284+
265285
/**
266286
* drm_kms_helper_poll_enable - re-enable output polling.
267287
* @dev: drm_device
@@ -279,37 +299,41 @@ static bool drm_kms_helper_enable_hpd(struct drm_device *dev)
279299
*/
280300
void drm_kms_helper_poll_enable(struct drm_device *dev)
281301
{
282-
bool poll = false;
283-
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
284-
285302
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll ||
286303
dev->mode_config.poll_running)
287304
return;
288305

289-
poll = drm_kms_helper_enable_hpd(dev);
290-
291-
if (dev->mode_config.delayed_event) {
292-
/*
293-
* FIXME:
294-
*
295-
* Use short (1s) delay to handle the initial delayed event.
296-
* This delay should not be needed, but Optimus/nouveau will
297-
* fail in a mysterious way if the delayed event is handled as
298-
* soon as possible like it is done in
299-
* drm_helper_probe_single_connector_modes() in case the poll
300-
* was enabled before.
301-
*/
302-
poll = true;
303-
delay = HZ;
304-
}
305-
306-
if (poll)
307-
schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
306+
if (drm_kms_helper_enable_hpd(dev) ||
307+
dev->mode_config.delayed_event)
308+
reschedule_output_poll_work(dev);
308309

309310
dev->mode_config.poll_running = true;
310311
}
311312
EXPORT_SYMBOL(drm_kms_helper_poll_enable);
312313

314+
/**
315+
* drm_kms_helper_poll_reschedule - reschedule the output polling work
316+
* @dev: drm_device
317+
*
318+
* This function reschedules the output polling work, after polling for a
319+
* connector has been enabled.
320+
*
321+
* Drivers must call this helper after enabling polling for a connector by
322+
* setting %DRM_CONNECTOR_POLL_CONNECT / %DRM_CONNECTOR_POLL_DISCONNECT flags
323+
* in drm_connector::polled. Note that after disabling polling by clearing these
324+
* flags for a connector will stop the output polling work automatically if
325+
* the polling is disabled for all other connectors as well.
326+
*
327+
* The function can be called only after polling has been enabled by calling
328+
* drm_kms_helper_poll_init() / drm_kms_helper_poll_enable().
329+
*/
330+
void drm_kms_helper_poll_reschedule(struct drm_device *dev)
331+
{
332+
if (dev->mode_config.poll_running)
333+
reschedule_output_poll_work(dev);
334+
}
335+
EXPORT_SYMBOL(drm_kms_helper_poll_reschedule);
336+
313337
static enum drm_connector_status
314338
drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
315339
{

include/drm/drm_probe_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector);
2525

2626
void drm_kms_helper_poll_disable(struct drm_device *dev);
2727
void drm_kms_helper_poll_enable(struct drm_device *dev);
28+
void drm_kms_helper_poll_reschedule(struct drm_device *dev);
2829
bool drm_kms_helper_is_poll_worker(void);
2930

3031
enum drm_mode_status drm_crtc_helper_mode_valid_fixed(struct drm_crtc *crtc,

0 commit comments

Comments
 (0)