Commit 6857f879 authored by Lyude Paul's avatar Lyude Paul
Browse files

drm/amdgpu: Iterate through DRM connectors correctly



Currently, every single piece of code in amdgpu that loops through
connectors does it incorrectly and doesn't use the proper list iteration
helpers, drm_connector_list_iter_begin() and
drm_connector_list_iter_end(). Yeesh.

So, do that.

Cc: Juston Li <juston.li@intel.com>
Cc: Imre Deak <imre.deak@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Harry Wentland <hwentlan@amd.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarLyude Paul <lyude@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191022023641.8026-12-lyude@redhat.com
parent ac0de16a
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -1019,8 +1019,12 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
			 */
			if (amdgpu_connector->shared_ddc && (ret == connector_status_connected)) {
				struct drm_connector *list_connector;
				struct drm_connector_list_iter iter;
				struct amdgpu_connector *list_amdgpu_connector;
				list_for_each_entry(list_connector, &dev->mode_config.connector_list, head) {

				drm_connector_list_iter_begin(dev, &iter);
				drm_for_each_connector_iter(list_connector,
							    &iter) {
					if (connector == list_connector)
						continue;
					list_amdgpu_connector = to_amdgpu_connector(list_connector);
@@ -1037,6 +1041,7 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
						}
					}
				}
				drm_connector_list_iter_end(&iter);
			}
		}
	}
@@ -1494,6 +1499,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
{
	struct drm_device *dev = adev->ddev;
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;
	struct amdgpu_connector *amdgpu_connector;
	struct amdgpu_connector_atom_dig *amdgpu_dig_connector;
	struct drm_encoder *encoder;
@@ -1508,10 +1514,12 @@ amdgpu_connector_add(struct amdgpu_device *adev,
		return;

	/* see if we already added it */
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_connector_list_iter_begin(dev, &iter);
	drm_for_each_connector_iter(connector, &iter) {
		amdgpu_connector = to_amdgpu_connector(connector);
		if (amdgpu_connector->connector_id == connector_id) {
			amdgpu_connector->devices |= supported_device;
			drm_connector_list_iter_end(&iter);
			return;
		}
		if (amdgpu_connector->ddc_bus && i2c_bus->valid) {
@@ -1526,6 +1534,7 @@ amdgpu_connector_add(struct amdgpu_device *adev,
			}
		}
	}
	drm_connector_list_iter_end(&iter);

	/* check if it's a dp bridge */
	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+14 −6
Original line number Diff line number Diff line
@@ -3007,6 +3007,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
	struct amdgpu_device *adev;
	struct drm_crtc *crtc;
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;
	int r;

	if (dev == NULL || dev->dev_private == NULL) {
@@ -3029,9 +3030,11 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
	if (!amdgpu_device_has_dc_support(adev)) {
		/* turn off display hw */
		drm_modeset_lock_all(dev);
		list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
		}
		drm_connector_list_iter_begin(dev, &iter);
		drm_for_each_connector_iter(connector, &iter)
			drm_helper_connector_dpms(connector,
						  DRM_MODE_DPMS_OFF);
		drm_connector_list_iter_end(&iter);
		drm_modeset_unlock_all(dev);
			/* unpin the front buffers and cursors */
		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
@@ -3110,6 +3113,7 @@ int amdgpu_device_suspend(struct drm_device *dev, bool suspend, bool fbcon)
int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
{
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;
	struct amdgpu_device *adev = dev->dev_private;
	struct drm_crtc *crtc;
	int r = 0;
@@ -3180,9 +3184,13 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)

			/* turn on display hw */
			drm_modeset_lock_all(dev);
			list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
				drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
			}

			drm_connector_list_iter_begin(dev, &iter);
			drm_for_each_connector_iter(connector, &iter)
				drm_helper_connector_dpms(connector,
							  DRM_MODE_DPMS_ON);
			drm_connector_list_iter_end(&iter);

			drm_modeset_unlock_all(dev);
		}
		amdgpu_fbdev_set_suspend(adev, 0);
+4 −1
Original line number Diff line number Diff line
@@ -370,11 +370,13 @@ void amdgpu_display_print_display_setup(struct drm_device *dev)
	struct amdgpu_connector *amdgpu_connector;
	struct drm_encoder *encoder;
	struct amdgpu_encoder *amdgpu_encoder;
	struct drm_connector_list_iter iter;
	uint32_t devices;
	int i = 0;

	drm_connector_list_iter_begin(dev, &iter);
	DRM_INFO("AMDGPU Display Connectors\n");
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_for_each_connector_iter(connector, &iter) {
		amdgpu_connector = to_amdgpu_connector(connector);
		DRM_INFO("Connector %d:\n", i);
		DRM_INFO("  %s\n", connector->name);
@@ -438,6 +440,7 @@ void amdgpu_display_print_display_setup(struct drm_device *dev)
		}
		i++;
	}
	drm_connector_list_iter_end(&iter);
}

