forked from Minki/linux
drm: Convert all helpers to drm_connector_list_iter
Mostly nothing special (except making sure that really all error paths and friends call iter_put). v2: Don't forget the raw connector_list walking in drm_helper_move_panel_connectors_to_head. That one unfortunately can't be converted to the iterator helpers, but since it's just some list splicing best to just wrap the entire thing up in one critical section. v3: Bail out after iter_put (Harry). Cc: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Harry Wentland <harry.wentland@amd.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/20161215155843.13408-1-daniel.vetter@ffwll.ch
This commit is contained in:
parent
613051dac4
commit
c36a3254f7
@ -94,9 +94,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
|
||||
{
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_encoder *encoder;
|
||||
unsigned encoder_mask = 0;
|
||||
int i, ret;
|
||||
int i, ret = 0;
|
||||
|
||||
/*
|
||||
* First loop, find all newly assigned encoders from the connectors
|
||||
@ -144,7 +145,8 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
|
||||
* and the crtc is disabled if no encoder is left. This preserves
|
||||
* compatibility with the legacy set_config behavior.
|
||||
*/
|
||||
drm_for_each_connector(connector, state->dev) {
|
||||
drm_connector_list_iter_get(state->dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
if (drm_atomic_get_existing_connector_state(state, connector))
|
||||
@ -160,12 +162,15 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
|
||||
connector->state->crtc->base.id,
|
||||
connector->state->crtc->name,
|
||||
connector->base.id, connector->name);
|
||||
return -EINVAL;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
conn_state = drm_atomic_get_connector_state(state, connector);
|
||||
if (IS_ERR(conn_state))
|
||||
return PTR_ERR(conn_state);
|
||||
if (IS_ERR(conn_state)) {
|
||||
ret = PTR_ERR(conn_state);
|
||||
goto out;
|
||||
}
|
||||
|
||||
DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
|
||||
encoder->base.id, encoder->name,
|
||||
@ -176,19 +181,21 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
|
||||
|
||||
ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
if (!crtc_state->connector_mask) {
|
||||
ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
|
||||
NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
crtc_state->active = false;
|
||||
}
|
||||
}
|
||||
out:
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2442,6 +2449,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_connector *conn;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int err;
|
||||
|
||||
state = drm_atomic_state_alloc(dev);
|
||||
@ -2450,7 +2458,8 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
|
||||
|
||||
state->acquire_ctx = ctx;
|
||||
|
||||
drm_for_each_connector(conn, dev) {
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
struct drm_crtc *crtc = conn->state->crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
@ -2468,6 +2477,7 @@ int drm_atomic_helper_disable_all(struct drm_device *dev,
|
||||
|
||||
err = drm_atomic_commit(state);
|
||||
free:
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
drm_atomic_state_put(state);
|
||||
return err;
|
||||
}
|
||||
@ -2840,6 +2850,7 @@ int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_connector *tmp_connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int ret;
|
||||
bool active = false;
|
||||
int old_mode = connector->dpms;
|
||||
@ -2867,7 +2878,8 @@ retry:
|
||||
|
||||
WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
|
||||
|
||||
drm_for_each_connector(tmp_connector, connector->dev) {
|
||||
drm_connector_list_iter_get(connector->dev, &conn_iter);
|
||||
drm_for_each_connector_iter(tmp_connector, &conn_iter) {
|
||||
if (tmp_connector->state->crtc != crtc)
|
||||
continue;
|
||||
|
||||
@ -2876,6 +2888,7 @@ retry:
|
||||
break;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
crtc_state->active = active;
|
||||
|
||||
ret = drm_atomic_commit(state);
|
||||
@ -3253,6 +3266,7 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
|
||||
{
|
||||
struct drm_atomic_state *state;
|
||||
struct drm_connector *conn;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
struct drm_plane *plane;
|
||||
struct drm_crtc *crtc;
|
||||
int err = 0;
|
||||
@ -3283,15 +3297,18 @@ drm_atomic_helper_duplicate_state(struct drm_device *dev,
|
||||
}
|
||||
}
|
||||
|
||||
drm_for_each_connector(conn, dev) {
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(conn, &conn_iter) {
|
||||
struct drm_connector_state *conn_state;
|
||||
|
||||
conn_state = drm_atomic_get_connector_state(state, conn);
|
||||
if (IS_ERR(conn_state)) {
|
||||
err = PTR_ERR(conn_state);
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
goto free;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
|
||||
/* clear the acquire context so that it isn't accidentally reused */
|
||||
state->acquire_ctx = NULL;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -120,20 +120,22 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
|
||||
{
|
||||
struct drm_device *dev = fb_helper->dev;
|
||||
struct drm_connector *connector;
|
||||
int i, ret;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int i, ret = 0;
|
||||
|
||||
if (!drm_fbdev_emulation)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_for_each_connector(connector, dev) {
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
ret = drm_fb_helper_add_one_connector(fb_helper, connector);
|
||||
|
||||
if (ret)
|
||||
goto fail;
|
||||
}
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
fail:
|
||||
drm_fb_helper_for_each_connector(fb_helper, i) {
|
||||
struct drm_fb_helper_connector *fb_helper_connector =
|
||||
@ -145,6 +147,8 @@ fail:
|
||||
fb_helper->connector_info[i] = NULL;
|
||||
}
|
||||
fb_helper->connector_count = 0;
|
||||
out:
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -48,6 +48,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
|
||||
|
||||
INIT_LIST_HEAD(&panel_list);
|
||||
|
||||
spin_lock_irq(&dev->mode_config.connector_list_lock);
|
||||
list_for_each_entry_safe(connector, tmp,
|
||||
&dev->mode_config.connector_list, head) {
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
|
||||
@ -57,6 +58,7 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
|
||||
}
|
||||
|
||||
list_splice(&panel_list, &dev->mode_config.connector_list);
|
||||
spin_unlock_irq(&dev->mode_config.connector_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
|
||||
|
||||
|
@ -75,6 +75,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
int count = 0;
|
||||
|
||||
/*
|
||||
@ -84,7 +85,8 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
|
||||
*/
|
||||
WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
|
||||
|
||||
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_list != NULL && count < num_connectors)
|
||||
*(connector_list++) = connector;
|
||||
@ -92,6 +94,7 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
|
||||
count++;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
|
||||
{
|
||||
bool poll = false;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
|
||||
@ -136,11 +137,13 @@ void drm_kms_helper_poll_enable_locked(struct drm_device *dev)
|
||||
if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
|
||||
return;
|
||||
|
||||
drm_for_each_connector(connector, dev) {
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
|
||||
DRM_CONNECTOR_POLL_DISCONNECT))
|
||||
poll = true;
|
||||
}
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
|
||||
if (dev->mode_config.delayed_event) {
|
||||
poll = true;
|
||||
@ -382,6 +385,7 @@ static void output_poll_execute(struct work_struct *work)
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
enum drm_connector_status old_status;
|
||||
bool repoll = false, changed;
|
||||
|
||||
@ -397,8 +401,8 @@ static void output_poll_execute(struct work_struct *work)
|
||||
goto out;
|
||||
}
|
||||
|
||||
drm_for_each_connector(connector, dev) {
|
||||
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
/* Ignore forced connectors. */
|
||||
if (connector->force)
|
||||
continue;
|
||||
@ -451,6 +455,7 @@ static void output_poll_execute(struct work_struct *work)
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
@ -562,6 +567,7 @@ EXPORT_SYMBOL(drm_kms_helper_poll_fini);
|
||||
bool drm_helper_hpd_irq_event(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_list_iter conn_iter;
|
||||
enum drm_connector_status old_status;
|
||||
bool changed = false;
|
||||
|
||||
@ -569,8 +575,8 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
|
||||
return false;
|
||||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_for_each_connector(connector, dev) {
|
||||
|
||||
drm_connector_list_iter_get(dev, &conn_iter);
|
||||
drm_for_each_connector_iter(connector, &conn_iter) {
|
||||
/* Only handle HPD capable connectors. */
|
||||
if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
|
||||
continue;
|
||||
@ -586,7 +592,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev)
|
||||
if (old_status != connector->status)
|
||||
changed = true;
|
||||
}
|
||||
|
||||
drm_connector_list_iter_put(&conn_iter);
|
||||
mutex_unlock(&dev->mode_config.mutex);
|
||||
|
||||
if (changed)
|
||||
|
Loading…
Reference in New Issue
Block a user