drivers/rtc/rtc-fsl-ftm-alarm.c

Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-fsl-ftm-alarm.c

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-fsl-ftm-alarm.c
Extension
.c
Size
8219 bytes
Lines
332
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 ftm_rtc {
	struct rtc_device *rtc_dev;
	void __iomem *base;
	bool big_endian;
	u32 alarm_freq;
};

static inline u32 rtc_readl(struct ftm_rtc *dev, u32 reg)
{
	if (dev->big_endian)
		return ioread32be(dev->base + reg);
	else
		return ioread32(dev->base + reg);
}

static inline void rtc_writel(struct ftm_rtc *dev, u32 reg, u32 val)
{
	if (dev->big_endian)
		iowrite32be(val, dev->base + reg);
	else
		iowrite32(val, dev->base + reg);
}

static inline void ftm_counter_enable(struct ftm_rtc *rtc)
{
	u32 val;

	/* select and enable counter clock source */
	val = rtc_readl(rtc, FTM_SC);
	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
	val |= (FTM_SC_PS_MASK | FTM_SC_CLK(FTM_SC_CLKS_FIXED_FREQ));
	rtc_writel(rtc, FTM_SC, val);
}

static inline void ftm_counter_disable(struct ftm_rtc *rtc)
{
	u32 val;

	/* disable counter clock source */
	val = rtc_readl(rtc, FTM_SC);
	val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
	rtc_writel(rtc, FTM_SC, val);
}

static inline void ftm_irq_acknowledge(struct ftm_rtc *rtc)
{
	unsigned int timeout = 100;

	/*
	 *Fix errata A-007728 for flextimer
	 *	If the FTM counter reaches the FTM_MOD value between
	 *	the reading of the TOF bit and the writing of 0 to
	 *	the TOF bit, the process of clearing the TOF bit
	 *	does not work as expected when FTMx_CONF[NUMTOF] != 0
	 *	and the current TOF count is less than FTMx_CONF[NUMTOF].
	 *	If the above condition is met, the TOF bit remains set.
	 *	If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1),the
	 *	TOF interrupt also remains asserted.
	 *
	 *	Above is the errata discription
	 *
	 *	In one word: software clearing TOF bit not works when
	 *	FTMx_CONF[NUMTOF] was seted as nonzero and FTM counter
	 *	reaches the FTM_MOD value.
	 *
	 *	The workaround is clearing TOF bit until it works
	 *	(FTM counter doesn't always reache the FTM_MOD anyway),
	 *	which may cost some cycles.
	 */
	while ((FTM_SC_TOF & rtc_readl(rtc, FTM_SC)) && timeout--)
		rtc_writel(rtc, FTM_SC, rtc_readl(rtc, FTM_SC) & (~FTM_SC_TOF));
}

static inline void ftm_irq_enable(struct ftm_rtc *rtc)
{
	u32 val;

	val = rtc_readl(rtc, FTM_SC);
	val |= FTM_SC_TOIE;
	rtc_writel(rtc, FTM_SC, val);
}

static inline void ftm_irq_disable(struct ftm_rtc *rtc)
{
	u32 val;

	val = rtc_readl(rtc, FTM_SC);
	val &= ~FTM_SC_TOIE;
	rtc_writel(rtc, FTM_SC, val);
}

Annotation

Implementation Notes