drivers/memory/dfl-emif.c
Source file repositories/reference/linux-study-clean/drivers/memory/dfl-emif.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/memory/dfl-emif.c- Extension
.c- Size
- 7304 bytes
- Lines
- 260
- Domain
- Driver Families
- Bucket
- drivers/memory
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/bitfield.hlinux/dfl.hlinux/errno.hlinux/io.hlinux/iopoll.hlinux/io-64-nonatomic-lo-hi.hlinux/kernel.hlinux/module.hlinux/spinlock.hlinux/types.h
Detected Declarations
struct dfl_emifstruct emif_attrfunction emif_state_showfunction emif_clear_storefunction dfl_emif_visiblefunction dfl_emif_probe
Annotated Snippet
struct dfl_emif {
struct device *dev;
void __iomem *base;
spinlock_t lock; /* Serialises access to EMIF_CTRL reg */
};
struct emif_attr {
struct device_attribute attr;
u32 shift;
u32 index;
};
#define to_emif_attr(dev_attr) \
container_of(dev_attr, struct emif_attr, attr)
static ssize_t emif_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct emif_attr *eattr = to_emif_attr(attr);
struct dfl_emif *de = dev_get_drvdata(dev);
u64 val;
val = readq(de->base + EMIF_STAT);
return sysfs_emit(buf, "%u\n",
!!(val & BIT_ULL(eattr->shift + eattr->index)));
}
static ssize_t emif_clear_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct emif_attr *eattr = to_emif_attr(attr);
struct dfl_emif *de = dev_get_drvdata(dev);
u64 clear_busy_msk, clear_en_msk, val;
void __iomem *base = de->base;
if (!sysfs_streq(buf, "1"))
return -EINVAL;
clear_busy_msk = BIT_ULL(EMIF_STAT_CLEAR_BUSY_SFT + eattr->index);
clear_en_msk = BIT_ULL(EMIF_CTRL_CLEAR_EN_SFT + eattr->index);
spin_lock(&de->lock);
/* The CLEAR_EN field is WO, but other fields are RW */
val = readq(base + EMIF_CTRL);
val &= ~EMIF_CTRL_CLEAR_EN_MSK;
val |= clear_en_msk;
writeq(val, base + EMIF_CTRL);
spin_unlock(&de->lock);
if (readq_poll_timeout(base + EMIF_STAT, val,
!(val & clear_busy_msk),
EMIF_POLL_INVL, EMIF_POLL_TIMEOUT)) {
dev_err(de->dev, "timeout, fail to clear\n");
return -ETIMEDOUT;
}
return count;
}
#define emif_state_attr(_name, _shift, _index) \
static struct emif_attr emif_attr_##inf##_index##_##_name = \
{ .attr = __ATTR(inf##_index##_##_name, 0444, \
emif_state_show, NULL), \
.shift = (_shift), .index = (_index) }
#define emif_clear_attr(_index) \
static struct emif_attr emif_attr_##inf##_index##_clear = \
{ .attr = __ATTR(inf##_index##_clear, 0200, \
NULL, emif_clear_store), \
.index = (_index) }
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 0);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 1);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 2);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 3);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 4);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 5);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 6);
emif_state_attr(init_done, EMIF_STAT_INIT_DONE_SFT, 7);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 0);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 1);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 2);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 3);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 4);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 5);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 6);
emif_state_attr(cal_fail, EMIF_STAT_CALC_FAIL_SFT, 7);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/dfl.h`, `linux/errno.h`, `linux/io.h`, `linux/iopoll.h`, `linux/io-64-nonatomic-lo-hi.h`, `linux/kernel.h`, `linux/module.h`.
- Detected declarations: `struct dfl_emif`, `struct emif_attr`, `function emif_state_show`, `function emif_clear_store`, `function dfl_emif_visible`, `function dfl_emif_probe`.
- Atlas domain: Driver Families / drivers/memory.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.