drivers/mailbox/mailbox-mpfs.c
Source file repositories/reference/linux-study-clean/drivers/mailbox/mailbox-mpfs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mailbox/mailbox-mpfs.c- Extension
.c- Size
- 9088 bytes
- Lines
- 341
- Domain
- Driver Families
- Bucket
- drivers/mailbox
- 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.
- 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
linux/io.hlinux/err.hlinux/init.hlinux/module.hlinux/kernel.hlinux/regmap.hlinux/interrupt.hlinux/mfd/syscon.hlinux/mod_devicetable.hlinux/platform_device.hlinux/mailbox_controller.hsoc/microchip/mpfs.h
Detected Declarations
struct mpfs_mboxfunction mpfs_mbox_busyfunction mpfs_mbox_last_tx_donefunction mpfs_mbox_send_datafunction mpfs_mbox_rx_datafunction mpfs_mbox_inbox_isrfunction mpfs_mbox_startupfunction mpfs_mbox_shutdownfunction mpfs_mbox_syscon_probefunction mpfs_mbox_old_format_probefunction mpfs_mbox_probe
Annotated Snippet
struct mpfs_mbox {
struct mbox_controller controller;
struct device *dev;
int irq;
void __iomem *ctrl_base;
void __iomem *mbox_base;
void __iomem *int_reg;
struct mbox_chan chans[1];
struct mpfs_mss_response *response;
struct regmap *sysreg_scb, *control_scb;
u16 resp_offset;
};
static bool mpfs_mbox_busy(struct mpfs_mbox *mbox)
{
u32 status;
if (mbox->control_scb)
regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &status);
else
status = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
return status & SCB_STATUS_BUSY_MASK;
}
static bool mpfs_mbox_last_tx_done(struct mbox_chan *chan)
{
struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
struct mpfs_mss_response *response = mbox->response;
u32 val;
if (mpfs_mbox_busy(mbox))
return false;
/*
* The service status is stored in bits 31:16 of the SERVICES_SR
* register & is only valid when the system controller is not busy.
* Failed services are intended to generated interrupts, but in reality
* this does not happen, so the status must be checked here.
*/
if (mbox->control_scb)
regmap_read(mbox->control_scb, SERVICES_SR_OFFSET, &val);
else
val = readl_relaxed(mbox->ctrl_base + SERVICES_SR_OFFSET);
response->resp_status = (val & SCB_STATUS_MASK) >> SCB_STATUS_POS;
return true;
}
static int mpfs_mbox_send_data(struct mbox_chan *chan, void *data)
{
struct mpfs_mbox *mbox = (struct mpfs_mbox *)chan->con_priv;
struct mpfs_mss_msg *msg = data;
u32 tx_trigger;
u16 opt_sel;
u32 val = 0u;
mbox->response = msg->response;
mbox->resp_offset = msg->resp_offset;
if (mpfs_mbox_busy(mbox))
return -EBUSY;
if (msg->cmd_data_size) {
u32 index;
u8 extra_bits = msg->cmd_data_size & 3;
u32 *word_buf = (u32 *)msg->cmd_data;
for (index = 0; index < (msg->cmd_data_size / 4); index++)
writel_relaxed(word_buf[index],
mbox->mbox_base + msg->mbox_offset + index * 0x4);
if (extra_bits) {
u8 i;
u8 byte_off = ALIGN_DOWN(msg->cmd_data_size, 4);
u8 *byte_buf = msg->cmd_data + byte_off;
val = readl_relaxed(mbox->mbox_base + msg->mbox_offset + index * 0x4);
for (i = 0u; i < extra_bits; i++) {
val &= ~(0xffu << (i * 8u));
val |= (byte_buf[i] << (i * 8u));
}
writel_relaxed(val, mbox->mbox_base + msg->mbox_offset + index * 0x4);
}
}
opt_sel = ((msg->mbox_offset << 7u) | (msg->cmd_opcode & 0x7fu));
Annotation
- Immediate include surface: `linux/io.h`, `linux/err.h`, `linux/init.h`, `linux/module.h`, `linux/kernel.h`, `linux/regmap.h`, `linux/interrupt.h`, `linux/mfd/syscon.h`.
- Detected declarations: `struct mpfs_mbox`, `function mpfs_mbox_busy`, `function mpfs_mbox_last_tx_done`, `function mpfs_mbox_send_data`, `function mpfs_mbox_rx_data`, `function mpfs_mbox_inbox_isr`, `function mpfs_mbox_startup`, `function mpfs_mbox_shutdown`, `function mpfs_mbox_syscon_probe`, `function mpfs_mbox_old_format_probe`.
- Atlas domain: Driver Families / drivers/mailbox.
- Implementation status: source implementation candidate.
- 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.