drivers/video/fbdev/core/fb_defio.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/core/fb_defio.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/core/fb_defio.c
Extension
.c
Size
12553 bytes
Lines
480
Domain
Driver Families
Bucket
drivers/video
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 fb_deferred_io_state {
	struct kref ref;

	int open_count; /* number of opened files; protected by fb_info lock */
	struct address_space *mapping; /* page cache object for fb device */

	struct mutex lock; /* mutex that protects the pageref list */
	/* fields protected by lock */
	struct fb_info *info;
	struct list_head pagereflist; /* list of pagerefs for touched pages */
	unsigned long npagerefs;
	struct fb_deferred_io_pageref *pagerefs;
};

static struct fb_deferred_io_state *fb_deferred_io_state_alloc(unsigned long len)
{
	struct fb_deferred_io_state *fbdefio_state;
	struct fb_deferred_io_pageref *pagerefs;
	unsigned long npagerefs;

	fbdefio_state = kzalloc_obj(*fbdefio_state);
	if (!fbdefio_state)
		return NULL;

	npagerefs = DIV_ROUND_UP(len, PAGE_SIZE);

	/* alloc a page ref for each page of the display memory */
	pagerefs = kvzalloc_objs(*pagerefs, npagerefs);
	if (!pagerefs)
		goto err_kfree;
	fbdefio_state->npagerefs = npagerefs;
	fbdefio_state->pagerefs = pagerefs;

	kref_init(&fbdefio_state->ref);
	mutex_init(&fbdefio_state->lock);

	INIT_LIST_HEAD(&fbdefio_state->pagereflist);

	return fbdefio_state;

err_kfree:
	kfree(fbdefio_state);
	return NULL;
}

static void fb_deferred_io_state_release(struct fb_deferred_io_state *fbdefio_state)
{
	WARN_ON(!list_empty(&fbdefio_state->pagereflist));
	mutex_destroy(&fbdefio_state->lock);
	kvfree(fbdefio_state->pagerefs);

	kfree(fbdefio_state);
}

static void fb_deferred_io_state_get(struct fb_deferred_io_state *fbdefio_state)
{
	kref_get(&fbdefio_state->ref);
}

static void __fb_deferred_io_state_release(struct kref *ref)
{
	struct fb_deferred_io_state *fbdefio_state =
		container_of(ref, struct fb_deferred_io_state, ref);

	fb_deferred_io_state_release(fbdefio_state);
}

static void fb_deferred_io_state_put(struct fb_deferred_io_state *fbdefio_state)
{
	kref_put(&fbdefio_state->ref, __fb_deferred_io_state_release);
}

/*
 * struct vm_operations_struct
 */

static void fb_deferred_io_vm_open(struct vm_area_struct *vma)
{
	struct fb_deferred_io_state *fbdefio_state = vma->vm_private_data;

	WARN_ON_ONCE(!try_module_get(THIS_MODULE));
	fb_deferred_io_state_get(fbdefio_state);
}

static void fb_deferred_io_vm_close(struct vm_area_struct *vma)
{
	struct fb_deferred_io_state *fbdefio_state = vma->vm_private_data;

	fb_deferred_io_state_put(fbdefio_state);
	module_put(THIS_MODULE);

Annotation

Implementation Notes