drivers/mmc/host/sdhci-pci-arasan.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-pci-arasan.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-pci-arasan.c- Extension
.c- Size
- 8525 bytes
- Lines
- 332
- Domain
- Driver Families
- Bucket
- drivers/mmc
- 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/pci.hlinux/delay.hsdhci.hsdhci-pci.h
Detected Declarations
struct arasan_hostfunction arasan_phy_addr_pollfunction arasan_phy_writefunction arasan_phy_readfunction arasan_phy_sts_pollfunction arasan_phy_initfunction arasan_phy_setfunction arasan_select_phy_clockfunction arasan_pci_probe_slotfunction arasan_sdhci_set_clock
Annotated Snippet
struct arasan_host {
u32 chg_clk;
};
static int arasan_phy_addr_poll(struct sdhci_host *host, u32 offset, u32 mask)
{
ktime_t timeout = ktime_add_us(ktime_get(), 100);
bool failed;
u8 val = 0;
while (1) {
failed = ktime_after(ktime_get(), timeout);
val = sdhci_readw(host, PHY_ADDR_REG);
if (!(val & mask))
return 0;
if (failed)
return -EBUSY;
}
}
static int arasan_phy_write(struct sdhci_host *host, u8 data, u8 offset)
{
sdhci_writew(host, data, PHY_DAT_REG);
sdhci_writew(host, (PHY_WRITE | offset), PHY_ADDR_REG);
return arasan_phy_addr_poll(host, PHY_ADDR_REG, PHY_BUSY);
}
static int arasan_phy_read(struct sdhci_host *host, u8 offset, u8 *data)
{
int ret;
sdhci_writew(host, 0, PHY_DAT_REG);
sdhci_writew(host, offset, PHY_ADDR_REG);
ret = arasan_phy_addr_poll(host, PHY_ADDR_REG, PHY_BUSY);
/* Masking valid data bits */
*data = sdhci_readw(host, PHY_DAT_REG) & DATA_MASK;
return ret;
}
static int arasan_phy_sts_poll(struct sdhci_host *host, u32 offset, u32 mask)
{
int ret;
ktime_t timeout = ktime_add_us(ktime_get(), 100);
bool failed;
u8 val = 0;
while (1) {
failed = ktime_after(ktime_get(), timeout);
ret = arasan_phy_read(host, offset, &val);
if (ret)
return -EBUSY;
else if (val & mask)
return 0;
if (failed)
return -EBUSY;
}
}
/* Initialize the Arasan PHY */
static int arasan_phy_init(struct sdhci_host *host)
{
int ret;
u8 val;
/* Program IOPADs and wait for calibration to be done */
if (arasan_phy_read(host, IPAD_CTRL1, &val) ||
arasan_phy_write(host, val | RETB_ENBL | PDB_ENBL, IPAD_CTRL1) ||
arasan_phy_read(host, IPAD_CTRL2, &val) ||
arasan_phy_write(host, val | RTRIM_EN, IPAD_CTRL2))
return -EBUSY;
ret = arasan_phy_sts_poll(host, IPAD_STS, CALDONE_MASK);
if (ret)
return -EBUSY;
/* Program CMD/Data lines */
if (arasan_phy_read(host, IOREN_CTRL1, &val) ||
arasan_phy_write(host, val | REN_CMND | REN_STRB, IOREN_CTRL1) ||
arasan_phy_read(host, IOPU_CTRL1, &val) ||
arasan_phy_write(host, val | PU_CMD, IOPU_CTRL1) ||
arasan_phy_read(host, CMD_CTRL, &val) ||
arasan_phy_write(host, val | PDB_CMND, CMD_CTRL) ||
arasan_phy_read(host, IOREN_CTRL2, &val) ||
arasan_phy_write(host, val | REN_DATA, IOREN_CTRL2) ||
arasan_phy_read(host, IOPU_CTRL2, &val) ||
arasan_phy_write(host, val | PU_DAT, IOPU_CTRL2) ||
arasan_phy_read(host, DATA_CTRL, &val) ||
arasan_phy_write(host, val | PDB_DATA, DATA_CTRL) ||
arasan_phy_read(host, STRB_CTRL, &val) ||
arasan_phy_write(host, val | PDB_STRB, STRB_CTRL) ||
Annotation
- Immediate include surface: `linux/pci.h`, `linux/delay.h`, `sdhci.h`, `sdhci-pci.h`.
- Detected declarations: `struct arasan_host`, `function arasan_phy_addr_poll`, `function arasan_phy_write`, `function arasan_phy_read`, `function arasan_phy_sts_poll`, `function arasan_phy_init`, `function arasan_phy_set`, `function arasan_select_phy_clock`, `function arasan_pci_probe_slot`, `function arasan_sdhci_set_clock`.
- Atlas domain: Driver Families / drivers/mmc.
- 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.