* 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 mode)
+int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
+ int mode)
{
struct drm_mode_config *config = &connector->dev->mode_config;
struct drm_atomic_state *state;
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;
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));
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);
/* 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);
* 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;
}
}
- return;
+ return 0;
}
EXPORT_SYMBOL(drm_helper_connector_dpms);
}
/* 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);
mode = DRM_MODE_DPMS_OFF;
if (mode == connector->dpms)
- return;
+ return 0;
old_dpms = connector->dpms;
connector->dpms = mode;
crtc = encoder->base.crtc;
if (!crtc) {
encoder->connectors_active = false;
- return;
+ return 0;
}
/* We need the pipe to run for anything but OFF. */
}
intel_modeset_check_state(connector->dev);
+
+ return 0;
}
static enum drm_mode_status
/* 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;
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
void intel_encoder_destroy(struct drm_encoder *encoder);
int intel_connector_init(struct intel_connector *);
struct intel_connector *intel_connector_alloc(void);
-void intel_connector_dpms(struct drm_connector *, int mode);
+int intel_connector_dpms(struct drm_connector *, int mode);
bool intel_connector_get_hw_state(struct intel_connector *connector);
void intel_modeset_check_state(struct drm_device *dev);
bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,
}
/* Special dpms function to support cloning between dvo/sdvo/crt. */
-static void intel_dvo_dpms(struct drm_connector *connector, int mode)
+static int intel_dvo_dpms(struct drm_connector *connector, int mode)
{
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
struct drm_crtc *crtc;
mode = DRM_MODE_DPMS_OFF;
if (mode == connector->dpms)
- return;
+ return 0;
connector->dpms = mode;
crtc = intel_dvo->base.base.crtc;
if (!crtc) {
intel_dvo->base.connectors_active = false;
- return;
+ return 0;
}
/* We call connector dpms manually below in case pipe dpms doesn't
}
intel_modeset_check_state(connector->dev);
+
+ return 0;
}
static enum drm_mode_status
}
/* Special dpms function to support cloning between dvo/sdvo/crt. */
-static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
+static int intel_sdvo_dpms(struct drm_connector *connector, int mode)
{
struct drm_crtc *crtc;
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
mode = DRM_MODE_DPMS_OFF;
if (mode == connector->dpms)
- return;
+ return 0;
connector->dpms = mode;
crtc = intel_sdvo->base.base.crtc;
if (!crtc) {
intel_sdvo->base.connectors_active = false;
- return;
+ return 0;
}
/* We set active outputs manually below in case pipe dpms doesn't change
}
intel_modeset_check_state(connector->dev);
+
+ return 0;
}
static enum drm_mode_status
.force = nouveau_connector_force
};
-static void
+static int
nouveau_connector_dp_dpms(struct drm_connector *connector, int mode)
{
struct nouveau_encoder *nv_encoder = NULL;
}
}
- drm_helper_connector_dpms(connector, mode);
+ return drm_helper_connector_dpms(connector, mode);
}
static const struct drm_connector_funcs
kfree(radeon_connector);
}
-static void radeon_connector_dpms(struct drm_connector *connector, int mode)
+static int radeon_connector_dpms(struct drm_connector *connector, int mode)
{
DRM_DEBUG_KMS("\n");
+ return 0;
}
static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {
tegra_dsi_soft_reset(dsi->slave);
}
-static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
+static int tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
{
+ return 0;
}
static void tegra_dsi_connector_reset(struct drm_connector *connector)
return drm_detect_hdmi_monitor(edid);
}
-static void tegra_hdmi_connector_dpms(struct drm_connector *connector,
- int mode)
+static int tegra_hdmi_connector_dpms(struct drm_connector *connector,
+ int mode)
{
+ return 0;
}
static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
tegra_dc_writel(dc, table[i].value, table[i].offset);
}
-static void tegra_rgb_connector_dpms(struct drm_connector *connector,
- int mode)
+static int tegra_rgb_connector_dpms(struct drm_connector *connector,
+ int mode)
{
+ return 0;
}
static const struct drm_connector_funcs tegra_rgb_connector_funcs = {
sor->debugfs_files = NULL;
}
-static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
+static int tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
{
+ return 0;
}
static enum drm_connector_status
}
}
-void vmw_du_connector_dpms(struct drm_connector *connector, int mode)
+int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
{
+ return 0;
}
void vmw_du_connector_save(struct drm_connector *connector)
int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
uint32_t handle, uint32_t width, uint32_t height);
int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
-void vmw_du_connector_dpms(struct drm_connector *connector, int mode);
+int vmw_du_connector_dpms(struct drm_connector *connector, int mode);
void vmw_du_connector_save(struct drm_connector *connector);
void vmw_du_connector_restore(struct drm_connector *connector);
enum drm_connector_status
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t flags);
-void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
- int mode);
+int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
+ int mode);
/* default implementations for state handling */
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
* etc.
*/
struct drm_connector_funcs {
- void (*dpms)(struct drm_connector *connector, int mode);
+ int (*dpms)(struct drm_connector *connector, int mode);
void (*save)(struct drm_connector *connector);
void (*restore)(struct drm_connector *connector);
void (*reset)(struct drm_connector *connector);
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
-extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
+extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode);
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *);