drivers/clk/analogbits/wrpll-cln28hpc.c
Source file repositories/reference/linux-study-clean/drivers/clk/analogbits/wrpll-cln28hpc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/analogbits/wrpll-cln28hpc.c- Extension
.c- Size
- 11473 bytes
- Lines
- 377
- Domain
- Driver Families
- Bucket
- drivers/clk
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bug.hlinux/err.hlinux/limits.hlinux/log2.hlinux/math64.hlinux/math.hlinux/minmax.hlinux/module.hlinux/clk/analogbits-wrpll-cln28hpc.h
Detected Declarations
function __wrpll_calc_filter_rangefunction __wrpll_calc_fbdivfunction __wrpll_calc_divqfunction __wrpll_update_parent_ratefunction wrpll_configure_for_ratefunction wrpll_calc_output_ratefunction lockexport wrpll_configure_for_rateexport wrpll_calc_output_rateexport wrpll_calc_max_lock_us
Annotated Snippet
if (__wrpll_update_parent_rate(c, parent_rate)) {
pr_err("%s: PLL input rate is out of range\n",
__func__);
return -ERANGE;
}
}
c->flags &= ~WRPLL_FLAGS_RESET_MASK;
/* Put the PLL into bypass if the user requests the parent clock rate */
if (target_rate == parent_rate) {
c->flags |= WRPLL_FLAGS_BYPASS_MASK;
return 0;
}
c->flags &= ~WRPLL_FLAGS_BYPASS_MASK;
/* Calculate the Q shift and target VCO rate */
divq = __wrpll_calc_divq(target_rate, &target_vco_rate);
if (!divq)
return -1;
c->divq = divq;
/* Precalculate the pre-Q divider target ratio */
ratio = div64_u64((target_vco_rate << ROUND_SHIFT), parent_rate);
fbdiv = __wrpll_calc_fbdiv(c);
best_r = 0;
best_f = 0;
best_delta = MAX_VCO_FREQ;
/*
* Consider all values for R which land within
* [MIN_POST_DIVR_FREQ, MAX_POST_DIVR_FREQ]; prefer smaller R
*/
for (r = c->init_r; r <= c->max_r; ++r) {
f_pre_div = ratio * r;
f = (f_pre_div + (1 << ROUND_SHIFT)) >> ROUND_SHIFT;
f >>= (fbdiv - 1);
post_divr_freq = div_u64(parent_rate, r);
vco_pre = fbdiv * post_divr_freq;
vco = vco_pre * f;
/* Ensure rounding didn't take us out of range */
if (vco > target_vco_rate) {
--f;
vco = vco_pre * f;
} else if (vco < MIN_VCO_FREQ) {
++f;
vco = vco_pre * f;
}
delta = abs(target_vco_rate - vco);
if (delta < best_delta) {
best_delta = delta;
best_r = r;
best_f = f;
}
}
c->divr = best_r - 1;
c->divf = best_f - 1;
post_divr_freq = div_u64(parent_rate, best_r);
/* Pick the best PLL jitter filter */
range = __wrpll_calc_filter_range(post_divr_freq);
if (range < 0)
return range;
c->range = range;
return 0;
}
EXPORT_SYMBOL_GPL(wrpll_configure_for_rate);
/**
* wrpll_calc_output_rate() - calculate the PLL's target output rate
* @c: ptr to a struct wrpll_cfg record to read from
* @parent_rate: PLL refclk rate
*
* Given a pointer to the PLL's current input configuration @c and the
* PLL's input reference clock rate @parent_rate (before the R
* pre-divider), calculate the PLL's output clock rate (after the Q
* post-divider).
*
* Context: Any context. Caller must protect the memory pointed to by @c
* from simultaneous modification.
*
* Return: the PLL's output clock rate, in Hz. The return value from
Annotation
- Immediate include surface: `linux/bug.h`, `linux/err.h`, `linux/limits.h`, `linux/log2.h`, `linux/math64.h`, `linux/math.h`, `linux/minmax.h`, `linux/module.h`.
- Detected declarations: `function __wrpll_calc_filter_range`, `function __wrpll_calc_fbdiv`, `function __wrpll_calc_divq`, `function __wrpll_update_parent_rate`, `function wrpll_configure_for_rate`, `function wrpll_calc_output_rate`, `function lock`, `export wrpll_configure_for_rate`, `export wrpll_calc_output_rate`, `export wrpll_calc_max_lock_us`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: integration implementation candidate.
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.