drivers/clk/bcm/clk-iproc-asiu.c
Source file repositories/reference/linux-study-clean/drivers/clk/bcm/clk-iproc-asiu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/bcm/clk-iproc-asiu.c- Extension
.c- Size
- 6309 bytes
- Lines
- 266
- 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/kernel.hlinux/err.hlinux/clk-provider.hlinux/io.hlinux/of.hlinux/clkdev.hlinux/of_address.hlinux/delay.hclk-iproc.h
Detected Declarations
struct iproc_asiustruct iproc_asiu_clkstruct iproc_asiufunction iproc_asiu_clk_enablefunction iproc_asiu_clk_disablefunction iproc_asiu_clk_recalc_ratefunction iproc_asiu_clk_determine_ratefunction iproc_asiu_clk_set_ratefunction iproc_asiu_setup
Annotated Snippet
struct iproc_asiu_clk {
struct clk_hw hw;
const char *name;
struct iproc_asiu *asiu;
unsigned long rate;
struct iproc_asiu_div div;
struct iproc_asiu_gate gate;
};
struct iproc_asiu {
void __iomem *div_base;
void __iomem *gate_base;
struct clk_hw_onecell_data *clk_data;
struct iproc_asiu_clk *clks;
};
#define to_asiu_clk(hw) container_of(hw, struct iproc_asiu_clk, hw)
static int iproc_asiu_clk_enable(struct clk_hw *hw)
{
struct iproc_asiu_clk *clk = to_asiu_clk(hw);
struct iproc_asiu *asiu = clk->asiu;
u32 val;
/* some clocks at the ASIU level are always enabled */
if (clk->gate.offset == IPROC_CLK_INVALID_OFFSET)
return 0;
val = readl(asiu->gate_base + clk->gate.offset);
val |= (1 << clk->gate.en_shift);
writel(val, asiu->gate_base + clk->gate.offset);
return 0;
}
static void iproc_asiu_clk_disable(struct clk_hw *hw)
{
struct iproc_asiu_clk *clk = to_asiu_clk(hw);
struct iproc_asiu *asiu = clk->asiu;
u32 val;
/* some clocks at the ASIU level are always enabled */
if (clk->gate.offset == IPROC_CLK_INVALID_OFFSET)
return;
val = readl(asiu->gate_base + clk->gate.offset);
val &= ~(1 << clk->gate.en_shift);
writel(val, asiu->gate_base + clk->gate.offset);
}
static unsigned long iproc_asiu_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct iproc_asiu_clk *clk = to_asiu_clk(hw);
struct iproc_asiu *asiu = clk->asiu;
u32 val;
unsigned int div_h, div_l;
if (parent_rate == 0) {
clk->rate = 0;
return 0;
}
/* if clock divisor is not enabled, simply return parent rate */
val = readl(asiu->div_base + clk->div.offset);
if ((val & (1 << clk->div.en_shift)) == 0) {
clk->rate = parent_rate;
return parent_rate;
}
/* clock rate = parent rate / (high_div + 1) + (low_div + 1) */
div_h = (val >> clk->div.high_shift) & bit_mask(clk->div.high_width);
div_h++;
div_l = (val >> clk->div.low_shift) & bit_mask(clk->div.low_width);
div_l++;
clk->rate = parent_rate / (div_h + div_l);
pr_debug("%s: rate: %lu. parent rate: %lu div_h: %u div_l: %u\n",
__func__, clk->rate, parent_rate, div_h, div_l);
return clk->rate;
}
static int iproc_asiu_clk_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
unsigned int div;
if (req->rate == 0 || req->best_parent_rate == 0)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/err.h`, `linux/clk-provider.h`, `linux/io.h`, `linux/of.h`, `linux/clkdev.h`, `linux/of_address.h`, `linux/delay.h`.
- Detected declarations: `struct iproc_asiu`, `struct iproc_asiu_clk`, `struct iproc_asiu`, `function iproc_asiu_clk_enable`, `function iproc_asiu_clk_disable`, `function iproc_asiu_clk_recalc_rate`, `function iproc_asiu_clk_determine_rate`, `function iproc_asiu_clk_set_rate`, `function iproc_asiu_setup`.
- 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.