drivers/gpu/drm/drm_client_modeset.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/drm_client_modeset.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_client_modeset.c
Extension
.c
Size
34724 bytes
Lines
1344
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct drm_client_offset {
	int x, y;
};

int drm_client_modeset_create(struct drm_client_dev *client)
{
	struct drm_device *dev = client->dev;
	unsigned int num_crtc = dev->mode_config.num_crtc;
	unsigned int max_connector_count = 1;
	struct drm_mode_set *modeset;
	struct drm_crtc *crtc;
	int i = 0;

	/* Add terminating zero entry to enable index less iteration */
	client->modesets = kzalloc_objs(*client->modesets, num_crtc + 1);
	if (!client->modesets)
		return -ENOMEM;

	mutex_init(&client->modeset_mutex);

	drm_for_each_crtc(crtc, dev)
		client->modesets[i++].crtc = crtc;

	/* Cloning is only supported in the single crtc case. */
	if (num_crtc == 1)
		max_connector_count = DRM_CLIENT_MAX_CLONED_CONNECTORS;

	for (modeset = client->modesets; modeset->crtc; modeset++) {
		modeset->connectors = kzalloc_objs(*modeset->connectors,
						   max_connector_count);
		if (!modeset->connectors)
			goto err_free;
	}

	return 0;

err_free:
	drm_client_modeset_free(client);

	return -ENOMEM;
}

static void drm_client_modeset_release(struct drm_client_dev *client)
{
	struct drm_mode_set *modeset;

	drm_client_for_each_modeset(modeset, client) {
		int i;

		drm_mode_destroy(client->dev, modeset->mode);
		modeset->mode = NULL;
		modeset->fb = NULL;

		for (i = 0; i < modeset->num_connectors; i++) {
			drm_connector_put(modeset->connectors[i]);
			modeset->connectors[i] = NULL;
		}
		modeset->num_connectors = 0;
	}
}

void drm_client_modeset_free(struct drm_client_dev *client)
{
	struct drm_mode_set *modeset;

	mutex_lock(&client->modeset_mutex);

	drm_client_modeset_release(client);

	drm_client_for_each_modeset(modeset, client)
		kfree(modeset->connectors);

	mutex_unlock(&client->modeset_mutex);

	mutex_destroy(&client->modeset_mutex);
	kfree(client->modesets);
}

static struct drm_mode_set *
drm_client_find_modeset(struct drm_client_dev *client, struct drm_crtc *crtc)
{
	struct drm_mode_set *modeset;

	drm_client_for_each_modeset(modeset, client)
		if (modeset->crtc == crtc)
			return modeset;

	return NULL;
}

Annotation

Implementation Notes