drivers/edac/xgene_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/xgene_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/xgene_edac.c- Extension
.c- Size
- 60438 bytes
- Lines
- 2043
- 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.
- 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/ctype.hlinux/edac.hlinux/interrupt.hlinux/mfd/syscon.hlinux/module.hlinux/of.hlinux/of_address.hlinux/regmap.hlinux/string_choices.hedac_module.h
Detected Declarations
struct xgene_edacstruct xgene_edac_mc_ctxstruct xgene_edac_pmd_ctxstruct xgene_edac_dev_ctxfunction xgene_edac_pcp_rdfunction xgene_edac_pcp_clrbitsfunction xgene_edac_pcp_setbitsfunction xgene_edac_mc_err_inject_writefunction xgene_edac_mc_create_debugfs_nodefunction xgene_edac_mc_checkfunction xgene_edac_mc_irq_ctlfunction xgene_edac_mc_is_activefunction xgene_edac_mc_addfunction xgene_edac_mc_removefunction xgene_edac_pmd_l1_checkfunction xgene_edac_pmd_l2_checkfunction xgene_edac_pmd_checkfunction xgene_edac_pmd_cpu_hw_cfgfunction xgene_edac_pmd_hw_cfgfunction xgene_edac_pmd_hw_ctlfunction xgene_edac_pmd_l1_inject_ctrl_writefunction xgene_edac_pmd_l2_inject_ctrl_writefunction xgene_edac_pmd_create_debugfs_nodesfunction xgene_edac_pmd_availablefunction xgene_edac_pmd_addfunction xgene_edac_pmd_removefunction xgene_edac_l3_promote_to_uc_errfunction xgene_edac_l3_checkfunction xgene_edac_l3_hw_initfunction xgene_edac_l3_inject_ctrl_writefunction xgene_edac_l3_create_debugfs_nodesfunction xgene_edac_l3_addfunction xgene_edac_l3_removefunction xgene_edac_iob_gic_reportfunction xgene_edac_rb_reportfunction xgene_edac_pa_reportfunction xgene_edac_soc_checkfunction xgene_edac_soc_hw_initfunction xgene_edac_soc_addfunction xgene_edac_soc_removefunction xgene_edac_isrfunction list_for_each_entryfunction xgene_edac_probefunction for_each_child_of_nodefunction xgene_edac_removefunction xgene_edac_initfunction xgene_edac_exitmodule init xgene_edac_init
Annotated Snippet
static const struct file_operations xgene_edac_mc_debug_inject_fops = {
.open = simple_open,
.write = xgene_edac_mc_err_inject_write,
.llseek = generic_file_llseek,
};
static void xgene_edac_mc_create_debugfs_node(struct mem_ctl_info *mci)
{
if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
return;
if (!mci->debugfs)
return;
edac_debugfs_create_file("inject_ctrl", S_IWUSR, mci->debugfs, mci,
&xgene_edac_mc_debug_inject_fops);
}
static void xgene_edac_mc_check(struct mem_ctl_info *mci)
{
struct xgene_edac_mc_ctx *ctx = mci->pvt_info;
unsigned int pcp_hp_stat;
unsigned int pcp_lp_stat;
u32 reg;
u32 rank;
u32 bank;
u32 count;
u32 col_row;
xgene_edac_pcp_rd(ctx->edac, PCPHPERRINTSTS, &pcp_hp_stat);
xgene_edac_pcp_rd(ctx->edac, PCPLPERRINTSTS, &pcp_lp_stat);
if (!((MCU_UNCORR_ERR_MASK & pcp_hp_stat) ||
(MCU_CTL_ERR_MASK & pcp_hp_stat) ||
(MCU_CORR_ERR_MASK & pcp_lp_stat)))
return;
for (rank = 0; rank < MCU_MAX_RANK; rank++) {
reg = readl(ctx->mcu_csr + MCUESRR0 + rank * MCU_RANK_STRIDE);
/* Detect uncorrectable memory error */
if (reg & (MCU_ESRR_DEMANDUCERR_MASK |
MCU_ESRR_BACKUCERR_MASK)) {
/* Detected uncorrectable memory error */
edac_mc_chipset_printk(mci, KERN_ERR, "X-Gene",
"MCU uncorrectable error at rank %d\n", rank);
edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
1, 0, 0, 0, 0, 0, -1, mci->ctl_name, "");
}
/* Detect correctable memory error */
if (reg & MCU_ESRR_CERR_MASK) {
bank = readl(ctx->mcu_csr + MCUEBLRR0 +
rank * MCU_RANK_STRIDE);
col_row = readl(ctx->mcu_csr + MCUERCRR0 +
rank * MCU_RANK_STRIDE);
count = readl(ctx->mcu_csr + MCUSBECNT0 +
rank * MCU_RANK_STRIDE);
edac_mc_chipset_printk(mci, KERN_WARNING, "X-Gene",
"MCU correctable error at rank %d bank %d column %d row %d count %d\n",
rank, MCU_EBLRR_ERRBANK_RD(bank),
MCU_ERCRR_ERRCOL_RD(col_row),
MCU_ERCRR_ERRROW_RD(col_row),
MCU_SBECNT_COUNT(count));
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
1, 0, 0, 0, 0, 0, -1, mci->ctl_name, "");
}
/* Clear all error registers */
writel(0x0, ctx->mcu_csr + MCUEBLRR0 + rank * MCU_RANK_STRIDE);
writel(0x0, ctx->mcu_csr + MCUERCRR0 + rank * MCU_RANK_STRIDE);
writel(0x0, ctx->mcu_csr + MCUSBECNT0 +
rank * MCU_RANK_STRIDE);
writel(reg, ctx->mcu_csr + MCUESRR0 + rank * MCU_RANK_STRIDE);
}
/* Detect memory controller error */
reg = readl(ctx->mcu_csr + MCUGESR);
if (reg) {
if (reg & MCU_GESR_ADDRNOMATCH_ERR_MASK)
edac_mc_chipset_printk(mci, KERN_WARNING, "X-Gene",
"MCU address miss-match error\n");
if (reg & MCU_GESR_ADDRMULTIMATCH_ERR_MASK)
edac_mc_chipset_printk(mci, KERN_WARNING, "X-Gene",
"MCU address multi-match error\n");
writel(reg, ctx->mcu_csr + MCUGESR);
}
}
Annotation
- Immediate include surface: `linux/ctype.h`, `linux/edac.h`, `linux/interrupt.h`, `linux/mfd/syscon.h`, `linux/module.h`, `linux/of.h`, `linux/of_address.h`, `linux/regmap.h`.
- Detected declarations: `struct xgene_edac`, `struct xgene_edac_mc_ctx`, `struct xgene_edac_pmd_ctx`, `struct xgene_edac_dev_ctx`, `function xgene_edac_pcp_rd`, `function xgene_edac_pcp_clrbits`, `function xgene_edac_pcp_setbits`, `function xgene_edac_mc_err_inject_write`, `function xgene_edac_mc_create_debugfs_node`, `function xgene_edac_mc_check`.
- Atlas domain: Driver Families / drivers/edac.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.