drivers/irqchip/irq-riscv-rpmi-sysmsi.c

Source file repositories/reference/linux-study-clean/drivers/irqchip/irq-riscv-rpmi-sysmsi.c

File Facts

System
Linux kernel
Corpus path
drivers/irqchip/irq-riscv-rpmi-sysmsi.c
Extension
.c
Size
8642 bytes
Lines
330
Domain
Driver Families
Bucket
drivers/irqchip
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 rpmi_sysmsi_get_attrs_rx {
	__le32 status;
	__le32 sys_num_msi;
	__le32 flag0;
	__le32 flag1;
};

#define RPMI_SYSMSI_MSI_ATTRIBUTES_FLAG0_PREF_PRIV	BIT(0)

struct rpmi_sysmsi_set_msi_state_tx {
	__le32 sys_msi_index;
	__le32 sys_msi_state;
};

struct rpmi_sysmsi_set_msi_state_rx {
	__le32 status;
};

#define RPMI_SYSMSI_MSI_STATE_ENABLE			BIT(0)
#define RPMI_SYSMSI_MSI_STATE_PENDING			BIT(1)

struct rpmi_sysmsi_set_msi_target_tx {
	__le32 sys_msi_index;
	__le32 sys_msi_address_low;
	__le32 sys_msi_address_high;
	__le32 sys_msi_data;
};

struct rpmi_sysmsi_set_msi_target_rx {
	__le32 status;
};

struct rpmi_sysmsi_priv {
	struct device		*dev;
	struct mbox_client	client;
	struct mbox_chan	*chan;
	u32			nr_irqs;
	u32			gsi_base;
};

static int rpmi_sysmsi_get_num_msi(struct rpmi_sysmsi_priv *priv)
{
	struct rpmi_sysmsi_get_attrs_rx rx;
	struct rpmi_mbox_message msg;
	int ret;

	rpmi_mbox_init_send_with_response(&msg, RPMI_SYSMSI_SRV_GET_ATTRIBUTES,
					  NULL, 0, &rx, sizeof(rx));
	ret = rpmi_mbox_send_message(priv->chan, &msg);
	if (ret)
		return ret;
	if (rx.status)
		return rpmi_to_linux_error(le32_to_cpu(rx.status));

	return le32_to_cpu(rx.sys_num_msi);
}

static int rpmi_sysmsi_set_msi_state(struct rpmi_sysmsi_priv *priv,
				     u32 sys_msi_index, u32 sys_msi_state)
{
	struct rpmi_sysmsi_set_msi_state_tx tx;
	struct rpmi_sysmsi_set_msi_state_rx rx;
	struct rpmi_mbox_message msg;
	int ret;

	tx.sys_msi_index = cpu_to_le32(sys_msi_index);
	tx.sys_msi_state = cpu_to_le32(sys_msi_state);
	rpmi_mbox_init_send_with_response(&msg, RPMI_SYSMSI_SRV_SET_MSI_STATE,
					  &tx, sizeof(tx), &rx, sizeof(rx));
	ret = rpmi_mbox_send_message(priv->chan, &msg);
	if (ret)
		return ret;
	if (rx.status)
		return rpmi_to_linux_error(le32_to_cpu(rx.status));

	return 0;
}

static int rpmi_sysmsi_set_msi_target(struct rpmi_sysmsi_priv *priv,
				      u32 sys_msi_index, struct msi_msg *m)
{
	struct rpmi_sysmsi_set_msi_target_tx tx;
	struct rpmi_sysmsi_set_msi_target_rx rx;
	struct rpmi_mbox_message msg;
	int ret;

	tx.sys_msi_index = cpu_to_le32(sys_msi_index);
	tx.sys_msi_address_low = cpu_to_le32(m->address_lo);
	tx.sys_msi_address_high = cpu_to_le32(m->address_hi);
	tx.sys_msi_data = cpu_to_le32(m->data);

Annotation

Implementation Notes