drivers/mailbox/zynqmp-ipi-mailbox.c
Source file repositories/reference/linux-study-clean/drivers/mailbox/zynqmp-ipi-mailbox.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mailbox/zynqmp-ipi-mailbox.c- Extension
.c- Size
- 28298 bytes
- Lines
- 1041
- Domain
- Driver Families
- Bucket
- drivers/mailbox
- 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 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/arm-smccc.hlinux/cpuhotplug.hlinux/delay.hlinux/device.hlinux/interrupt.hlinux/irqdomain.hlinux/io.hlinux/kernel.hlinux/mailbox_controller.hlinux/mailbox/zynqmp-ipi-message.hlinux/module.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/platform_device.h
Detected Declarations
struct zynqmp_ipi_mchanstruct zynqmp_ipi_mboxstruct zynqmp_ipi_mboxstruct zynqmp_ipi_pdatafunction zynqmp_ipi_fw_callfunction zynqmp_ipi_interruptfunction zynqmp_sgi_interruptfunction zynqmp_ipi_peek_datafunction zynqmp_ipi_last_tx_donefunction zynqmp_ipi_send_datafunction zynqmp_ipi_startupfunction zynqmp_ipi_shutdownfunction zynqmp_ipi_mbox_get_buf_resfunction zynqmp_ipi_mbox_dev_releasefunction zynqmp_ipi_mbox_probefunction zynqmp_ipi_setupfunction versal_ipi_setupfunction xlnx_mbox_cpuhp_startfunction xlnx_mbox_cpuhp_downfunction xlnx_disable_percpu_irqfunction xlnx_mbox_init_sgifunction xlnx_mbox_cleanup_sgifunction zynqmp_ipi_free_mboxesfunction zynqmp_ipi_probefunction zynqmp_ipi_removefunction zynqmp_ipi_initfunction zynqmp_ipi_exitmodule init zynqmp_ipi_init
Annotated Snippet
static struct device_driver zynqmp_ipi_mbox_driver = {
.owner = THIS_MODULE,
.name = "zynqmp-ipi-mbox",
};
static void zynqmp_ipi_fw_call(struct zynqmp_ipi_mbox *ipi_mbox,
unsigned long a0, unsigned long a3,
struct arm_smccc_res *res)
{
struct zynqmp_ipi_pdata *pdata = ipi_mbox->pdata;
unsigned long a1, a2;
a1 = pdata->local_id;
a2 = ipi_mbox->remote_id;
if (pdata->method == USE_SMC)
arm_smccc_smc(a0, a1, a2, a3, 0, 0, 0, 0, res);
else
arm_smccc_hvc(a0, a1, a2, a3, 0, 0, 0, 0, res);
}
/**
* zynqmp_ipi_interrupt - Interrupt handler for IPI notification
*
* @irq: Interrupt number
* @data: ZynqMP IPI mailbox platform data.
*
* Return: -EINVAL if there is no instance
* IRQ_NONE if the interrupt is not ours.
* IRQ_HANDLED if the rx interrupt was successfully handled.
*/
static irqreturn_t zynqmp_ipi_interrupt(int irq, void *data)
{
struct zynqmp_ipi_pdata *pdata = data;
struct mbox_chan *chan;
struct zynqmp_ipi_mbox *ipi_mbox;
struct zynqmp_ipi_mchan *mchan;
struct zynqmp_ipi_message *msg;
u64 arg0, arg3;
struct arm_smccc_res res;
int ret, i, status = IRQ_NONE;
(void)irq;
arg0 = SMC_IPI_MAILBOX_STATUS_ENQUIRY;
arg3 = IPI_SMC_ENQUIRY_DIRQ_MASK;
for (i = 0; i < pdata->num_mboxes; i++) {
ipi_mbox = &pdata->ipi_mboxes[i];
mchan = &ipi_mbox->mchans[IPI_MB_CHNL_RX];
chan = &ipi_mbox->mbox.chans[IPI_MB_CHNL_RX];
zynqmp_ipi_fw_call(ipi_mbox, arg0, arg3, &res);
ret = (int)(res.a0 & 0xFFFFFFFF);
if (ret > 0 && ret & IPI_MB_STATUS_RECV_PENDING) {
if (mchan->is_opened) {
msg = mchan->rx_buf;
if (msg) {
msg->len = mchan->req_buf_size;
memcpy_fromio(msg->data, mchan->req_buf,
msg->len);
}
mbox_chan_received_data(chan, (void *)msg);
status = IRQ_HANDLED;
}
}
}
return status;
}
static irqreturn_t zynqmp_sgi_interrupt(int irq, void *data)
{
struct zynqmp_ipi_pdata **pdata_ptr = data;
struct zynqmp_ipi_pdata *pdata = *pdata_ptr;
return zynqmp_ipi_interrupt(irq, pdata);
}
/**
* zynqmp_ipi_peek_data - Peek to see if there are any rx messages.
*
* @chan: Channel Pointer
*
* Return: 'true' if there is pending rx data, 'false' if there is none.
*/
static bool zynqmp_ipi_peek_data(struct mbox_chan *chan)
{
struct device *dev = chan->mbox->dev;
struct zynqmp_ipi_mbox *ipi_mbox = dev_get_drvdata(dev);
struct zynqmp_ipi_mchan *mchan = chan->con_priv;
int ret;
u64 arg0;
struct arm_smccc_res res;
Annotation
- Immediate include surface: `linux/arm-smccc.h`, `linux/cpuhotplug.h`, `linux/delay.h`, `linux/device.h`, `linux/interrupt.h`, `linux/irqdomain.h`, `linux/io.h`, `linux/kernel.h`.
- Detected declarations: `struct zynqmp_ipi_mchan`, `struct zynqmp_ipi_mbox`, `struct zynqmp_ipi_mbox`, `struct zynqmp_ipi_pdata`, `function zynqmp_ipi_fw_call`, `function zynqmp_ipi_interrupt`, `function zynqmp_sgi_interrupt`, `function zynqmp_ipi_peek_data`, `function zynqmp_ipi_last_tx_done`, `function zynqmp_ipi_send_data`.
- Atlas domain: Driver Families / drivers/mailbox.
- Implementation status: pattern 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.