drivers/edac/fsl_ddr_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/fsl_ddr_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/fsl_ddr_edac.c- Extension
.c- Size
- 16596 bytes
- Lines
- 674
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/init.hlinux/interrupt.hlinux/ctype.hlinux/io.hlinux/mod_devicetable.hlinux/edac.hlinux/smp.hlinux/gfp.hlinux/of.hlinux/of_address.hedac_module.hfsl_ddr_edac.h
Detected Declarations
function ddr_in32function ddr_out32function fsl_mc_inject_data_hi_showfunction fsl_mc_inject_data_lo_showfunction fsl_mc_inject_ctrl_showfunction fsl_mc_inject_data_hi_storefunction fsl_mc_inject_data_lo_storefunction fsl_mc_inject_ctrl_storefunction calculate_eccfunction syndrome_from_bitfunction sbe_ecc_decodefunction fsl_mc_checkfunction fsl_mc_isrfunction fsl_ddr_init_csrowsfunction fsl_mc_err_probefunction fsl_mc_err_remove
Annotated Snippet
static u8 syndrome_from_bit(unsigned int bit) {
int i;
u8 syndrome = 0;
/*
* Cycle through the upper or lower 32-bit portion of each value in
* ecc_table depending on if 'bit' is in the upper or lower half of
* 64-bit data.
*/
for (i = bit < 32; i < 16; i += 2)
syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
return syndrome;
}
/*
* Decode data and ecc syndrome to determine what went wrong
* Note: This can only decode single-bit errors
*/
static void sbe_ecc_decode(u32 cap_high, u32 cap_low, u32 cap_ecc,
int *bad_data_bit, int *bad_ecc_bit)
{
int i;
u8 syndrome;
*bad_data_bit = -1;
*bad_ecc_bit = -1;
/*
* Calculate the ECC of the captured data and XOR it with the captured
* ECC to find an ECC syndrome value we can search for
*/
syndrome = calculate_ecc(cap_high, cap_low) ^ cap_ecc;
/* Check if a data line is stuck... */
for (i = 0; i < 64; i++) {
if (syndrome == syndrome_from_bit(i)) {
*bad_data_bit = i;
return;
}
}
/* If data is correct, check ECC bits for errors... */
for (i = 0; i < 8; i++) {
if ((syndrome >> i) & 0x1) {
*bad_ecc_bit = i;
return;
}
}
}
#define make64(high, low) (((u64)(high) << 32) | (low))
static void fsl_mc_check(struct mem_ctl_info *mci)
{
struct fsl_mc_pdata *pdata = mci->pvt_info;
struct csrow_info *csrow;
u32 bus_width;
u32 err_detect;
u32 syndrome;
u64 err_addr;
u32 pfn;
int row_index;
u32 cap_high;
u32 cap_low;
int bad_data_bit;
int bad_ecc_bit;
err_detect = ddr_in32(pdata, FSL_MC_ERR_DETECT);
if (!err_detect)
return;
fsl_mc_printk(mci, KERN_ERR, "Err Detect Register: %#8.8x\n",
err_detect);
/* no more processing if not ECC bit errors */
if (!(err_detect & (DDR_EDE_SBE | DDR_EDE_MBE))) {
ddr_out32(pdata, FSL_MC_ERR_DETECT, err_detect);
return;
}
syndrome = ddr_in32(pdata, FSL_MC_CAPTURE_ECC);
/* Mask off appropriate bits of syndrome based on bus width */
bus_width = (ddr_in32(pdata, FSL_MC_DDR_SDRAM_CFG) &
DSC_DBW_MASK) ? 32 : 64;
if (bus_width == 64)
syndrome &= 0xff;
else
syndrome &= 0xffff;
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/interrupt.h`, `linux/ctype.h`, `linux/io.h`, `linux/mod_devicetable.h`, `linux/edac.h`, `linux/smp.h`.
- Detected declarations: `function ddr_in32`, `function ddr_out32`, `function fsl_mc_inject_data_hi_show`, `function fsl_mc_inject_data_lo_show`, `function fsl_mc_inject_ctrl_show`, `function fsl_mc_inject_data_hi_store`, `function fsl_mc_inject_data_lo_store`, `function fsl_mc_inject_ctrl_store`, `function calculate_ecc`, `function syndrome_from_bit`.
- Atlas domain: Driver Families / drivers/edac.
- Implementation status: source implementation candidate.
- 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.