drivers/edac/zynqmp_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/zynqmp_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/zynqmp_edac.c- Extension
.c- Size
- 12188 bytes
- Lines
- 466
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/edac.hlinux/interrupt.hlinux/module.hlinux/of.hlinux/of_platform.hlinux/platform_device.hedac_module.h
Detected Declarations
struct ecc_error_infostruct ecc_statusstruct edac_privfunction get_error_infofunction handle_errorfunction intr_handlerfunction get_eccstatefunction write_fault_countfunction inject_ce_writefunction inject_ue_writefunction setup_debugfsfunction edac_probefunction edac_remove
Annotated Snippet
static const struct file_operations inject_ce_fops = {
.open = simple_open,
.write = inject_ce_write,
.llseek = generic_file_llseek,
};
/*
* To get the Uncorrectable Error injected, the following steps are needed:
* - Setup the optional Fault Injection Count:
* echo <fault_count val> > /sys/kernel/debug/edac/ocm/inject_fault_count
* - Write the Uncorrectable Error bit position values:
* echo <bit_pos0 val>,<bit_pos1 val> > /sys/kernel/debug/edac/ocm/inject_ue_bitpos
*/
static ssize_t inject_ue_write(struct file *file, const char __user *data,
size_t count, loff_t *ppos)
{
struct edac_device_ctl_info *edac_dev = file->private_data;
struct edac_priv *priv = edac_dev->pvt_info;
char buf[6], *pbuf, *token[2];
u64 ue_bitpos;
int i, ret;
u8 len;
if (!data)
return -EFAULT;
len = min_t(size_t, count, sizeof(buf));
if (copy_from_user(buf, data, len))
return -EFAULT;
buf[len] = '\0';
pbuf = &buf[0];
for (i = 0; i < OCM_NUM_UE_BITPOS; i++)
token[i] = strsep(&pbuf, ",");
ret = kstrtou8(token[0], 0, &priv->ue_bitpos[0]);
if (ret)
return ret;
ret = kstrtou8(token[1], 0, &priv->ue_bitpos[1]);
if (ret)
return ret;
if (priv->ue_bitpos[0] > UE_MAX_BITPOS_UPPER ||
priv->ue_bitpos[1] > UE_MAX_BITPOS_UPPER)
return -EINVAL;
if (priv->ue_bitpos[0] == priv->ue_bitpos[1]) {
edac_printk(KERN_ERR, EDAC_DEVICE, "Bit positions should not be equal\n");
return -EINVAL;
}
ue_bitpos = BIT(priv->ue_bitpos[0]) | BIT(priv->ue_bitpos[1]);
writel((u32)ue_bitpos, priv->baseaddr + OCM_FID0_OFST);
writel((u32)(ue_bitpos >> 32), priv->baseaddr + OCM_FID1_OFST);
write_fault_count(priv);
return count;
}
static const struct file_operations inject_ue_fops = {
.open = simple_open,
.write = inject_ue_write,
.llseek = generic_file_llseek,
};
static void setup_debugfs(struct edac_device_ctl_info *edac_dev)
{
struct edac_priv *priv = edac_dev->pvt_info;
priv->debugfs_dir = edac_debugfs_create_dir("ocm");
if (!priv->debugfs_dir)
return;
edac_debugfs_create_x32("inject_fault_count", 0644, priv->debugfs_dir,
&priv->fault_injection_cnt);
edac_debugfs_create_file("inject_ue_bitpos", 0644, priv->debugfs_dir,
edac_dev, &inject_ue_fops);
edac_debugfs_create_file("inject_ce_bitpos", 0644, priv->debugfs_dir,
edac_dev, &inject_ce_fops);
}
#endif
static int edac_probe(struct platform_device *pdev)
{
struct edac_device_ctl_info *dci;
struct edac_priv *priv;
void __iomem *baseaddr;
Annotation
- Immediate include surface: `linux/edac.h`, `linux/interrupt.h`, `linux/module.h`, `linux/of.h`, `linux/of_platform.h`, `linux/platform_device.h`, `edac_module.h`.
- Detected declarations: `struct ecc_error_info`, `struct ecc_status`, `struct edac_priv`, `function get_error_info`, `function handle_error`, `function intr_handler`, `function get_eccstate`, `function write_fault_count`, `function inject_ce_write`, `function inject_ue_write`.
- Atlas domain: Driver Families / drivers/edac.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.