@ -89,6 +89,7 @@
bool drm_helper_encoder_in_use ( struct drm_encoder * encoder )
{
struct drm_connector * connector ;
struct drm_connector_list_iter conn_iter ;
struct drm_device * dev = encoder - > dev ;
/*
@ -100,9 +101,15 @@ bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
WARN_ON ( ! drm_modeset_is_locked ( & dev - > mode_config . connection_mutex ) ) ;
}
drm_for_each_connector ( connector , dev )
if ( connector - > encoder = = encoder )
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter ) {
if ( connector - > encoder = = encoder ) {
drm_connector_list_iter_put ( & conn_iter ) ;
return true ;
}
}
drm_connector_list_iter_put ( & conn_iter ) ;
return false ;
}
EXPORT_SYMBOL ( drm_helper_encoder_in_use ) ;
@ -437,10 +444,13 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
/* Decouple all encoders and their attached connectors from this crtc */
drm_for_each_encoder ( encoder , dev ) {
struct drm_connector_list_iter conn_iter ;
if ( encoder - > crtc ! = crtc )
continue ;
drm_for_each_connector ( connector , dev ) {
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter ) {
if ( connector - > encoder ! = encoder )
continue ;
@ -457,6 +467,7 @@ drm_crtc_helper_disable(struct drm_crtc *crtc)
/* we keep a reference while the encoder is bound */
drm_connector_unreference ( connector ) ;
}
drm_connector_list_iter_put ( & conn_iter ) ;
}
__drm_helper_disable_unused_functions ( dev ) ;
@ -508,6 +519,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
bool mode_changed = false ; /* if true do a full mode set */
bool fb_changed = false ; /* if true and !mode_changed just do a flip */
struct drm_connector * connector ;
struct drm_connector_list_iter conn_iter ;
int count = 0 , ro , fail = 0 ;
const struct drm_crtc_helper_funcs * crtc_funcs ;
struct drm_mode_set save_set ;
@ -572,9 +584,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
count = 0 ;
drm_for_each_connector ( connector , dev ) {
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter )
save_connector_encoders [ count + + ] = connector - > encoder ;
}
drm_connector_list_iter_put ( & conn_iter ) ;
save_set . crtc = set - > crtc ;
save_set . mode = & set - > crtc - > mode ;
@ -616,7 +629,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
/* a) traverse passed in connector list and get encoders for them */
count = 0 ;
drm_for_each_connector ( connector , dev ) {
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter ) {
const struct drm_connector_helper_funcs * connector_funcs =
connector - > helper_private ;
new_encoder = connector - > encoder ;
@ -649,6 +663,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
connector - > encoder = new_encoder ;
}
}
drm_connector_list_iter_put ( & conn_iter ) ;
if ( fail ) {
ret = - EINVAL ;
@ -656,7 +671,8 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
}
count = 0 ;
drm_for_each_connector ( connector , dev ) {
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter ) {
if ( ! connector - > encoder )
continue ;
@ -674,6 +690,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
if ( new_crtc & &
! drm_encoder_crtc_ok ( connector - > encoder , new_crtc ) ) {
ret = - EINVAL ;
drm_connector_list_iter_put ( & conn_iter ) ;
goto fail ;
}
if ( new_crtc ! = connector - > encoder - > crtc ) {
@ -690,6 +707,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
connector - > base . id , connector - > name ) ;
}
}
drm_connector_list_iter_put ( & conn_iter ) ;
/* mode_set_base is not a required function */
if ( fb_changed & & ! crtc_funcs - > mode_set_base )
@ -744,9 +762,10 @@ fail:
}
count = 0 ;
drm_for_each_connector ( connector , dev ) {
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter )
connector - > encoder = save_connector_encoders [ count + + ] ;
}
drm_connector_list_iter_put ( & conn_iter ) ;
/* after fail drop reference on all unbound connectors in set, let
* bound connectors keep their reference
@ -773,12 +792,16 @@ static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
{
int dpms = DRM_MODE_DPMS_OFF ;
struct drm_connector * connector ;
struct drm_connector_list_iter conn_iter ;
struct drm_device * dev = encoder - > dev ;
drm_for_each_connector ( connector , dev )
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter )
if ( connector - > encoder = = encoder )
if ( connector - > dpms < dpms )
dpms = connector - > dpms ;
drm_connector_list_iter_put ( & conn_iter ) ;
return dpms ;
}
@ -810,12 +833,16 @@ static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
{
int dpms = DRM_MODE_DPMS_OFF ;
struct drm_connector * connector ;
struct drm_connector_list_iter conn_iter ;
struct drm_device * dev = crtc - > dev ;
drm_for_each_connector ( connector , dev )
drm_connector_list_iter_get ( dev , & conn_iter ) ;
drm_for_each_connector_iter ( connector , & conn_iter )
if ( connector - > encoder & & connector - > encoder - > crtc = = crtc )
if ( connector - > dpms < dpms )
dpms = connector - > dpms ;
drm_connector_list_iter_put ( & conn_iter ) ;
return dpms ;
}