drivers/clk/clk-apple-nco.c
Source file repositories/reference/linux-study-clean/drivers/clk/clk-apple-nco.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/clk-apple-nco.c- Extension
.c- Size
- 8923 bytes
- Lines
- 341
- Domain
- Driver Families
- Bucket
- drivers/clk
- 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.
- 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/bits.hlinux/bitfield.hlinux/clk-provider.hlinux/io.hlinux/kernel.hlinux/math64.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/spinlock.h
Detected Declarations
struct applnco_tablesstruct applnco_channelfunction applnco_enable_nolockfunction applnco_disable_nolockfunction applnco_is_enabledfunction applnco_compute_tablesfunction applnco_div_out_of_rangefunction applnco_div_translatefunction applnco_div_translate_invfunction applnco_set_ratefunction applnco_recalc_ratefunction applnco_determine_ratefunction applnco_enablefunction applnco_disablefunction applnco_probe
Annotated Snippet
struct applnco_tables {
u16 fwd[LFSR_TBLSIZE];
u16 inv[LFSR_TBLSIZE];
};
struct applnco_channel {
void __iomem *base;
struct applnco_tables *tbl;
struct clk_hw hw;
spinlock_t lock;
};
#define to_applnco_channel(_hw) container_of(_hw, struct applnco_channel, hw)
static void applnco_enable_nolock(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
u32 val;
val = readl_relaxed(chan->base + REG_CTRL);
writel_relaxed(val | CTRL_ENABLE, chan->base + REG_CTRL);
}
static void applnco_disable_nolock(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
u32 val;
val = readl_relaxed(chan->base + REG_CTRL);
writel_relaxed(val & ~CTRL_ENABLE, chan->base + REG_CTRL);
}
static int applnco_is_enabled(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
return (readl_relaxed(chan->base + REG_CTRL) & CTRL_ENABLE) != 0;
}
static void applnco_compute_tables(struct applnco_tables *tbl)
{
int i;
u32 state = LFSR_INIT;
/*
* Go through the states of a Galois LFSR and build
* a coarse divisor translation table.
*/
for (i = LFSR_PERIOD; i > 0; i--) {
if (state & 1)
state = (state >> 1) ^ (LFSR_POLY >> 1);
else
state = (state >> 1);
tbl->fwd[i] = state;
tbl->inv[state] = i;
}
/* Zero value is special-cased */
tbl->fwd[0] = 0;
tbl->inv[0] = 0;
}
static bool applnco_div_out_of_range(unsigned int div)
{
unsigned int coarse = div / 4;
return coarse < COARSE_DIV_OFFSET ||
coarse >= COARSE_DIV_OFFSET + LFSR_TBLSIZE;
}
static u32 applnco_div_translate(struct applnco_tables *tbl, unsigned int div)
{
unsigned int coarse = div / 4;
if (WARN_ON(applnco_div_out_of_range(div)))
return 0;
return FIELD_PREP(DIV_COARSE, tbl->fwd[coarse - COARSE_DIV_OFFSET]) |
FIELD_PREP(DIV_FINE, div % 4);
}
static unsigned int applnco_div_translate_inv(struct applnco_tables *tbl, u32 regval)
{
unsigned int coarse, fine;
coarse = tbl->inv[FIELD_GET(DIV_COARSE, regval)] + COARSE_DIV_OFFSET;
fine = FIELD_GET(DIV_FINE, regval);
return coarse * 4 + fine;
Annotation
- Immediate include surface: `linux/bits.h`, `linux/bitfield.h`, `linux/clk-provider.h`, `linux/io.h`, `linux/kernel.h`, `linux/math64.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct applnco_tables`, `struct applnco_channel`, `function applnco_enable_nolock`, `function applnco_disable_nolock`, `function applnco_is_enabled`, `function applnco_compute_tables`, `function applnco_div_out_of_range`, `function applnco_div_translate`, `function applnco_div_translate_inv`, `function applnco_set_rate`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.