drivers/rtc/rtc-optee.c

Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-optee.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-optee.c
Extension
.c
Size
19844 bytes
Lines
736
Domain
Driver Families
Bucket
drivers/rtc
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 optee_rtc_time {
	u32 tm_sec;
	u32 tm_min;
	u32 tm_hour;
	u32 tm_mday;
	u32 tm_mon;
	u32 tm_year;
	u32 tm_wday;
};

struct optee_rtc_alarm {
	u8 enabled;
	u8 pending;
	struct optee_rtc_time time;
};

struct optee_rtc_info {
	u64 version;
	u64 features;
	struct optee_rtc_time range_min;
	struct optee_rtc_time range_max;
};

/**
 * struct optee_rtc - OP-TEE RTC private data
 * @dev:		OP-TEE based RTC device.
 * @ctx:		OP-TEE context handler.
 * @session_id:		RTC TA session identifier.
 * @session2_id:	RTC wait alarm session identifier.
 * @shm:		Memory pool shared with RTC device.
 * @features:		Bitfield of RTC features
 * @alarm_task:		RTC wait alamr task.
 * @rtc:		RTC device.
 */
struct optee_rtc {
	struct device *dev;
	struct tee_context *ctx;
	u32 session_id;
	u32 session2_id;
	struct tee_shm *shm;
	u64 features;
	struct task_struct *alarm_task;
	struct rtc_device *rtc;
};

static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm)
{
	struct optee_rtc *priv = dev_get_drvdata(dev);
	struct tee_ioctl_invoke_arg inv_arg = {0};
	struct optee_rtc_time *optee_tm;
	struct tee_param param[4] = {0};
	int ret;

	inv_arg.func = PTA_CMD_RTC_GET_TIME;
	inv_arg.session = priv->session_id;
	inv_arg.num_params = 4;

	/* Fill invoke cmd params */
	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
	param[0].u.memref.shm = priv->shm;
	param[0].u.memref.size = sizeof(struct optee_rtc_time);

	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
	if (ret < 0 || inv_arg.ret != 0)
		return ret ? ret : -EPROTO;

	optee_tm = tee_shm_get_va(priv->shm, 0);
	if (IS_ERR(optee_tm))
		return PTR_ERR(optee_tm);

	if (param[0].u.memref.size != sizeof(*optee_tm))
		return -EPROTO;

	tm->tm_sec = optee_tm->tm_sec;
	tm->tm_min = optee_tm->tm_min;
	tm->tm_hour = optee_tm->tm_hour;
	tm->tm_mday = optee_tm->tm_mday;
	tm->tm_mon = optee_tm->tm_mon;
	tm->tm_year = optee_tm->tm_year - 1900;
	tm->tm_wday = optee_tm->tm_wday;
	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);

	return 0;
}

static int optee_rtc_settime(struct device *dev, struct rtc_time *tm)
{
	struct optee_rtc *priv = dev_get_drvdata(dev);
	struct tee_ioctl_invoke_arg inv_arg = {0};
	struct tee_param param[4] = {0};

Annotation

Implementation Notes