drivers/clk/clk-multiplier.c
Source file repositories/reference/linux-study-clean/drivers/clk/clk-multiplier.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/clk-multiplier.c- Extension
.c- Size
- 3965 bytes
- Lines
- 159
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitops.hlinux/clk-provider.hlinux/err.hlinux/export.hlinux/io.hlinux/kernel.hlinux/of.hlinux/slab.h
Detected Declarations
function Copyrightfunction clk_mult_writelfunction __get_multfunction clk_multiplier_recalc_ratefunction __is_best_ratefunction __bestmultfunction clk_multiplier_determine_ratefunction clk_multiplier_set_rateexport clk_multiplier_ops
Annotated Snippet
if (rate == orig_parent_rate * i) {
/*
* This is the best case for us if we have a
* perfect match without changing the parent
* rate.
*/
*best_parent_rate = orig_parent_rate;
return i;
}
parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
rate / i);
current_rate = parent_rate * i;
if (__is_best_rate(rate, current_rate, best_rate, flags)) {
bestmult = i;
best_rate = current_rate;
*best_parent_rate = parent_rate;
}
}
return bestmult;
}
static int clk_multiplier_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct clk_multiplier *mult = to_clk_multiplier(hw);
unsigned long factor = __bestmult(hw, req->rate, &req->best_parent_rate,
mult->width, mult->flags);
req->rate = req->best_parent_rate * factor;
return 0;
}
static int clk_multiplier_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_multiplier *mult = to_clk_multiplier(hw);
unsigned long factor = __get_mult(mult, rate, parent_rate);
unsigned long flags = 0;
unsigned long val;
if (mult->lock)
spin_lock_irqsave(mult->lock, flags);
else
__acquire(mult->lock);
val = clk_mult_readl(mult);
val &= ~GENMASK(mult->width + mult->shift - 1, mult->shift);
val |= factor << mult->shift;
clk_mult_writel(mult, val);
if (mult->lock)
spin_unlock_irqrestore(mult->lock, flags);
else
__release(mult->lock);
return 0;
}
const struct clk_ops clk_multiplier_ops = {
.recalc_rate = clk_multiplier_recalc_rate,
.determine_rate = clk_multiplier_determine_rate,
.set_rate = clk_multiplier_set_rate,
};
EXPORT_SYMBOL_GPL(clk_multiplier_ops);
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/clk-provider.h`, `linux/err.h`, `linux/export.h`, `linux/io.h`, `linux/kernel.h`, `linux/of.h`, `linux/slab.h`.
- Detected declarations: `function Copyright`, `function clk_mult_writel`, `function __get_mult`, `function clk_multiplier_recalc_rate`, `function __is_best_rate`, `function __bestmult`, `function clk_multiplier_determine_rate`, `function clk_multiplier_set_rate`, `export clk_multiplier_ops`.
- Atlas domain: Driver Families / drivers/clk.
- Implementation status: integration 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.