drivers/rtc/rtc-ti-k3.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-ti-k3.c
Extension
.c
Size
18296 bytes
Lines
672
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 ti_k3_rtc {
	unsigned int irq;
	u32 sync_timeout_us;
	unsigned long rate_32k;
	struct rtc_device *rtc_dev;
	struct regmap *regmap;
	struct regmap_field *r_fields[K3_RTC_MAX_FIELDS];
};

static int k3rtc_field_read(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f)
{
	int ret;
	int val;

	ret = regmap_field_read(priv->r_fields[f], &val);
	/*
	 * We shouldn't be seeing regmap fail on us for mmio reads
	 * This is possible if clock context fails, but that isn't the case for us
	 */
	if (WARN_ON_ONCE(ret))
		return ret;
	return val;
}

static void k3rtc_field_write(struct ti_k3_rtc *priv, enum ti_k3_rtc_fields f, u32 val)
{
	regmap_field_write(priv->r_fields[f], val);
}

/**
 * k3rtc_fence  - Ensure a register sync took place between the two domains
 * @priv:      pointer to priv data
 *
 * Return: 0 if the sync took place, else returns -ETIMEDOUT
 */
static int k3rtc_fence(struct ti_k3_rtc *priv)
{
	int ret;

	ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_PEND], ret,
					     !ret, 2, priv->sync_timeout_us);

	return ret;
}

static inline int k3rtc_check_unlocked(struct ti_k3_rtc *priv)
{
	int ret;

	ret = k3rtc_field_read(priv, K3RTC_UNLOCK);
	if (ret < 0)
		return ret;

	return (ret) ? 0 : 1;
}

static int k3rtc_unlock_rtc(struct ti_k3_rtc *priv)
{
	int ret;

	ret = k3rtc_check_unlocked(priv);
	if (!ret)
		return ret;

	k3rtc_field_write(priv, K3RTC_KICK0, K3RTC_KICK0_UNLOCK_VALUE);
	k3rtc_field_write(priv, K3RTC_KICK1, K3RTC_KICK1_UNLOCK_VALUE);

	/* Skip fence since we are going to check the unlock bit as fence */
	ret = regmap_field_read_poll_timeout(priv->r_fields[K3RTC_UNLOCK], ret,
					     ret, 2, priv->sync_timeout_us);

	return ret;
}

/*
 * This is the list of SoCs affected by TI's i2327 errata causing the RTC
 * state-machine to break if not unlocked fast enough during boot. These
 * SoCs must have the bootloader unlock this device very early in the
 * boot-flow before we (Linux) can use this device.
 */
static const struct soc_device_attribute has_erratum_i2327[] = {
	{ .family = "AM62X", .revision = "SR1.0" },
	{ /* sentinel */ }
};

static int k3rtc_configure(struct device *dev)
{
	int ret;
	struct ti_k3_rtc *priv = dev_get_drvdata(dev);

Annotation

Implementation Notes