drivers/firmware/arm_scmi/transports/mailbox.c

Source file repositories/reference/linux-study-clean/drivers/firmware/arm_scmi/transports/mailbox.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/arm_scmi/transports/mailbox.c
Extension
.c
Size
10948 bytes
Lines
389
Domain
Driver Families
Bucket
drivers/firmware
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct scmi_mailbox {
	struct mbox_client cl;
	struct mbox_chan *chan;
	struct mbox_chan *chan_receiver;
	struct mbox_chan *chan_platform_receiver;
	struct scmi_chan_info *cinfo;
	struct scmi_shared_mem __iomem *shmem;
	struct mutex chan_lock;
	struct scmi_shmem_io_ops *io_ops;
};

#define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)

static struct scmi_transport_core_operations *core;

static void tx_prepare(struct mbox_client *cl, void *m)
{
	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);

	core->shmem->tx_prepare(smbox->shmem, m, smbox->cinfo,
				smbox->io_ops->toio);
}

static void rx_callback(struct mbox_client *cl, void *m)
{
	struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl);

	/*
	 * An A2P IRQ is NOT valid when received while the platform still has
	 * the ownership of the channel, because the platform at first releases
	 * the SMT channel and then sends the completion interrupt.
	 *
	 * This addresses a possible race condition in which a spurious IRQ from
	 * a previous timed-out reply which arrived late could be wrongly
	 * associated with the next pending transaction.
	 */
	if (cl->knows_txdone &&
	    !core->shmem->channel_free(smbox->shmem)) {
		dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n");
		core->bad_message_trace(smbox->cinfo,
			     core->shmem->read_header(smbox->shmem),
							     MSG_MBOX_SPURIOUS);
		return;
	}

	core->rx_callback(smbox->cinfo,
		      core->shmem->read_header(smbox->shmem), NULL);
}

static bool mailbox_chan_available(struct device_node *of_node, int idx)
{
	int num_mb;

	/*
	 * Just check if bidirrectional channels are involved, and check the
	 * index accordingly; proper full validation will be made later
	 * in mailbox_chan_setup().
	 */
	num_mb = of_count_phandle_with_args(of_node, "mboxes", "#mbox-cells");
	if (num_mb == 3 && idx == 1)
		idx = 2;

	return !of_parse_phandle_with_args(of_node, "mboxes",
					   "#mbox-cells", idx, NULL);
}

/**
 * mailbox_chan_validate  - Validate transport configuration and map channels
 *
 * @cdev: Reference to the underlying transport device carrying the
 *	  of_node descriptor to analyze.
 * @a2p_rx_chan: A reference to an optional unidirectional channel to use
 *		 for replies on the a2p channel. Set as zero if not present.
 * @p2a_chan: A reference to the optional p2a channel.
 *	      Set as zero if not present.
 * @p2a_rx_chan: A reference to the optional p2a completion channel.
 *	      Set as zero if not present.
 *
 * At first, validate the transport configuration as described in terms of
 * 'mboxes' and 'shmem', then determin which mailbox channel indexes are
 * appropriate to be use in the current configuration.
 *
 * Return: 0 on Success or error
 */
static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan,
				 int *p2a_chan, int *p2a_rx_chan)
{
	int num_mb, num_sh, ret = 0;
	struct device_node *np = cdev->of_node;

Annotation

Implementation Notes