Skip to content

Commit 9a69a9a

Browse files
mlankhorstdanvet
authored andcommitted
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: Maarten Lankhorst <[email protected]> [danvet: Resolve conflicts due to different merge order.] Signed-off-by: Daniel Vetter <[email protected]>
1 parent 613d2b2 commit 9a69a9a

19 files changed

+65
-44
lines changed

drivers/gpu/drm/drm_atomic_helper.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,9 +1974,12 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
19741974
* implementing the legacy DPMS connector interface. It computes the new desired
19751975
* ->active state for the corresponding CRTC (if the connector is enabled) and
19761976
* updates it.
1977+
*
1978+
* Returns:
1979+
* Returns 0 on success, negative errno numbers on failure.
19771980
*/
1978-
void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
1979-
int mode)
1981+
int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
1982+
int mode)
19801983
{
19811984
struct drm_mode_config *config = &connector->dev->mode_config;
19821985
struct drm_atomic_state *state;
@@ -1985,6 +1988,7 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
19851988
struct drm_connector *tmp_connector;
19861989
int ret;
19871990
bool active = false;
1991+
int old_mode = connector->dpms;
19881992

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

19951999
if (!crtc)
1996-
return;
2000+
return 0;
19972001

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

20032006
state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
20042007
retry:
20052008
crtc_state = drm_atomic_get_crtc_state(state, crtc);
2006-
if (IS_ERR(crtc_state))
2007-
return;
2009+
if (IS_ERR(crtc_state)) {
2010+
ret = PTR_ERR(crtc_state);
2011+
goto fail;
2012+
}
20082013

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

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

2026-
/* Driver takes ownership of state on successful async commit. */
2027-
return;
2031+
/* Driver takes ownership of state on successful commit. */
2032+
return 0;
20282033
fail:
20292034
if (ret == -EDEADLK)
20302035
goto backoff;
20312036

2037+
connector->dpms = old_mode;
20322038
drm_atomic_state_free(state);
20332039

2034-
WARN(1, "Driver bug: Changing ->active failed with ret=%i\n", ret);
2035-
2036-
return;
2040+
return ret;
20372041
backoff:
20382042
drm_atomic_state_clear(state);
20392043
drm_atomic_legacy_backoff(state);

drivers/gpu/drm/drm_crtc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4753,9 +4753,9 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,
47534753

47544754
/* Do DPMS ourselves */
47554755
if (property == connector->dev->mode_config.dpms_property) {
4756-
if (connector->funcs->dpms)
4757-
(*connector->funcs->dpms)(connector, (int)value);
47584756
ret = 0;
4757+
if (connector->funcs->dpms)
4758+
ret = (*connector->funcs->dpms)(connector, (int)value);
47594759
} else if (connector->funcs->set_property)
47604760
ret = connector->funcs->set_property(connector, property, value);
47614761

drivers/gpu/drm/drm_crtc_helper.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -762,15 +762,18 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
762762
* implementing the DPMS connector attribute. It computes the new desired DPMS
763763
* state for all encoders and crtcs in the output mesh and calls the ->dpms()
764764
* callback provided by the driver appropriately.
765+
*
766+
* Returns:
767+
* Always returns 0.
765768
*/
766-
void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
769+
int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
767770
{
768771
struct drm_encoder *encoder = connector->encoder;
769772
struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
770773
int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
771774

772775
if (mode == connector->dpms)
773-
return;
776+
return 0;
774777

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

805-
return;
808+
return 0;
806809
}
807810
EXPORT_SYMBOL(drm_helper_connector_dpms);
808811

drivers/gpu/drm/i915/intel_crt.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static void intel_enable_crt(struct intel_encoder *encoder)
237237
}
238238

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

251251
if (mode == connector->dpms)
252-
return;
252+
return 0;
253253

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

