drivers/accel/habanalabs/common/irq.c

Source file repositories/reference/linux-study-clean/drivers/accel/habanalabs/common/irq.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/habanalabs/common/irq.c
Extension
.c
Size
19444 bytes
Lines
727
Domain
Driver Families
Bucket
drivers/accel
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 hl_eqe_work {
	struct work_struct	eq_work;
	struct hl_device	*hdev;
	struct hl_eq_entry	eq_entry;
};

/**
 * hl_cq_inc_ptr - increment ci or pi of cq
 *
 * @ptr: the current ci or pi value of the completion queue
 *
 * Increment ptr by 1. If it reaches the number of completion queue
 * entries, set it to 0
 */
inline u32 hl_cq_inc_ptr(u32 ptr)
{
	ptr++;
	if (unlikely(ptr == HL_CQ_LENGTH))
		ptr = 0;
	return ptr;
}

/**
 * hl_eq_inc_ptr - increment ci of eq
 *
 * @ptr: the current ci value of the event queue
 *
 * Increment ptr by 1. If it reaches the number of event queue
 * entries, set it to 0
 */
static inline u32 hl_eq_inc_ptr(u32 ptr)
{
	ptr++;
	if (unlikely(ptr == HL_EQ_LENGTH))
		ptr = 0;
	return ptr;
}

static void irq_handle_eqe(struct work_struct *work)
{
	struct hl_eqe_work *eqe_work = container_of(work, struct hl_eqe_work,
							eq_work);
	struct hl_device *hdev = eqe_work->hdev;

	hdev->asic_funcs->handle_eqe(hdev, &eqe_work->eq_entry);

	kfree(eqe_work);
}

/**
 * job_finish - queue job finish work
 *
 * @hdev: pointer to device structure
 * @cs_seq: command submission sequence
 * @cq: completion queue
 * @timestamp: interrupt timestamp
 *
 */
static void job_finish(struct hl_device *hdev, u32 cs_seq, struct hl_cq *cq, ktime_t timestamp)
{
	struct hl_hw_queue *queue;
	struct hl_cs_job *job;

	queue = &hdev->kernel_queues[cq->hw_queue_id];
	job = queue->shadow_queue[hl_pi_2_offset(cs_seq)];
	job->timestamp = timestamp;
	queue_work(hdev->cq_wq[cq->cq_idx], &job->finish_work);

	atomic_inc(&queue->ci);
}

/**
 * cs_finish - queue all cs jobs finish work
 *
 * @hdev: pointer to device structure
 * @cs_seq: command submission sequence
 * @timestamp: interrupt timestamp
 *
 */
static void cs_finish(struct hl_device *hdev, u16 cs_seq, ktime_t timestamp)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	struct hl_hw_queue *queue;
	struct hl_cs *cs;
	struct hl_cs_job *job;

	cs = hdev->shadow_cs_queue[cs_seq & (prop->max_pending_cs - 1)];
	if (!cs) {
		dev_warn(hdev->dev,
			"No pointer to CS in shadow array at index %d\n",

Annotation

Implementation Notes