/**
+28 −12
Original line number Diff line number Diff line
@@ -37,12 +37,14 @@ amdgpu_link_encoder_connector(struct drm_device *dev)
{
	struct amdgpu_device *adev = dev->dev_private;
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;
	struct amdgpu_connector *amdgpu_connector;
	struct drm_encoder *encoder;
	struct amdgpu_encoder *amdgpu_encoder;

	drm_connector_list_iter_begin(dev, &iter);
	/* walk the list and link encoders to connectors */
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_for_each_connector_iter(connector, &iter) {
		amdgpu_connector = to_amdgpu_connector(connector);
		list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
			amdgpu_encoder = to_amdgpu_encoder(encoder);
@@ -55,6 +57,7 @@ amdgpu_link_encoder_connector(struct drm_device *dev)
			}
		}
	}
	drm_connector_list_iter_end(&iter);
}

void amdgpu_encoder_set_active_device(struct drm_encoder *encoder)
@@ -62,8 +65,10 @@ void amdgpu_encoder_set_active_device(struct drm_encoder *encoder)
	struct drm_device *dev = encoder->dev;
	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_connector_list_iter_begin(dev, &iter);
	drm_for_each_connector_iter(connector, &iter) {
		if (connector->encoder == encoder) {
			struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
			amdgpu_encoder->active_device = amdgpu_encoder->devices & amdgpu_connector->devices;
@@ -72,6 +77,7 @@ void amdgpu_encoder_set_active_device(struct drm_encoder *encoder)
				  amdgpu_connector->devices, encoder->encoder_type);
		}
	}
	drm_connector_list_iter_end(&iter);
}

struct drm_connector *
@@ -79,15 +85,20 @@ amdgpu_get_connector_for_encoder(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
	struct drm_connector *connector;
	struct drm_connector *connector, *found = NULL;
	struct drm_connector_list_iter iter;
	struct amdgpu_connector *amdgpu_connector;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_connector_list_iter_begin(dev, &iter);
	drm_for_each_connector_iter(connector, &iter) {
		amdgpu_connector = to_amdgpu_connector(connector);
		if (amdgpu_encoder->active_device & amdgpu_connector->devices)
			return connector;
		if (amdgpu_encoder->active_device & amdgpu_connector->devices) {
			found = connector;
			break;
		}
	return NULL;
	}
	drm_connector_list_iter_end(&iter);
	return found;
}

struct drm_connector *
@@ -95,15 +106,20 @@ amdgpu_get_connector_for_encoder_init(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
	struct drm_connector *connector;
	struct drm_connector *connector, *found = NULL;
	struct drm_connector_list_iter iter;
	struct amdgpu_connector *amdgpu_connector;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
	drm_connector_list_iter_begin(dev, &iter);
	drm_for_each_connector_iter(connector, &iter) {
		amdgpu_connector = to_amdgpu_connector(connector);
		if (amdgpu_encoder->devices & amdgpu_connector->devices)
			return connector;
		if (amdgpu_encoder->devices & amdgpu_connector->devices) {
			found = connector;
			break;
		}
	return NULL;
	}
	drm_connector_list_iter_end(&iter);
	return found;
}

struct drm_encoder *amdgpu_get_external_encoder(struct drm_encoder *encoder)
+4 −1
Original line number Diff line number Diff line
@@ -87,10 +87,13 @@ static void amdgpu_hotplug_work_func(struct work_struct *work)
	struct drm_device *dev = adev->ddev;
	struct drm_mode_config *mode_config = &dev->mode_config;
	struct drm_connector *connector;
	struct drm_connector_list_iter iter;

	mutex_lock(&mode_config->mutex);
	list_for_each_entry(connector, &mode_config->connector_list, head)
	drm_connector_list_iter_begin(dev, &iter);
	drm_for_each_connector_iter(connector, &iter)
		amdgpu_connector_hotplug(connector);
	drm_connector_list_iter_end(&iter);
	mutex_unlock(&mode_config->mutex);
	/* Just fire off a uevent and let userspace tell us what to do */
	drm_helper_hpd_irq_event(dev);
Loading