Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a69a9ac authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Daniel Vetter
Browse files

drm: Make the connector dpms callback return a value, v2.



This is required to properly handle failing dpms calls.
When making a wait in i915 interruptible, I've noticed
that the dpms sequence could fail with -ERESTARTSYS because
it was waiting interruptibly for flips. So from now on
allow drivers to fail in their connector dpms callback.

Encoder and crtc dpms callbacks are unaffected.

Changes since v1:
- Update kerneldoc for the drm helper functions.

Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
[danvet: Resolve conflicts due to different merge order.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 613d2b27
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -1974,8 +1974,11 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
 * implementing the legacy DPMS connector interface. It computes the new desired
 * ->active state for the corresponding CRTC (if the connector is enabled) and
 *  updates it.
 *
 * Returns:
 * Returns 0 on success, negative errno numbers on failure.
 */
void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
				     int mode)
{
	struct drm_mode_config *config = &connector->dev->mode_config;
@@ -1985,6 +1988,7 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
	struct drm_connector *tmp_connector;
	int ret;
	bool active = false;
	int old_mode = connector->dpms;

	if (mode != DRM_MODE_DPMS_ON)
		mode = DRM_MODE_DPMS_OFF;
@@ -1993,18 +1997,19 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
	crtc = connector->state->crtc;

	if (!crtc)
		return;
		return 0;

	/* FIXME: ->dpms has no return value so can't forward the -ENOMEM. */
	state = drm_atomic_state_alloc(connector->dev);
	if (!state)
		return;
		return -ENOMEM;

	state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
retry:
	crtc_state = drm_atomic_get_crtc_state(state, crtc);
	if (IS_ERR(crtc_state))
		return;
	if (IS_ERR(crtc_state)) {
		ret = PTR_ERR(crtc_state);
		goto fail;
	}

	WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));

@@ -2023,17 +2028,16 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
	if (ret != 0)
		goto fail;

	/* Driver takes ownership of state on successful async commit. */
	return;
	/* Driver takes ownership of state on successful commit. */
	return 0;
fail:
	if (ret == -EDEADLK)
		goto backoff;

	connector->dpms = old_mode;
	drm_atomic_state_free(state);

	WARN(1, "Driver bug: Changing ->active failed with ret=%i\n", ret);

	return;
	return ret;
backoff:
	drm_atomic_state_clear(state);
	drm_atomic_legacy_backoff(state);
+2 −2
Original line number Diff line number Diff line
@@ -4753,9 +4753,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,

	/* Do DPMS ourselves */
	if (property == connector->dev->mode_config.dpms_property) {
		if (connector->funcs->dpms)
			(*connector->funcs->dpms)(connector, (int)value);
		ret = 0;
		if (connector->funcs->dpms)
			ret = (*connector->funcs->dpms)(connector, (int)value);
	} else if (connector->funcs->set_property)
		ret = connector->funcs->set_property(connector, property, value);

+6 −3
Original line number Diff line number Diff line
@@ -762,15 +762,18 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
 * implementing the DPMS connector attribute. It computes the new desired DPMS
 * state for all encoders and crtcs in the output mesh and calls the ->dpms()
 * callback provided by the driver appropriately.
 *
 * Returns:
 * Always returns 0.
 */
void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
{
	struct drm_encoder *encoder = connector->encoder;
	struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
	int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;

	if (mode == connector->dpms)
		return;
		return 0;

	old_dpms = connector->dpms;
	connector->dpms = mode;
@@ -802,7 +805,7 @@ void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
		}
	}

	return;
	return 0;
}
EXPORT_SYMBOL(drm_helper_connector_dpms);

+5 −3
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ static void intel_enable_crt(struct intel_encoder *encoder)
}

/* Special dpms function to support cloning between dvo/sdvo/crt. */
static void intel_crt_dpms(struct drm_connector *connector, int mode)
static int intel_crt_dpms(struct drm_connector *connector, int mode)
{
	struct drm_device *dev = connector->dev;
	struct intel_encoder *encoder = intel_attached_encoder(connector);
@@ -249,7 +249,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
		mode = DRM_MODE_DPMS_OFF;

	if (mode == connector->dpms)
		return;
		return 0;

	old_dpms = connector->dpms;
	connector->dpms = mode;
@@ -258,7 +258,7 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
	crtc = encoder->base.crtc;
	if (!crtc) {
		encoder->connectors_active = false;
		return;
		return 0;
	}

	/* We need the pipe to run for anything but OFF. */
@@ -281,6 +281,8 @@ static void intel_crt_dpms(struct drm_connector *connector, int mode)
	}

	intel_modeset_check_state(connector->dev);

	return 0;
}

static enum drm_mode_status
+4 −2
Original line number Diff line number Diff line
@@ -6429,14 +6429,14 @@ struct intel_connector *intel_connector_alloc(void)

/* Even simpler default implementation, if there's really no special case to
 * consider. */
void intel_connector_dpms(struct drm_connector *connector, int mode)
int intel_connector_dpms(struct drm_connector *connector, int mode)
{
	/* All the simple cases only support two dpms states. */
	if (mode != DRM_MODE_DPMS_ON)
		mode = DRM_MODE_DPMS_OFF;

	if (mode == connector->dpms)
		return;
		return 0;

	connector->dpms = mode;

@@ -6445,6 +6445,8 @@ void intel_connector_dpms(struct drm_connector *connector, int mode)
		intel_encoder_dpms(to_intel_encoder(connector->encoder), mode);

	intel_modeset_check_state(connector->dev);

	return 0;
}

/* Simple connector->get_hw_state implementation for encoders that support only
Loading