drivers/soc/ti/knav_qmss_queue.c

Source file repositories/reference/linux-study-clean/drivers/soc/ti/knav_qmss_queue.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/ti/knav_qmss_queue.c
Extension
.c
Size
47733 bytes
Lines
1892
Domain
Driver Families
Bucket
drivers/soc
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

if (range->irqs[queue].cpu_mask) {
			ret = irq_set_affinity_hint(irq, range->irqs[queue].cpu_mask);
			if (ret) {
				dev_warn(range->kdev->dev,
					 "Failed to set IRQ affinity\n");
				return ret;
			}
		}
	}
	return ret;
}

static void knav_queue_free_irq(struct knav_queue_inst *inst)
{
	struct knav_range_info *range = inst->range;
	unsigned queue = inst->id - inst->range->queue_base;
	int irq;

	if (range->flags & RANGE_HAS_IRQ) {
		irq = range->irqs[queue].irq;
		irq_set_affinity_hint(irq, NULL);
		free_irq(irq, inst);
	}
}

static inline bool knav_queue_is_busy(struct knav_queue_inst *inst)
{
	return !list_empty(&inst->handles);
}

static inline bool knav_queue_is_reserved(struct knav_queue_inst *inst)
{
	return inst->range->flags & RANGE_RESERVED;
}

static inline bool knav_queue_is_shared(struct knav_queue_inst *inst)
{
	struct knav_queue *tmp;

	rcu_read_lock();
	for_each_handle_rcu(tmp, inst) {
		if (tmp->flags & KNAV_QUEUE_SHARED) {
			rcu_read_unlock();
			return true;
		}
	}
	rcu_read_unlock();
	return false;
}

static inline bool knav_queue_match_type(struct knav_queue_inst *inst,
						unsigned type)
{
	if ((type == KNAV_QUEUE_QPEND) &&
	    (inst->range->flags & RANGE_HAS_IRQ)) {
		return true;
	} else if ((type == KNAV_QUEUE_ACC) &&
		(inst->range->flags & RANGE_HAS_ACCUMULATOR)) {
		return true;
	} else if ((type == KNAV_QUEUE_GP) &&
		!(inst->range->flags &
			(RANGE_HAS_ACCUMULATOR | RANGE_HAS_IRQ))) {
		return true;
	}
	return false;
}

static inline struct knav_queue_inst *
knav_queue_match_id_to_inst(struct knav_device *kdev, unsigned id)
{
	struct knav_queue_inst *inst;
	int idx;

	for_each_instance(idx, inst, kdev) {
		if (inst->id == id)
			return inst;
	}
	return NULL;
}

static inline struct knav_queue_inst *knav_queue_find_by_id(int id)
{
	if (knav_qdev->base_id <= id &&
	    knav_qdev->base_id + knav_qdev->num_queues > id) {
		id -= knav_qdev->base_id;
		return knav_queue_match_id_to_inst(knav_qdev, id);
	}
	return NULL;
}

Annotation

Implementation Notes