drivers/soc/fsl/dpio/dpio-service.c

Source file repositories/reference/linux-study-clean/drivers/soc/fsl/dpio/dpio-service.c

File Facts

System
Linux kernel
Corpus path
drivers/soc/fsl/dpio/dpio-service.c
Extension
.c
Size
24486 bytes
Lines
899
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

struct dpaa2_io {
	struct dpaa2_io_desc dpio_desc;
	struct qbman_swp_desc swp_desc;
	struct qbman_swp *swp;
	struct list_head node;
	/* protect against multiple management commands */
	spinlock_t lock_mgmt_cmd;
	/* protect notifications list */
	spinlock_t lock_notifications;
	struct list_head notifications;
	struct device *dev;

	/* Net DIM */
	struct dim rx_dim;
	/* protect against concurrent Net DIM updates */
	spinlock_t dim_lock;
	u16 event_ctr;
	u64 bytes;
	u64 frames;
};

struct dpaa2_io_store {
	unsigned int max;
	dma_addr_t paddr;
	struct dpaa2_dq *vaddr;
	void *alloced_addr;    /* unaligned value from kmalloc() */
	unsigned int idx;      /* position of the next-to-be-returned entry */
	struct qbman_swp *swp; /* portal used to issue VDQCR */
	struct device *dev;    /* device used for DMA mapping */
};

/* keep a per cpu array of DPIOs for fast access */
static struct dpaa2_io *dpio_by_cpu[NR_CPUS];
static struct list_head dpio_list = LIST_HEAD_INIT(dpio_list);
static DEFINE_SPINLOCK(dpio_list_lock);

static inline struct dpaa2_io *service_select_by_cpu(struct dpaa2_io *d,
						     int cpu)
{
	if (d)
		return d;

	if (cpu != DPAA2_IO_ANY_CPU && cpu >= num_possible_cpus())
		return NULL;

	/*
	 * If cpu == -1, choose the current cpu, with no guarantees about
	 * potentially being migrated away.
	 */
	if (cpu < 0)
		cpu = raw_smp_processor_id();

	/* If a specific cpu was requested, pick it up immediately */
	return dpio_by_cpu[cpu];
}

static inline struct dpaa2_io *service_select(struct dpaa2_io *d)
{
	if (d)
		return d;

	d = service_select_by_cpu(d, -1);
	if (d)
		return d;

	spin_lock(&dpio_list_lock);
	d = list_entry(dpio_list.next, struct dpaa2_io, node);
	list_del(&d->node);
	list_add_tail(&d->node, &dpio_list);
	spin_unlock(&dpio_list_lock);

	return d;
}

/**
 * dpaa2_io_service_select() - return a dpaa2_io service affined to this cpu
 * @cpu: the cpu id
 *
 * Return the affine dpaa2_io service, or NULL if there is no service affined
 * to the specified cpu. If DPAA2_IO_ANY_CPU is used, return the next available
 * service.
 */
struct dpaa2_io *dpaa2_io_service_select(int cpu)
{
	if (cpu == DPAA2_IO_ANY_CPU)
		return service_select(NULL);

	return service_select_by_cpu(NULL, cpu);
}
EXPORT_SYMBOL_GPL(dpaa2_io_service_select);

Annotation

Implementation Notes