drivers/edac/altera_edac.c
Source file repositories/reference/linux-study-clean/drivers/edac/altera_edac.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/edac/altera_edac.c- Extension
.c- Size
- 62285 bytes
- Lines
- 2226
- 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.
- 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
asm/cacheflush.hlinux/ctype.hlinux/delay.hlinux/edac.hlinux/firmware/intel/stratix10-smc.hlinux/genalloc.hlinux/interrupt.hlinux/irqchip/chained_irq.hlinux/kernel.hlinux/mfd/altera-sysmgr.hlinux/mfd/syscon.hlinux/notifier.hlinux/of_address.hlinux/of_irq.hlinux/of_platform.hlinux/panic_notifier.hlinux/platform_device.hlinux/property.hlinux/regmap.hlinux/types.hlinux/uaccess.haltera_edac.hedac_module.h
Detected Declarations
function altr_sdram_mc_err_handlerfunction altr_sdr_mc_err_inject_writefunction altr_sdr_mc_create_debugfs_nodesfunction get_total_memfunction for_each_node_by_typefunction a10_initfunction a10_unmask_irqfunction altr_sdram_probefunction altr_sdram_removefunction altr_sdram_preparefunction altr_edac_probefunction altr_edac_device_handlerfunction altr_edac_device_trigfunction altr_create_edacdev_dbgfsfunction altr_edac_device_probefunction altr_edac_device_removefunction altr_check_ecc_depsfunction altr_edac_a10_ecc_irqfunction a10_get_irq_maskfunction ecc_set_bitsfunction ecc_clear_bitsfunction ecc_test_bitsfunction altr_init_memory_portfunction altr_init_a10_ecc_blockfunction altr_init_a10_ecc_device_typefunction for_each_child_of_nodefunction callfunction ocram_free_memfunction altr_check_ocram_deps_initfunction l2_free_memfunction altr_l2_check_depsfunction altr_edac_a10_l2_irqfunction socfpga_init_ethernet_eccfunction socfpga_init_nand_eccfunction socfpga_init_dma_eccfunction socfpga_init_usb_eccfunction socfpga_init_qspi_eccfunction altr_portb_setupfunction socfpga_init_sdmmc_eccfunction altr_edac_a10_ecc_irq_portbfunction altr_edac_a10_device_trigfunction altr_edac_a10_device_trig2function altr_edac_a10_irq_handlerfunction validate_parent_availablefunction get_s10_sdram_edac_resourcefunction altr_edac_a10_device_addfunction a10_eccmgr_irq_maskfunction a10_eccmgr_irq_unmask
Annotated Snippet
static const struct file_operations altr_sdr_mc_debug_inject_fops = {
.open = simple_open,
.write = altr_sdr_mc_err_inject_write,
.llseek = generic_file_llseek,
};
static void altr_sdr_mc_create_debugfs_nodes(struct mem_ctl_info *mci)
{
if (!IS_ENABLED(CONFIG_EDAC_DEBUG))
return;
if (!mci->debugfs)
return;
edac_debugfs_create_file("altr_trigger", S_IWUSR, mci->debugfs, mci,
&altr_sdr_mc_debug_inject_fops);
}
/* Get total memory size from Open Firmware DTB */
static unsigned long get_total_mem(void)
{
struct device_node *np = NULL;
struct resource res;
int ret;
unsigned long total_mem = 0;
for_each_node_by_type(np, "memory") {
ret = of_address_to_resource(np, 0, &res);
if (ret)
continue;
total_mem += resource_size(&res);
}
edac_dbg(0, "total_mem 0x%lx\n", total_mem);
return total_mem;
}
static const struct of_device_id altr_sdram_ctrl_of_match[] = {
{ .compatible = "altr,sdram-edac", .data = &c5_data},
{ .compatible = "altr,sdram-edac-a10", .data = &a10_data},
{},
};
MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
static int a10_init(struct regmap *mc_vbase)
{
if (regmap_update_bits(mc_vbase, A10_INTMODE_OFST,
A10_INTMODE_SB_INT, A10_INTMODE_SB_INT)) {
edac_printk(KERN_ERR, EDAC_MC,
"Error setting SB IRQ mode\n");
return -ENODEV;
}
if (regmap_write(mc_vbase, A10_SERRCNTREG_OFST, 1)) {
edac_printk(KERN_ERR, EDAC_MC,
"Error setting trigger count\n");
return -ENODEV;
}
return 0;
}
static int a10_unmask_irq(struct platform_device *pdev, u32 mask)
{
void __iomem *sm_base;
int ret = 0;
if (!request_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32),
dev_name(&pdev->dev))) {
edac_printk(KERN_ERR, EDAC_MC,
"Unable to request mem region\n");
return -EBUSY;
}
sm_base = ioremap(A10_SYMAN_INTMASK_CLR, sizeof(u32));
if (!sm_base) {
edac_printk(KERN_ERR, EDAC_MC,
"Unable to ioremap device\n");
ret = -ENOMEM;
goto release;
}
iowrite32(mask, sm_base);
iounmap(sm_base);
release:
release_mem_region(A10_SYMAN_INTMASK_CLR, sizeof(u32));
Annotation
- Immediate include surface: `asm/cacheflush.h`, `linux/ctype.h`, `linux/delay.h`, `linux/edac.h`, `linux/firmware/intel/stratix10-smc.h`, `linux/genalloc.h`, `linux/interrupt.h`, `linux/irqchip/chained_irq.h`.
- Detected declarations: `function altr_sdram_mc_err_handler`, `function altr_sdr_mc_err_inject_write`, `function altr_sdr_mc_create_debugfs_nodes`, `function get_total_mem`, `function for_each_node_by_type`, `function a10_init`, `function a10_unmask_irq`, `function altr_sdram_probe`, `function altr_sdram_remove`, `function altr_sdram_prepare`.
- 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.
- 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.