drivers/firmware/samsung/exynos-acpm-tmu.c

Source file repositories/reference/linux-study-clean/drivers/firmware/samsung/exynos-acpm-tmu.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/samsung/exynos-acpm-tmu.c
Extension
.c
Size
4836 bytes
Lines
240
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 acpm_tmu_tx {
	u16 ctx;
	u16 fw_use;
	u8 type;
	u8 rsvd0;
	u8 tzid;
	u8 rsvd1;
	u8 data[ACPM_TMU_TX_DATA_LEN];
} __packed;

struct acpm_tmu_rx {
	u16 ctx;
	u16 fw_use;
	u8 type;
	s8 ret;
	u8 tzid;
	s8 temp;
	u8 rsvd;
	u8 data[ACPM_TMU_RX_DATA_LEN];
} __packed;

union acpm_tmu_msg {
	u32 data[4];
	struct acpm_tmu_tx tx;
	struct acpm_tmu_rx rx;
};

static int acpm_tmu_to_linux_err(s8 fw_err)
{
	/*
	 * ACPM_TMU_INIT uses BIT(0) and BIT(1) of msg.rx.ret to flag APM
	 * capabilities. Treat zero and all positive values as success.
	 */
	if (fw_err >= 0)
		return 0;

	if (fw_err == -1)
		return -EACCES;

	return -EIO;
}

int acpm_tmu_init(struct acpm_handle *handle, unsigned int acpm_chan_id)
{
	union acpm_tmu_msg msg = {0};
	struct acpm_xfer xfer;
	int ret;

	msg.tx.type = ACPM_TMU_INIT;
	acpm_set_xfer(&xfer, msg.data, ARRAY_SIZE(msg.data), acpm_chan_id,
		      true);

	ret = acpm_do_xfer(handle, &xfer);
	if (ret)
		return ret;

	return acpm_tmu_to_linux_err(msg.rx.ret);
}

int acpm_tmu_read_temp(struct acpm_handle *handle, unsigned int acpm_chan_id,
		       u8 tz, int *temp)
{
	union acpm_tmu_msg msg = {0};
	struct acpm_xfer xfer;
	int ret;

	msg.tx.type = ACPM_TMU_READ_TEMP;
	msg.tx.tzid = tz;

	acpm_set_xfer(&xfer, msg.data, ARRAY_SIZE(msg.data), acpm_chan_id,
		      true);

	ret = acpm_do_xfer(handle, &xfer);
	if (ret)
		return ret;

	ret = acpm_tmu_to_linux_err(msg.rx.ret);
	if (ret)
		return ret;

	*temp = msg.rx.temp;

	return 0;
}

int acpm_tmu_set_threshold(struct acpm_handle *handle,
			   unsigned int acpm_chan_id, u8 tz,
			   const u8 temperature[8], size_t tlen)
{
	union acpm_tmu_msg msg = {0};

Annotation

Implementation Notes