drivers/edac/loongson_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/loongson_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/loongson_edac.c- Extension
.c- Size
- 3648 bytes
- Lines
- 158
- 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.
- 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 or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/edac.hlinux/init.hlinux/io-64-nonatomic-lo-hi.hlinux/module.hlinux/platform_device.hedac_module.h
Detected Declarations
struct loongson_edac_pvtfunction read_eccfunction edac_checkfunction dimm_config_initfunction pvt_initfunction edac_probefunction edac_remove
Annotated Snippet
struct loongson_edac_pvt {
void __iomem *ecc_base;
/*
* The ECC register in this controller records the number of errors
* encountered since reset and cannot be zeroed so in order to be able
* to report the error count at each check, this records the previous
* register state.
*/
int last_ce_count;
};
static int read_ecc(struct mem_ctl_info *mci)
{
struct loongson_edac_pvt *pvt = mci->pvt_info;
u64 ecc;
int cs;
ecc = readq(pvt->ecc_base + ECC_CS_COUNT_REG);
/* cs0 -- cs3 */
cs = ecc & 0xff;
cs += (ecc >> 8) & 0xff;
cs += (ecc >> 16) & 0xff;
cs += (ecc >> 24) & 0xff;
return cs;
}
static void edac_check(struct mem_ctl_info *mci)
{
struct loongson_edac_pvt *pvt = mci->pvt_info;
int new, add;
new = read_ecc(mci);
add = new - pvt->last_ce_count;
pvt->last_ce_count = new;
if (add <= 0)
return;
edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, add,
0, 0, 0, 0, 0, -1, "error", "");
}
static void dimm_config_init(struct mem_ctl_info *mci)
{
struct dimm_info *dimm;
u32 size, npages;
/* size not used */
size = -1;
npages = MiB_TO_PAGES(size);
dimm = edac_get_dimm(mci, 0, 0, 0);
dimm->nr_pages = npages;
snprintf(dimm->label, sizeof(dimm->label),
"MC#%uChannel#%u_DIMM#%u", mci->mc_idx, 0, 0);
dimm->grain = 8;
}
static void pvt_init(struct mem_ctl_info *mci, void __iomem *vbase)
{
struct loongson_edac_pvt *pvt = mci->pvt_info;
pvt->ecc_base = vbase;
pvt->last_ce_count = read_ecc(mci);
}
static int edac_probe(struct platform_device *pdev)
{
struct edac_mc_layer layers[2];
struct mem_ctl_info *mci;
void __iomem *vbase;
int ret;
vbase = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(vbase))
return PTR_ERR(vbase);
layers[0].type = EDAC_MC_LAYER_CHANNEL;
layers[0].size = 1;
layers[0].is_virt_csrow = false;
layers[1].type = EDAC_MC_LAYER_SLOT;
layers[1].size = 1;
layers[1].is_virt_csrow = true;
mci = edac_mc_alloc(0, ARRAY_SIZE(layers), layers,
sizeof(struct loongson_edac_pvt));
if (mci == NULL)
return -ENOMEM;
mci->mc_idx = edac_device_alloc_index();
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/edac.h`, `linux/init.h`, `linux/io-64-nonatomic-lo-hi.h`, `linux/module.h`, `linux/platform_device.h`, `edac_module.h`.
- Detected declarations: `struct loongson_edac_pvt`, `function read_ecc`, `function edac_check`, `function dimm_config_init`, `function pvt_init`, `function edac_probe`, `function edac_remove`.
- Atlas domain: Driver Families / drivers/edac.
- Implementation status: source implementation candidate.
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.