drivers/clk/clk-sparx5.c
Source file repositories/reference/linux-study-clean/drivers/clk/clk-sparx5.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/clk-sparx5.c- Extension
.c- Size
- 6551 bytes
- Lines
- 298
- 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.
- 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/io.hlinux/module.hlinux/clk-provider.hlinux/bitfield.hlinux/of.hlinux/slab.hlinux/platform_device.hdt-bindings/clock/microchip,sparx5.h
Detected Declarations
struct s5_hw_clkstruct s5_clk_datastruct s5_pll_conffunction s5_calc_freqfunction s5_search_fractionalfunction s5_calc_paramsfunction s5_pll_enablefunction s5_pll_disablefunction s5_pll_set_ratefunction s5_pll_recalc_ratefunction s5_pll_determine_ratefunction s5_clk_probe
Annotated Snippet
struct s5_hw_clk {
struct clk_hw hw;
void __iomem *reg;
};
struct s5_clk_data {
void __iomem *base;
struct s5_hw_clk s5_hw[N_CLOCKS];
};
struct s5_pll_conf {
unsigned long freq;
u8 div;
bool rot_ena;
u8 rot_sel;
u8 rot_dir;
u8 pre_div;
};
#define to_s5_pll(hw) container_of(hw, struct s5_hw_clk, hw)
static unsigned long s5_calc_freq(unsigned long parent_rate,
const struct s5_pll_conf *conf)
{
unsigned long rate = parent_rate / conf->div;
if (conf->rot_ena) {
int sign = conf->rot_dir ? -1 : 1;
int divt = sel_rates[conf->rot_sel] * (1 + conf->pre_div);
int divb = divt + sign;
rate = mult_frac(rate, divt, divb);
rate = roundup(rate, 1000);
}
return rate;
}
static void s5_search_fractional(unsigned long rate,
unsigned long parent_rate,
int div,
struct s5_pll_conf *conf)
{
struct s5_pll_conf best;
ulong cur_offset, best_offset = rate;
int d, i, j;
memset(conf, 0, sizeof(*conf));
conf->div = div;
conf->rot_ena = 1; /* Fractional rate */
for (d = 0; best_offset > 0 && d <= 1 ; d++) {
conf->rot_dir = !!d;
for (i = 0; best_offset > 0 && i < MAX_PRE; i++) {
conf->pre_div = i;
for (j = 1; best_offset > 0 && j < MAX_SEL; j++) {
conf->rot_sel = j;
conf->freq = s5_calc_freq(parent_rate, conf);
cur_offset = abs(rate - conf->freq);
if (cur_offset < best_offset) {
best_offset = cur_offset;
best = *conf;
}
}
}
}
/* Best match */
*conf = best;
}
static unsigned long s5_calc_params(unsigned long rate,
unsigned long parent_rate,
struct s5_pll_conf *conf)
{
if (parent_rate % rate) {
struct s5_pll_conf alt1, alt2;
int div;
div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate);
s5_search_fractional(rate, parent_rate, div, &alt1);
/* Straight match? */
if (alt1.freq == rate) {
*conf = alt1;
} else {
/* Try without rounding divider */
div = parent_rate / rate;
if (div != alt1.div) {
s5_search_fractional(rate, parent_rate, div,
Annotation
- Immediate include surface: `linux/io.h`, `linux/module.h`, `linux/clk-provider.h`, `linux/bitfield.h`, `linux/of.h`, `linux/slab.h`, `linux/platform_device.h`, `dt-bindings/clock/microchip,sparx5.h`.
- Detected declarations: `struct s5_hw_clk`, `struct s5_clk_data`, `struct s5_pll_conf`, `function s5_calc_freq`, `function s5_search_fractional`, `function s5_calc_params`, `function s5_pll_enable`, `function s5_pll_disable`, `function s5_pll_set_rate`, `function s5_pll_recalc_rate`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: source 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.