drivers/rtc/rtc-sun6i.c
Source file repositories/reference/linux-study-clean/drivers/rtc/rtc-sun6i.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/rtc/rtc-sun6i.c- Extension
.c- Size
- 23669 bytes
- Lines
- 884
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/clk-provider.hlinux/clk/sunxi-ng.hlinux/delay.hlinux/err.hlinux/fs.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/module.hlinux/of.hlinux/of_address.hlinux/platform_device.hlinux/rtc.hlinux/slab.hlinux/types.h
Detected Declarations
struct sun6i_rtc_clk_datastruct sun6i_rtc_devfunction sun6i_rtc_osc_recalc_ratefunction sun6i_rtc_osc_get_parentfunction sun6i_rtc_osc_set_parentfunction sun6i_rtc_clk_initfunction sun6i_a31_rtc_clk_initfunction sun8i_a23_rtc_clk_initfunction sun8i_h3_rtc_clk_initfunction sun50i_h6_rtc_clk_initfunction sun8i_r40_rtc_clk_initfunction sun8i_v3_rtc_clk_initfunction sun6i_rtc_alarmirqfunction sun6i_rtc_setaiefunction sun6i_rtc_gettimefunction sun6i_rtc_getalarmfunction sun6i_rtc_setalarmfunction sun6i_rtc_waitfunction sun6i_rtc_settimefunction sun6i_rtc_alarm_irq_enablefunction sun6i_rtc_nvmem_readfunction sun6i_rtc_nvmem_writefunction sun6i_rtc_suspendfunction sun6i_rtc_resumefunction sun6i_rtc_bus_clk_cleanupfunction sun6i_rtc_probe
Annotated Snippet
struct sun6i_rtc_clk_data {
unsigned long rc_osc_rate;
unsigned int fixed_prescaler : 16;
unsigned int has_prescaler : 1;
unsigned int has_out_clk : 1;
unsigned int has_losc_en : 1;
unsigned int has_auto_swt : 1;
};
#define RTC_LINEAR_DAY BIT(0)
struct sun6i_rtc_dev {
struct rtc_device *rtc;
const struct sun6i_rtc_clk_data *data;
void __iomem *base;
int irq;
time64_t alarm;
unsigned long flags;
struct clk_hw hw;
struct clk_hw *int_osc;
struct clk *losc;
struct clk *ext_losc;
spinlock_t lock;
};
static struct sun6i_rtc_dev *sun6i_rtc;
static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
u32 val = 0;
val = readl(rtc->base + SUN6I_LOSC_CTRL);
if (val & SUN6I_LOSC_CTRL_EXT_OSC)
return parent_rate;
if (rtc->data->fixed_prescaler)
parent_rate /= rtc->data->fixed_prescaler;
if (rtc->data->has_prescaler) {
val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL);
val &= GENMASK(4, 0);
}
return parent_rate / (val + 1);
}
static u8 sun6i_rtc_osc_get_parent(struct clk_hw *hw)
{
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
return readl(rtc->base + SUN6I_LOSC_CTRL) & SUN6I_LOSC_CTRL_EXT_OSC;
}
static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index)
{
struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw);
unsigned long flags;
u32 val;
if (index > 1)
return -EINVAL;
spin_lock_irqsave(&rtc->lock, flags);
val = readl(rtc->base + SUN6I_LOSC_CTRL);
val &= ~SUN6I_LOSC_CTRL_EXT_OSC;
val |= SUN6I_LOSC_CTRL_KEY;
val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0;
if (rtc->data->has_losc_en) {
val &= ~SUN6I_LOSC_CTRL_EXT_LOSC_EN;
val |= index ? SUN6I_LOSC_CTRL_EXT_LOSC_EN : 0;
}
writel(val, rtc->base + SUN6I_LOSC_CTRL);
spin_unlock_irqrestore(&rtc->lock, flags);
return 0;
}
static const struct clk_ops sun6i_rtc_osc_ops = {
.recalc_rate = sun6i_rtc_osc_recalc_rate,
.determine_rate = clk_hw_determine_rate_no_reparent,
.get_parent = sun6i_rtc_osc_get_parent,
.set_parent = sun6i_rtc_osc_set_parent,
};
static void __init sun6i_rtc_clk_init(struct device_node *node,
Annotation
- Immediate include surface: `linux/clk.h`, `linux/clk-provider.h`, `linux/clk/sunxi-ng.h`, `linux/delay.h`, `linux/err.h`, `linux/fs.h`, `linux/init.h`, `linux/interrupt.h`.
- Detected declarations: `struct sun6i_rtc_clk_data`, `struct sun6i_rtc_dev`, `function sun6i_rtc_osc_recalc_rate`, `function sun6i_rtc_osc_get_parent`, `function sun6i_rtc_osc_set_parent`, `function sun6i_rtc_clk_init`, `function sun6i_a31_rtc_clk_init`, `function sun8i_a23_rtc_clk_init`, `function sun8i_h3_rtc_clk_init`, `function sun50i_h6_rtc_clk_init`.
- Atlas domain: Driver Families / drivers/rtc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.