drivers/rtc/rtc-cadence.c
Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-cadence.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rtc/rtc-cadence.c- Extension
.c- Size
- 10628 bytes
- Lines
- 413
- 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/module.hlinux/platform_device.hlinux/of.hlinux/io.hlinux/rtc.hlinux/clk.hlinux/bcd.hlinux/bitfield.hlinux/interrupt.hlinux/pm_wakeirq.h
Detected Declarations
struct cdns_rtcfunction cdns_rtc_set_enabledfunction cdns_rtc_get_enabledfunction cdns_rtc_irq_handlerfunction cdns_rtc_time2regfunction cdns_rtc_reg2timefunction cdns_rtc_read_timefunction cdns_rtc_set_timefunction cdns_rtc_alarm_irq_enablefunction cdns_rtc_read_alarmfunction cdns_rtc_set_alarmfunction cdns_rtc_probefunction cdns_rtc_removefunction cdns_rtc_suspendfunction cdns_rtc_resume
Annotated Snippet
struct cdns_rtc {
struct rtc_device *rtc_dev;
struct clk *pclk;
struct clk *ref_clk;
void __iomem *regs;
int irq;
};
static void cdns_rtc_set_enabled(struct cdns_rtc *crtc, bool enabled)
{
u32 reg = enabled ? 0x0 : CDNS_RTC_CTLR_TIME_CAL;
writel(reg, crtc->regs + CDNS_RTC_CTLR);
}
static bool cdns_rtc_get_enabled(struct cdns_rtc *crtc)
{
return !(readl(crtc->regs + CDNS_RTC_CTLR) & CDNS_RTC_CTLR_TIME_CAL);
}
static irqreturn_t cdns_rtc_irq_handler(int irq, void *id)
{
struct device *dev = id;
struct cdns_rtc *crtc = dev_get_drvdata(dev);
/* Reading the register clears it */
if (!(readl(crtc->regs + CDNS_RTC_EFLR) & CDNS_RTC_AEI_ALRM))
return IRQ_NONE;
rtc_update_irq(crtc->rtc_dev, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static u32 cdns_rtc_time2reg(struct rtc_time *tm)
{
return FIELD_PREP(CDNS_RTC_TIME_S, bin2bcd(tm->tm_sec))
| FIELD_PREP(CDNS_RTC_TIME_M, bin2bcd(tm->tm_min))
| FIELD_PREP(CDNS_RTC_TIME_HR, bin2bcd(tm->tm_hour));
}
static void cdns_rtc_reg2time(u32 reg, struct rtc_time *tm)
{
tm->tm_sec = bcd2bin(FIELD_GET(CDNS_RTC_TIME_S, reg));
tm->tm_min = bcd2bin(FIELD_GET(CDNS_RTC_TIME_M, reg));
tm->tm_hour = bcd2bin(FIELD_GET(CDNS_RTC_TIME_HR, reg));
}
static int cdns_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct cdns_rtc *crtc = dev_get_drvdata(dev);
u32 reg;
/* If the RTC is disabled, assume the values are invalid */
if (!cdns_rtc_get_enabled(crtc))
return -EINVAL;
cdns_rtc_set_enabled(crtc, false);
reg = readl(crtc->regs + CDNS_RTC_TIMR);
cdns_rtc_reg2time(reg, tm);
reg = readl(crtc->regs + CDNS_RTC_CALR);
tm->tm_mday = bcd2bin(FIELD_GET(CDNS_RTC_CAL_D, reg));
tm->tm_mon = bcd2bin(FIELD_GET(CDNS_RTC_CAL_M, reg)) - 1;
tm->tm_year = bcd2bin(FIELD_GET(CDNS_RTC_CAL_Y, reg))
+ bcd2bin(FIELD_GET(CDNS_RTC_CAL_C, reg)) * 100 - 1900;
tm->tm_wday = bcd2bin(FIELD_GET(CDNS_RTC_CAL_DAY, reg)) - 1;
cdns_rtc_set_enabled(crtc, true);
return 0;
}
static int cdns_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct cdns_rtc *crtc = dev_get_drvdata(dev);
u32 timr, calr, stsr;
int ret = -EIO;
int year = tm->tm_year + 1900;
int tries;
cdns_rtc_set_enabled(crtc, false);
timr = cdns_rtc_time2reg(tm);
calr = FIELD_PREP(CDNS_RTC_CAL_D, bin2bcd(tm->tm_mday))
| FIELD_PREP(CDNS_RTC_CAL_M, bin2bcd(tm->tm_mon + 1))
| FIELD_PREP(CDNS_RTC_CAL_Y, bin2bcd(year % 100))
| FIELD_PREP(CDNS_RTC_CAL_C, bin2bcd(year / 100))
| FIELD_PREP(CDNS_RTC_CAL_DAY, tm->tm_wday + 1);
Annotation
- Immediate include surface: `linux/module.h`, `linux/platform_device.h`, `linux/of.h`, `linux/io.h`, `linux/rtc.h`, `linux/clk.h`, `linux/bcd.h`, `linux/bitfield.h`.
- Detected declarations: `struct cdns_rtc`, `function cdns_rtc_set_enabled`, `function cdns_rtc_get_enabled`, `function cdns_rtc_irq_handler`, `function cdns_rtc_time2reg`, `function cdns_rtc_reg2time`, `function cdns_rtc_read_time`, `function cdns_rtc_set_time`, `function cdns_rtc_alarm_irq_enable`, `function cdns_rtc_read_alarm`.
- 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.