drivers/firmware/imx/imx-scu.c

Source file repositories/reference/linux-study-clean/drivers/firmware/imx/imx-scu.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/imx/imx-scu.c
Extension
.c
Size
9173 bytes
Lines
371
Domain
Driver Families
Bucket
drivers/firmware
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 imx_sc_chan {
	struct imx_sc_ipc *sc_ipc;

	struct mbox_client cl;
	struct mbox_chan *ch;
	int idx;
	struct completion tx_done;
};

struct imx_sc_ipc {
	/* SCU uses 4 Tx and 4 Rx channels */
	struct imx_sc_chan chans[SCU_MU_CHAN_NUM];
	struct device *dev;
	struct mutex lock;
	struct completion done;
	bool fast_ipc;

	/* temporarily store the SCU msg */
	u32 *msg;
	u8 rx_size;
	u8 count;
};

/*
 * This type is used to indicate error response for most functions.
 */
enum imx_sc_error_codes {
	IMX_SC_ERR_NONE = 0,	/* Success */
	IMX_SC_ERR_VERSION = 1,	/* Incompatible API version */
	IMX_SC_ERR_CONFIG = 2,	/* Configuration error */
	IMX_SC_ERR_PARM = 3,	/* Bad parameter */
	IMX_SC_ERR_NOACCESS = 4,	/* Permission error (no access) */
	IMX_SC_ERR_LOCKED = 5,	/* Permission error (locked) */
	IMX_SC_ERR_UNAVAILABLE = 6,	/* Unavailable (out of resources) */
	IMX_SC_ERR_NOTFOUND = 7,	/* Not found */
	IMX_SC_ERR_NOPOWER = 8,	/* No power */
	IMX_SC_ERR_IPC = 9,		/* Generic IPC error */
	IMX_SC_ERR_BUSY = 10,	/* Resource is currently busy/active */
	IMX_SC_ERR_FAIL = 11,	/* General I/O failure */
	IMX_SC_ERR_LAST
};

static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = {
	0,	 /* IMX_SC_ERR_NONE */
	-EINVAL, /* IMX_SC_ERR_VERSION */
	-EINVAL, /* IMX_SC_ERR_CONFIG */
	-EINVAL, /* IMX_SC_ERR_PARM */
	-EACCES, /* IMX_SC_ERR_NOACCESS */
	-EACCES, /* IMX_SC_ERR_LOCKED */
	-ERANGE, /* IMX_SC_ERR_UNAVAILABLE */
	-ENOENT, /* IMX_SC_ERR_NOTFOUND */
	-ENODEV, /* IMX_SC_ERR_NOPOWER */
	-ECOMM,	 /* IMX_SC_ERR_IPC */
	-EBUSY,	 /* IMX_SC_ERR_BUSY */
	-EIO,	 /* IMX_SC_ERR_FAIL */
};

static struct imx_sc_ipc *imx_sc_ipc_handle;

static inline int imx_sc_to_linux_errno(int errno)
{
	if (errno >= IMX_SC_ERR_NONE && errno < IMX_SC_ERR_LAST)
		return imx_sc_linux_errmap[errno];
	return -EIO;
}

/*
 * Get the default handle used by SCU
 */
int imx_scu_get_handle(struct imx_sc_ipc **ipc)
{
	if (!imx_sc_ipc_handle)
		return -EPROBE_DEFER;

	*ipc = imx_sc_ipc_handle;
	return 0;
}
EXPORT_SYMBOL(imx_scu_get_handle);

/* Callback called when the word of a message is ack-ed, eg read by SCU */
static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r)
{
	struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl);

	complete(&sc_chan->tx_done);
}

static void imx_scu_rx_callback(struct mbox_client *c, void *msg)
{
	struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl);

Annotation

Implementation Notes