drivers/gpu/drm/drm_debugfs_crc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_debugfs_crc.c
Extension
.c
Size
12097 bytes
Lines
440
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations drm_crtc_crc_control_fops = {
	.owner = THIS_MODULE,
	.open = crc_control_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = single_release,
	.write = crc_control_write
};

static int crtc_crc_data_count(struct drm_crtc_crc *crc)
{
	assert_spin_locked(&crc->lock);
	return CIRC_CNT(crc->head, crc->tail, DRM_CRC_ENTRIES_NR);
}

static void crtc_crc_cleanup(struct drm_crtc_crc *crc)
{
	kfree(crc->entries);
	crc->overflow = false;
	crc->entries = NULL;
	crc->head = 0;
	crc->tail = 0;
	crc->values_cnt = 0;
	crc->opened = false;
}

static int crtc_crc_open(struct inode *inode, struct file *filep)
{
	struct drm_crtc *crtc = inode->i_private;
	struct drm_crtc_crc *crc = &crtc->crc;
	struct drm_crtc_crc_entry *entries = NULL;
	size_t values_cnt;
	int ret = 0;

	if (drm_drv_uses_atomic_modeset(crtc->dev)) {
		ret = drm_modeset_lock_single_interruptible(&crtc->mutex);
		if (ret)
			return ret;

		if (!crtc->state->active)
			ret = -EIO;
		drm_modeset_unlock(&crtc->mutex);

		if (ret)
			return ret;
	}

	ret = crtc->funcs->verify_crc_source(crtc, crc->source, &values_cnt);
	if (ret)
		return ret;

	if (WARN_ON(values_cnt > DRM_MAX_CRC_NR))
		return -EINVAL;

	if (WARN_ON(values_cnt == 0))
		return -EINVAL;

	entries = kzalloc_objs(*entries, DRM_CRC_ENTRIES_NR);
	if (!entries)
		return -ENOMEM;

	spin_lock_irq(&crc->lock);
	if (!crc->opened) {
		crc->opened = true;
		crc->entries = entries;
		crc->values_cnt = values_cnt;
	} else {
		ret = -EBUSY;
	}
	spin_unlock_irq(&crc->lock);

	if (ret) {
		kfree(entries);
		return ret;
	}

	ret = crtc->funcs->set_crc_source(crtc, crc->source);
	if (ret)
		goto err;

	return 0;

err:
	spin_lock_irq(&crc->lock);
	crtc_crc_cleanup(crc);
	spin_unlock_irq(&crc->lock);
	return ret;
}

static int crtc_crc_release(struct inode *inode, struct file *filep)

Annotation

Implementation Notes