drivers/edac/npcm_edac.c

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

File Facts

System
Linux kernel
Corpus path
drivers/edac/npcm_edac.c
Extension
.c
Size
15029 bytes
Lines
543
Domain
Driver Families
Bucket
drivers/edac
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations force_ecc_error_fops = {
	.open = simple_open,
	.write = force_ecc_error,
	.llseek = generic_file_llseek,
};

/*
 * Setup debugfs for error injection.
 *
 * Nodes:
 *   error_type		- 0: CE, 1: UE
 *   location		- 0: data, 1: checkcode
 *   bit		- 0 ~ 63 for data and 0 ~ 7 for checkcode
 *   force_ecc_error	- trigger
 *
 * Examples:
 *   1. Inject a correctable error (CE) at checkcode bit 7.
 *      ~# echo 0 > /sys/kernel/debug/edac/npcm-edac/error_type
 *      ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/location
 *      ~# echo 7 > /sys/kernel/debug/edac/npcm-edac/bit
 *      ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/force_ecc_error
 *
 *   2. Inject an uncorrectable error (UE).
 *      ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/error_type
 *      ~# echo 1 > /sys/kernel/debug/edac/npcm-edac/force_ecc_error
 */
static void setup_debugfs(struct mem_ctl_info *mci)
{
	struct priv_data *priv = mci->pvt_info;

	priv->debugfs = edac_debugfs_create_dir(mci->mod_name);
	if (!priv->debugfs)
		return;

	edac_debugfs_create_x8("error_type", 0644, priv->debugfs, &priv->error_type);
	edac_debugfs_create_x8("location", 0644, priv->debugfs, &priv->location);
	edac_debugfs_create_x8("bit", 0644, priv->debugfs, &priv->bit);
	edac_debugfs_create_file("force_ecc_error", 0200, priv->debugfs,
				 &mci->dev, &force_ecc_error_fops);
}

static int setup_irq(struct mem_ctl_info *mci, struct platform_device *pdev)
{
	const struct npcm_platform_data *pdata;
	int ret, irq;

	pdata = ((struct priv_data *)mci->pvt_info)->pdata;
	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		edac_printk(KERN_ERR, EDAC_MOD_NAME, "IRQ not defined in DTS\n");
		return irq;
	}

	ret = devm_request_irq(&pdev->dev, irq, edac_ecc_isr, 0,
			       dev_name(&pdev->dev), mci);
	if (ret < 0) {
		edac_printk(KERN_ERR, EDAC_MOD_NAME, "failed to request IRQ\n");
		return ret;
	}

	/* enable the functional group of ECC and mask the others */
	regmap_write(npcm_regmap, pdata->ctl_int_mask_master,
		     pdata->int_mask_master_non_ecc_mask);

	if (pdata->chip == NPCM8XX_CHIP)
		regmap_write(npcm_regmap, pdata->ctl_int_mask_ecc,
			     pdata->int_mask_ecc_non_event_mask);

	return 0;
}

static const struct regmap_config npcm_regmap_cfg = {
	.reg_bits	= 32,
	.reg_stride	= 4,
	.val_bits	= 32,
};

static int edac_probe(struct platform_device *pdev)
{
	const struct npcm_platform_data *pdata;
	struct device *dev = &pdev->dev;
	struct edac_mc_layer layers[1];
	struct mem_ctl_info *mci;
	struct priv_data *priv;
	void __iomem *reg;
	u32 val;
	int rc;

	reg = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(reg))

Annotation

Implementation Notes