{
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
* 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))
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,
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
{
struct drm_atomic_state *state;
struct drm_connector *conn;
+ struct drm_connector_list_iter conn_iter;
int err;
state = drm_atomic_state_alloc(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;
err = drm_atomic_commit(state);
free:
+ drm_connector_list_iter_put(&conn_iter);
drm_atomic_state_put(state);
return err;
}
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;
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;
break;
}
}
+ drm_connector_list_iter_put(&conn_iter);
crtc_state->active = active;
ret = drm_atomic_commit(state);
{
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;
}
}
- 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;
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;
/*
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);
/* 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;
/* 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);
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;
}
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;
/* 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;
connector->encoder = new_encoder;
}
}
+ drm_connector_list_iter_put(&conn_iter);
if (fail) {
ret = -EINVAL;
}
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;
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) {
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)
}
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
{
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;
}
{
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;
}
{
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 =
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;
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 ||
}
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);
{
struct drm_device *dev = crtc->dev;
struct drm_connector *connector;
+ struct drm_connector_list_iter conn_iter;
int count = 0;
/*
*/
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;
count++;
}
}
+ drm_connector_list_iter_put(&conn_iter);
return count;
}
{
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));
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;
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;
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;
changed = true;
}
}
+ drm_connector_list_iter_put(&conn_iter);
mutex_unlock(&dev->mode_config.mutex);
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;
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;
if (old_status != connector->status)
changed = true;
}
-
+ drm_connector_list_iter_put(&conn_iter);
mutex_unlock(&dev->mode_config.mutex);
if (changed)