drivers/edac/bluefield_edac.c

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

File Facts

System
Linux kernel
Corpus path
drivers/edac/bluefield_edac.c
Extension
.c
Size
12610 bytes
Lines
495
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 bluefield_edac_priv {
	/* pointer to device structure */
	struct device *dev;
	int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
	void __iomem *emi_base;
	int dimm_per_mc;
	/* access to secure regs supported */
	bool svc_sreg_support;
	/* SMC table# for secure regs access */
	u32 sreg_tbl;
};

static u64 smc_call1(u64 smc_op, u64 smc_arg)
{
	struct arm_smccc_res res;

	arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);

	return res.a0;
}

static int secure_readl(void __iomem *addr, u32 *result, u32 sreg_tbl)
{
	struct arm_smccc_res res;
	int status;

	arm_smccc_smc(MLXBF_READ_REG_32, sreg_tbl, (uintptr_t)addr,
		      0, 0, 0, 0, 0, &res);

	status = res.a0;

	if (status == SMCCC_RET_NOT_SUPPORTED ||
	    status == MLXBF_SMCCC_ACCESS_VIOLATION)
		return -1;

	*result = (u32)res.a1;
	return 0;
}

static int secure_writel(void __iomem *addr, u32 data, u32 sreg_tbl)
{
	struct arm_smccc_res res;
	int status;

	arm_smccc_smc(MLXBF_WRITE_REG_32, sreg_tbl, data, (uintptr_t)addr,
		      0, 0, 0, 0, &res);

	status = res.a0;

	if (status == SMCCC_RET_NOT_SUPPORTED ||
	    status == MLXBF_SMCCC_ACCESS_VIOLATION)
		return -1;
	else
		return 0;
}

static int bluefield_edac_readl(struct bluefield_edac_priv *priv, u32 offset, u32 *result)
{
	void __iomem *addr;
	int err = 0;

	addr = priv->emi_base + offset;

	if (priv->svc_sreg_support)
		err = secure_readl(addr, result, priv->sreg_tbl);
	else
		*result = readl(addr);

	return err;
}

static int bluefield_edac_writel(struct bluefield_edac_priv *priv, u32 offset, u32 data)
{
	void __iomem *addr;
	int err = 0;

	addr = priv->emi_base + offset;

	if (priv->svc_sreg_support)
		err = secure_writel(addr, data, priv->sreg_tbl);
	else
		writel(data, addr);

	return err;
}

/*
 * Gather the ECC information from the External Memory Interface registers
 * and report it to the edac handler.
 */

Annotation

Implementation Notes