drivers/rtc/rtc-jz4740.c

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

File Facts

System
Linux kernel
Corpus path
drivers/rtc/rtc-jz4740.c
Extension
.c
Size
11209 bytes
Lines
440
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 jz4740_rtc {
	void __iomem *base;
	enum jz4740_rtc_type type;

	struct rtc_device *rtc;

	struct clk_hw clk32k;

	spinlock_t lock;
};

static struct device *dev_for_power_off;

static inline uint32_t jz4740_rtc_reg_read(struct jz4740_rtc *rtc, size_t reg)
{
	return readl(rtc->base + reg);
}

static int jz4740_rtc_wait_write_ready(struct jz4740_rtc *rtc)
{
	uint32_t ctrl;

	return readl_poll_timeout(rtc->base + JZ_REG_RTC_CTRL, ctrl,
				  ctrl & JZ_RTC_CTRL_WRDY, 0, 1000);
}

static inline int jz4780_rtc_enable_write(struct jz4740_rtc *rtc)
{
	uint32_t ctrl;
	int ret;

	ret = jz4740_rtc_wait_write_ready(rtc);
	if (ret != 0)
		return ret;

	writel(JZ_RTC_WENR_MAGIC, rtc->base + JZ_REG_RTC_WENR);

	return readl_poll_timeout(rtc->base + JZ_REG_RTC_WENR, ctrl,
				  ctrl & JZ_RTC_WENR_WEN, 0, 1000);
}

static inline int jz4740_rtc_reg_write(struct jz4740_rtc *rtc, size_t reg,
	uint32_t val)
{
	int ret = 0;

	if (rtc->type >= ID_JZ4760)
		ret = jz4780_rtc_enable_write(rtc);
	if (ret == 0)
		ret = jz4740_rtc_wait_write_ready(rtc);
	if (ret == 0)
		writel(val, rtc->base + reg);

	return ret;
}

static int jz4740_rtc_ctrl_set_bits(struct jz4740_rtc *rtc, uint32_t mask,
	bool set)
{
	int ret;
	unsigned long flags;
	uint32_t ctrl;

	spin_lock_irqsave(&rtc->lock, flags);

	ctrl = jz4740_rtc_reg_read(rtc, JZ_REG_RTC_CTRL);

	/* Don't clear interrupt flags by accident */
	ctrl |= JZ_RTC_CTRL_1HZ | JZ_RTC_CTRL_AF;

	if (set)
		ctrl |= mask;
	else
		ctrl &= ~mask;

	ret = jz4740_rtc_reg_write(rtc, JZ_REG_RTC_CTRL, ctrl);

	spin_unlock_irqrestore(&rtc->lock, flags);

	return ret;
}

static int jz4740_rtc_read_time(struct device *dev, struct rtc_time *time)
{
	struct jz4740_rtc *rtc = dev_get_drvdata(dev);
	uint32_t secs, secs2;
	int timeout = 5;

	if (jz4740_rtc_reg_read(rtc, JZ_REG_RTC_SCRATCHPAD) != 0x12345678)
		return -EINVAL;

Annotation

Implementation Notes