drivers/edac/dmc520_edac.c

Source file repositories/reference/linux-study-clean/drivers/edac/dmc520_edac.c

File Facts

System
Linux kernel
Corpus path
drivers/edac/dmc520_edac.c
Extension
.c
Size
16672 bytes
Lines
653
Domain
Driver Families
Bucket
drivers/edac
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 ecc_error_info {
	u32 col;
	u32 row;
	u32 bank;
	u32 rank;
};

/* The interrupt config */
struct dmc520_irq_config {
	char *name;
	int mask;
};

/* The interrupt mappings */
static struct dmc520_irq_config dmc520_irq_configs[] = {
	{
		.name = "ram_ecc_errc",
		.mask = RAM_ECC_INT_CE_BIT
	},
	{
		.name = "ram_ecc_errd",
		.mask = RAM_ECC_INT_UE_BIT
	},
	{
		.name = "dram_ecc_errc",
		.mask = DRAM_ECC_INT_CE_BIT
	},
	{
		.name = "dram_ecc_errd",
		.mask = DRAM_ECC_INT_UE_BIT
	},
	{
		.name = "failed_access",
		.mask = FAILED_ACCESS_INT_BIT
	},
	{
		.name = "failed_prog",
		.mask = FAILED_PROG_INT_BIT
	},
	{
		.name = "link_err",
		.mask = LINK_ERR_INT_BIT
	},
	{
		.name = "temperature_event",
		.mask = TEMPERATURE_EVENT_INT_BIT
	},
	{
		.name = "arch_fsm",
		.mask = ARCH_FSM_INT_BIT
	},
	{
		.name = "phy_request",
		.mask = PHY_REQUEST_INT_BIT
	}
};

#define NUMBER_OF_IRQS				ARRAY_SIZE(dmc520_irq_configs)

/*
 * The EDAC driver private data.
 * error_lock is to protect concurrent writes to the mci->error_desc through
 * edac_mc_handle_error().
 */
struct dmc520_edac {
	void __iomem *reg_base;
	spinlock_t error_lock;
	u32 mem_width_in_bytes;
	int irqs[NUMBER_OF_IRQS];
	int masks[NUMBER_OF_IRQS];
};

static int dmc520_mc_idx;

static u32 dmc520_read_reg(struct dmc520_edac *pvt, u32 offset)
{
	return readl(pvt->reg_base + offset);
}

static void dmc520_write_reg(struct dmc520_edac *pvt, u32 val, u32 offset)
{
	writel(val, pvt->reg_base + offset);
}

static u32 dmc520_calc_dram_ecc_error(u32 value)
{
	u32 total = 0;

	/* Each rank's error counter takes one byte. */
	while (value > 0) {

Annotation

Implementation Notes