264264
/* 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)
281281
}
282282

283283
intel_modeset_check_state(connector->dev);
284+
285+
return 0;
284286
}
285287

286288
static enum drm_mode_status

drivers/gpu/drm/i915/intel_display.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6429,14 +6429,14 @@ struct intel_connector *intel_connector_alloc(void)
64296429

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

64386438
if (mode == connector->dpms)
6439-
return;
6439+
return 0;
64406440

64416441
connector->dpms = mode;
64426442

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

64476447
intel_modeset_check_state(connector->dev);
6448+
6449+
return 0;
64486450
}
64496451

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

drivers/gpu/drm/i915/intel_drv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,7 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc);
997997
void intel_encoder_destroy(struct drm_encoder *encoder);
998998
int intel_connector_init(struct intel_connector *);
999999
struct intel_connector *intel_connector_alloc(void);
1000-
void intel_connector_dpms(struct drm_connector *, int mode);
1000+
int intel_connector_dpms(struct drm_connector *, int mode);
10011001
bool intel_connector_get_hw_state(struct intel_connector *connector);
10021002
void intel_modeset_check_state(struct drm_device *dev);
10031003
bool ibx_digital_port_connected(struct drm_i915_private *dev_priv,

drivers/gpu/drm/i915/intel_dvo.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ static void intel_enable_dvo(struct intel_encoder *encoder)
197197
}
198198

199199
/* Special dpms function to support cloning between dvo/sdvo/crt. */
200-
static void intel_dvo_dpms(struct drm_connector *connector, int mode)
200+
static int intel_dvo_dpms(struct drm_connector *connector, int mode)
201201
{
202202
struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
203203
struct drm_crtc *crtc;
@@ -208,15 +208,15 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
208208
mode = DRM_MODE_DPMS_OFF;
209209

210210
if (mode == connector->dpms)
211-
return;
211+
return 0;
212212

213213
connector->dpms = mode;
214214

215215
/* Only need to change hw state when actually enabled */
216216
crtc = intel_dvo->base.base.crtc;
217217
if (!crtc) {
218218
intel_dvo->base.connectors_active = false;
219-
return;
219+
return 0;
220220
}
221221

222222
/* We call connector dpms manually below in case pipe dpms doesn't
@@ -238,6 +238,8 @@ static void intel_dvo_dpms(struct drm_connector *connector, int mode)
238238
}
239239

240240
intel_modeset_check_state(connector->dev);
241+
242+
return 0;
241243
}
242244

243245
static enum drm_mode_status

drivers/gpu/drm/i915/intel_sdvo.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,7 +1509,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
15091509
}
15101510

15111511
/* Special dpms function to support cloning between dvo/sdvo/crt. */
1512-
static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
1512+
static int intel_sdvo_dpms(struct drm_connector *connector, int mode)
15131513
{
15141514
struct drm_crtc *crtc;
15151515
struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
@@ -1519,15 +1519,15 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
15191519
mode = DRM_MODE_DPMS_OFF;
15201520

15211521
if (mode == connector->dpms)
1522-
return;
1522+
return 0;
15231523

15241524
connector->dpms = mode;
15251525

15261526
/* Only need to change hw state when actually enabled */
15271527
crtc = intel_sdvo->base.base.crtc;
15281528
if (!crtc) {
15291529
intel_sdvo->base.connectors_active = false;
1530-
return;
1530+
return 0;
15311531
}
15321532

15331533
/* We set active outputs manually below in case pipe dpms doesn't change
@@ -1551,6 +1551,8 @@ static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
15511551
}
15521552

15531553
intel_modeset_check_state(connector->dev);
1554+
1555+
return 0;
15541556
}
15551557

15561558
static enum drm_mode_status

drivers/gpu/drm/nouveau/nouveau_connector.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -919,7 +919,7 @@ nouveau_connector_funcs_lvds = {
919919
.force = nouveau_connector_force
920920
};
921921

922-
static void
922+
static int
923923
nouveau_connector_dp_dpms(struct drm_connector *connector, int mode)
924924
{
925925
struct nouveau_encoder *nv_encoder = NULL;
@@ -938,7 +938,7 @@ nouveau_connector_dp_dpms(struct drm_connector *connector, int mode)
938938
}
939939
}
940940

941-
drm_helper_connector_dpms(connector, mode);
941+
return drm_helper_connector_dpms(connector, mode);
942942
}
943943

944944
static const struct drm_connector_funcs

drivers/gpu/drm/radeon/radeon_dp_mst.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,10 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector)
246246
kfree(radeon_connector);
247247
}
248248

249-
static void radeon_connector_dpms(struct drm_connector *connector, int mode)
249+
static int radeon_connector_dpms(struct drm_connector *connector, int mode)
250250
{
251251
DRM_DEBUG_KMS("\n");
252+
return 0;
252253
}
253254

254255
static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {

drivers/gpu/drm/tegra/dsi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,9 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi)
726726
tegra_dsi_soft_reset(dsi->slave);
727727
}
728728

729-
static void tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
729+
static int tegra_dsi_connector_dpms(struct drm_connector *connector, int mode)
730730
{
731+
return 0;
731732
}
732733

733734
static void tegra_dsi_connector_reset(struct drm_connector *connector)

drivers/gpu/drm/tegra/hdmi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,9 +772,10 @@ static bool tegra_output_is_hdmi(struct tegra_output *output)
772772
return drm_detect_hdmi_monitor(edid);
773773
}
774774

775-
static void tegra_hdmi_connector_dpms(struct drm_connector *connector,
776-
int mode)
775+
static int tegra_hdmi_connector_dpms(struct drm_connector *connector,
776+
int mode)
777777
{
778+
return 0;
778779
}
779780

780781
static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {

drivers/gpu/drm/tegra/rgb.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ static void tegra_dc_write_regs(struct tegra_dc *dc,
8888
tegra_dc_writel(dc, table[i].value, table[i].offset);
8989
}
9090

91-
static void tegra_rgb_connector_dpms(struct drm_connector *connector,
92-
int mode)
91+
static int tegra_rgb_connector_dpms(struct drm_connector *connector,
92+
int mode)
9393
{
94+
return 0;
9495
}
9596

9697
static const struct drm_connector_funcs tegra_rgb_connector_funcs = {

drivers/gpu/drm/tegra/sor.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,8 +866,9 @@ static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
866866
sor->debugfs_files = NULL;
867867
}
868868

869-
static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
869+
static int tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
870870
{
871+
return 0;
871872
}
872873

873874
static enum drm_connector_status

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,8 +1808,9 @@ void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
18081808
}
18091809
}
18101810

1811-
void vmw_du_connector_dpms(struct drm_connector *connector, int mode)
1811+
int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
18121812
{
1813+
return 0;
18131814
}
18141815

18151816
void vmw_du_connector_save(struct drm_connector *connector)

drivers/gpu/drm/vmwgfx/vmwgfx_kms.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
133133
int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
134134
uint32_t handle, uint32_t width, uint32_t height);
135135
int vmw_du_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
136-
void vmw_du_connector_dpms(struct drm_connector *connector, int mode);
136+
int vmw_du_connector_dpms(struct drm_connector *connector, int mode);
137137
void vmw_du_connector_save(struct drm_connector *connector);
138138
void vmw_du_connector_restore(struct drm_connector *connector);
139139
enum drm_connector_status

include/drm/drm_atomic_helper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
8787
struct drm_framebuffer *fb,
8888
struct drm_pending_vblank_event *event,
8989
uint32_t flags);
90-
void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
91-
int mode);
90+
int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
91+
int mode);
9292

9393
/* default implementations for state handling */
9494
void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);

include/drm/drm_crtc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ struct drm_connector_state {
527527
* etc.
528528
*/
529529
struct drm_connector_funcs {
530-
void (*dpms)(struct drm_connector *connector, int mode);
530+
int (*dpms)(struct drm_connector *connector, int mode);
531531
void (*save)(struct drm_connector *connector);
532532
void (*restore)(struct drm_connector *connector);
533533
void (*reset)(struct drm_connector *connector);

include/drm/drm_crtc_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
189189
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
190190
extern bool drm_helper_encoder_in_use(struct drm_encoder *encoder);
191191

192-
extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);
192+
extern int drm_helper_connector_dpms(struct drm_connector *connector, int mode);
193193

194194
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *);
195195

0 commit comments

Comments
 (0)