drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c

Source file repositories/reference/linux-study-clean/drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c

File Facts

System
Linux kernel
Corpus path
drivers/staging/media/atomisp/pci/base/refcount/src/refcount.c
Extension
.c
Size
5828 bytes
Lines
268
Domain
Driver Families
Bucket
drivers/staging
Inferred role
Driver Families: implementation source
Status
source 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 ia_css_refcount_entry {
	u32 count;
	ia_css_ptr data;
	s32 id;
};

struct ia_css_refcount_list {
	u32 size;
	struct ia_css_refcount_entry *items;
};

static struct ia_css_refcount_list myrefcount;

static struct ia_css_refcount_entry *refcount_find_entry(ia_css_ptr ptr,
	bool firstfree)
{
	u32 i;

	if (ptr == 0)
		return NULL;
	if (!myrefcount.items) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
				    "%s(): Ref count not initialized!\n", __func__);
		return NULL;
	}

	for (i = 0; i < myrefcount.size; i++) {
		if ((&myrefcount.items[i])->data == 0) {
			if (firstfree) {
				/* for new entry */
				return &myrefcount.items[i];
			}
		}
		if ((&myrefcount.items[i])->data == ptr) {
			/* found entry */
			return &myrefcount.items[i];
		}
	}
	return NULL;
}

int ia_css_refcount_init(uint32_t size)
{
	int err = 0;

	if (size == 0) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
				    "%s(): Size of 0 for Ref count init!\n", __func__);
		return -EINVAL;
	}
	if (myrefcount.items) {
		ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
				    "%s(): Ref count is already initialized\n", __func__);
		return -EINVAL;
	}
	myrefcount.items =
	    kvmalloc(sizeof(struct ia_css_refcount_entry) * size, GFP_KERNEL);
	if (!myrefcount.items)
		err = -ENOMEM;
	if (!err) {
		memset(myrefcount.items, 0,
		       sizeof(struct ia_css_refcount_entry) * size);
		myrefcount.size = size;
	}
	return err;
}

void ia_css_refcount_uninit(void)
{
	struct ia_css_refcount_entry *entry;
	u32 i;

	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
			    "%s() entry\n", __func__);
	for (i = 0; i < myrefcount.size; i++) {
		/* driver verifier tool has issues with &arr[i]
		   and prefers arr + i; as these are actually equivalent
		   the line below uses + i
		*/
		entry = myrefcount.items + i;
		if (entry->data != mmgr_NULL) {
			/*	ia_css_debug_dtrace(IA_CSS_DBG_TRACE,
				"ia_css_refcount_uninit: freeing (%x)\n",
				entry->data);*/
			hmm_free(entry->data);
			entry->data = mmgr_NULL;
			entry->count = 0;
			entry->id = 0;
		}
	}

Annotation

Implementation Notes