drivers/rtc/rtc-zynqmp.c
Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-zynqmp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rtc/rtc-zynqmp.c- Extension
.c- Size
- 11186 bytes
- Lines
- 424
- 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.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/delay.hlinux/init.hlinux/io.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/rtc.h
Detected Declarations
struct xlnx_rtc_devfunction xlnx_rtc_set_timefunction xlnx_rtc_read_timefunction xlnx_rtc_read_alarmfunction xlnx_rtc_alarm_irq_enablefunction xlnx_rtc_set_alarmfunction xlnx_init_rtcfunction xlnx_rtc_read_offsetfunction xlnx_rtc_set_offsetfunction xlnx_rtc_interruptfunction xlnx_rtc_probefunction xlnx_rtc_removefunction xlnx_rtc_suspendfunction xlnx_rtc_resume
Annotated Snippet
struct xlnx_rtc_dev {
struct rtc_device *rtc;
void __iomem *reg_base;
int alarm_irq;
int sec_irq;
struct clk *rtc_clk;
unsigned int freq;
};
static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
unsigned long new_time;
/*
* The value written will be updated after 1 sec into the
* seconds read register, so we need to program time +1 sec
* to get the correct time on read.
*/
new_time = rtc_tm_to_time64(tm) + 1;
writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
/*
* Clear the rtc interrupt status register after setting the
* time. During a read_time function, the code should read the
* RTC_INT_STATUS register and if bit 0 is still 0, it means
* that one second has not elapsed yet since RTC was set and
* the current time should be read from SET_TIME_READ register;
* otherwise, CURRENT_TIME register is read to report the time
*/
writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
return 0;
}
static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
u32 status;
unsigned long read_time;
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
status = readl(xrtcdev->reg_base + RTC_INT_STS);
if (status & RTC_INT_SEC) {
/*
* RTC has updated the CURRENT_TIME with the time written into
* SET_TIME_WRITE register.
*/
read_time = readl(xrtcdev->reg_base + RTC_CUR_TM);
} else {
/*
* Time written in SET_TIME_WRITE has not yet updated into
* the seconds read register, so read the time from the
* SET_TIME_WRITE instead of CURRENT_TIME register.
* Since we add +1 sec while writing, we need to -1 sec while
* reading.
*/
read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
}
rtc_time64_to_tm(read_time, tm);
return 0;
}
static int xlnx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_ALRM), &alrm->time);
alrm->enabled = readl(xrtcdev->reg_base + RTC_INT_MASK) & RTC_INT_ALRM;
return 0;
}
static int xlnx_rtc_alarm_irq_enable(struct device *dev, u32 enabled)
{
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
unsigned int status;
ulong timeout;
timeout = jiffies + msecs_to_jiffies(RTC_MSEC);
if (enabled) {
while (1) {
status = readl(xrtcdev->reg_base + RTC_INT_STS);
if (!((status & RTC_ALRM_MASK) == RTC_ALRM_MASK))
break;
if (time_after_eq(jiffies, timeout)) {
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/init.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/rtc.h`.
- Detected declarations: `struct xlnx_rtc_dev`, `function xlnx_rtc_set_time`, `function xlnx_rtc_read_time`, `function xlnx_rtc_read_alarm`, `function xlnx_rtc_alarm_irq_enable`, `function xlnx_rtc_set_alarm`, `function xlnx_init_rtc`, `function xlnx_rtc_read_offset`, `function xlnx_rtc_set_offset`, `function xlnx_rtc_interrupt`.
- Atlas domain: Driver Families / drivers/rtc.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.