drivers/mfd/intel-m10-bmc-pmci.c
Source file repositories/reference/linux-study-clean/drivers/mfd/intel-m10-bmc-pmci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mfd/intel-m10-bmc-pmci.c- Extension
.c- Size
- 12137 bytes
- Lines
- 458
- Domain
- Driver Families
- Bucket
- drivers/mfd
- 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/device.hlinux/dfl.hlinux/mfd/core.hlinux/mfd/intel-m10-bmc.hlinux/minmax.hlinux/module.hlinux/regmap.h
Detected Declarations
struct m10bmc_pmci_devicestruct indirect_ctxfunction indirect_clear_cmdfunction indirect_reg_readfunction indirect_reg_writefunction pmci_write_fifofunction pmci_read_fifofunction pmci_get_write_spacefunction pmci_flash_bulk_writefunction pmci_flash_bulk_readfunction m10bmc_pmci_set_flash_host_muxfunction m10bmc_pmci_flash_readfunction m10bmc_pmci_flash_writefunction m10bmc_pmci_flash_lockfunction m10bmc_pmci_flash_unlockfunction m10bmc_pmci_probefunction m10bmc_pmci_remove
Annotated Snippet
struct m10bmc_pmci_device {
void __iomem *base;
struct intel_m10bmc m10bmc;
struct mutex flash_mutex; /* protects flash_busy and serializes flash read/read */
bool flash_busy;
};
/*
* Intel FGPA indirect register access via hardware controller/bridge.
*/
#define INDIRECT_CMD_OFF 0
#define INDIRECT_CMD_CLR 0
#define INDIRECT_CMD_RD BIT(0)
#define INDIRECT_CMD_WR BIT(1)
#define INDIRECT_CMD_ACK BIT(2)
#define INDIRECT_ADDR_OFF 0x4
#define INDIRECT_RD_OFF 0x8
#define INDIRECT_WR_OFF 0xc
#define INDIRECT_INT_US 1
#define INDIRECT_TIMEOUT_US 10000
struct indirect_ctx {
void __iomem *base;
struct device *dev;
};
static int indirect_clear_cmd(struct indirect_ctx *ctx)
{
unsigned int cmd;
int ret;
writel(INDIRECT_CMD_CLR, ctx->base + INDIRECT_CMD_OFF);
ret = readl_poll_timeout(ctx->base + INDIRECT_CMD_OFF, cmd,
cmd == INDIRECT_CMD_CLR,
INDIRECT_INT_US, INDIRECT_TIMEOUT_US);
if (ret)
dev_err(ctx->dev, "timed out waiting clear cmd (residual cmd=0x%x)\n", cmd);
return ret;
}
static int indirect_reg_read(void *context, unsigned int reg, unsigned int *val)
{
struct indirect_ctx *ctx = context;
unsigned int cmd, ack, tmpval;
int ret, ret2;
cmd = readl(ctx->base + INDIRECT_CMD_OFF);
if (cmd != INDIRECT_CMD_CLR)
dev_warn(ctx->dev, "residual cmd 0x%x on read entry\n", cmd);
writel(reg, ctx->base + INDIRECT_ADDR_OFF);
writel(INDIRECT_CMD_RD, ctx->base + INDIRECT_CMD_OFF);
ret = readl_poll_timeout(ctx->base + INDIRECT_CMD_OFF, ack,
(ack & INDIRECT_CMD_ACK) == INDIRECT_CMD_ACK,
INDIRECT_INT_US, INDIRECT_TIMEOUT_US);
if (ret)
dev_err(ctx->dev, "read timed out on reg 0x%x ack 0x%x\n", reg, ack);
else
tmpval = readl(ctx->base + INDIRECT_RD_OFF);
ret2 = indirect_clear_cmd(ctx);
if (ret)
return ret;
if (ret2)
return ret2;
*val = tmpval;
return 0;
}
static int indirect_reg_write(void *context, unsigned int reg, unsigned int val)
{
struct indirect_ctx *ctx = context;
unsigned int cmd, ack;
int ret, ret2;
cmd = readl(ctx->base + INDIRECT_CMD_OFF);
if (cmd != INDIRECT_CMD_CLR)
dev_warn(ctx->dev, "residual cmd 0x%x on write entry\n", cmd);
writel(val, ctx->base + INDIRECT_WR_OFF);
writel(reg, ctx->base + INDIRECT_ADDR_OFF);
writel(INDIRECT_CMD_WR, ctx->base + INDIRECT_CMD_OFF);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/device.h`, `linux/dfl.h`, `linux/mfd/core.h`, `linux/mfd/intel-m10-bmc.h`, `linux/minmax.h`, `linux/module.h`, `linux/regmap.h`.
- Detected declarations: `struct m10bmc_pmci_device`, `struct indirect_ctx`, `function indirect_clear_cmd`, `function indirect_reg_read`, `function indirect_reg_write`, `function pmci_write_fifo`, `function pmci_read_fifo`, `function pmci_get_write_space`, `function pmci_flash_bulk_write`, `function pmci_flash_bulk_read`.
- Atlas domain: Driver Families / drivers/mfd.
- 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.