drivers/net/can/sja1000/sja1000_platform.c

Source file repositories/reference/linux-study-clean/drivers/net/can/sja1000/sja1000_platform.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/sja1000/sja1000_platform.c
Extension
.c
Size
8025 bytes
Lines
331
Domain
Driver Families
Bucket
drivers/net
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 sja1000_of_data {
	size_t  priv_sz;
	void    (*init)(struct sja1000_priv *priv, struct device_node *of);
};

struct technologic_priv {
	spinlock_t      io_lock;
};

static u8 sp_read_reg8(const struct sja1000_priv *priv, int reg)
{
	return ioread8(priv->reg_base + reg);
}

static void sp_write_reg8(const struct sja1000_priv *priv, int reg, u8 val)
{
	iowrite8(val, priv->reg_base + reg);
}

static u8 sp_read_reg16(const struct sja1000_priv *priv, int reg)
{
	return ioread8(priv->reg_base + reg * 2);
}

static void sp_write_reg16(const struct sja1000_priv *priv, int reg, u8 val)
{
	iowrite8(val, priv->reg_base + reg * 2);
}

static u8 sp_read_reg32(const struct sja1000_priv *priv, int reg)
{
	return ioread8(priv->reg_base + reg * 4);
}

static void sp_write_reg32(const struct sja1000_priv *priv, int reg, u8 val)
{
	iowrite8(val, priv->reg_base + reg * 4);
}

static u8 sp_technologic_read_reg16(const struct sja1000_priv *priv, int reg)
{
	struct technologic_priv *tp = priv->priv;
	unsigned long flags;
	u8 val;

	spin_lock_irqsave(&tp->io_lock, flags);
	iowrite16(reg, priv->reg_base + 0);
	val = ioread16(priv->reg_base + 2);
	spin_unlock_irqrestore(&tp->io_lock, flags);

	return val;
}

static void sp_technologic_write_reg16(const struct sja1000_priv *priv,
				       int reg, u8 val)
{
	struct technologic_priv *tp = priv->priv;
	unsigned long flags;

	spin_lock_irqsave(&tp->io_lock, flags);
	iowrite16(reg, priv->reg_base + 0);
	iowrite16(val, priv->reg_base + 2);
	spin_unlock_irqrestore(&tp->io_lock, flags);
}

static void sp_technologic_init(struct sja1000_priv *priv, struct device_node *of)
{
	struct technologic_priv *tp = priv->priv;

	priv->read_reg = sp_technologic_read_reg16;
	priv->write_reg = sp_technologic_write_reg16;
	spin_lock_init(&tp->io_lock);
}

static void sp_rzn1_init(struct sja1000_priv *priv, struct device_node *of)
{
	priv->flags = SJA1000_QUIRK_NO_CDR_REG | SJA1000_QUIRK_RESET_ON_OVERRUN;
}

static void sp_populate(struct sja1000_priv *priv,
			struct sja1000_platform_data *pdata,
			unsigned long resource_mem_flags)
{
	/* The CAN clock frequency is half the oscillator clock frequency */
	priv->can.clock.freq = pdata->osc_freq / 2;
	priv->ocr = pdata->ocr;
	priv->cdr = pdata->cdr;

	switch (resource_mem_flags & IORESOURCE_MEM_TYPE_MASK) {
	case IORESOURCE_MEM_32BIT:

Annotation

Implementation Notes