drivers/clk/aspeed/clk-ast2600.c
Source file repositories/reference/linux-study-clean/drivers/clk/aspeed/clk-ast2600.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/aspeed/clk-ast2600.c- Extension
.c- Size
- 25698 bytes
- Lines
- 872
- 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/mfd/syscon.hlinux/mod_devicetable.hlinux/of_address.hlinux/platform_device.hlinux/regmap.hlinux/slab.hdt-bindings/clock/ast2600-clock.hclk-aspeed.h
Detected Declarations
function get_bitfunction get_reset_regfunction get_clock_regfunction aspeed_g6_clk_is_enabledfunction aspeed_g6_clk_enablefunction aspeed_g6_clk_disablefunction aspeed_g6_reset_deassertfunction aspeed_g6_reset_assertfunction aspeed_g6_reset_statusfunction aspeed_g6_clk_probefunction aspeed_g6_ccfunction aspeed_g6_cc_init
Annotated Snippet
if (val & BIT(24)) {
/* Pass through mode */
mult = div = 1;
} else {
/* F = 25Mhz * [(m + 1) / (n + 1)] / (p + 1) */
u32 m = val & 0x1fff;
u32 n = (val >> 13) & 0x3f;
u32 p = (val >> 19) & 0xf;
mult = (m + 1);
div = (n + 1) * (p + 1);
}
} else {
if (val & BIT(20)) {
/* Pass through mode */
mult = div = 1;
} else {
/* F = 25Mhz * (2-od) * [(m + 2) / (n + 1)] */
u32 m = (val >> 5) & 0x3f;
u32 od = (val >> 4) & 0x1;
u32 n = val & 0xf;
mult = (2 - od) * (m + 2);
div = n + 1;
}
}
return clk_hw_register_fixed_factor(NULL, name, "clkin", 0,
mult, div);
};
static u32 get_bit(u8 idx)
{
return BIT(idx % 32);
}
static u32 get_reset_reg(struct aspeed_clk_gate *gate)
{
if (gate->reset_idx < 32)
return ASPEED_G6_RESET_CTRL;
return ASPEED_G6_RESET_CTRL2;
}
static u32 get_clock_reg(struct aspeed_clk_gate *gate)
{
if (gate->clock_idx < 32)
return ASPEED_G6_CLK_STOP_CTRL;
return ASPEED_G6_CLK_STOP_CTRL2;
}
static int aspeed_g6_clk_is_enabled(struct clk_hw *hw)
{
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
u32 clk = get_bit(gate->clock_idx);
u32 rst = get_bit(gate->reset_idx);
u32 reg;
u32 enval;
/*
* If the IP is in reset, treat the clock as not enabled,
* this happens with some clocks such as the USB one when
* coming from cold reset. Without this, aspeed_clk_enable()
* will fail to lift the reset.
*/
if (gate->reset_idx >= 0) {
regmap_read(gate->map, get_reset_reg(gate), ®);
if (reg & rst)
return 0;
}
regmap_read(gate->map, get_clock_reg(gate), ®);
enval = (gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : clk;
return ((reg & clk) == enval) ? 1 : 0;
}
static int aspeed_g6_clk_enable(struct clk_hw *hw)
{
struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw);
unsigned long flags;
u32 clk = get_bit(gate->clock_idx);
u32 rst = get_bit(gate->reset_idx);
spin_lock_irqsave(gate->lock, flags);
if (aspeed_g6_clk_is_enabled(hw)) {
spin_unlock_irqrestore(gate->lock, flags);
Annotation
- Immediate include surface: `linux/mfd/syscon.h`, `linux/mod_devicetable.h`, `linux/of_address.h`, `linux/platform_device.h`, `linux/regmap.h`, `linux/slab.h`, `dt-bindings/clock/ast2600-clock.h`, `clk-aspeed.h`.
- Detected declarations: `function get_bit`, `function get_reset_reg`, `function get_clock_reg`, `function aspeed_g6_clk_is_enabled`, `function aspeed_g6_clk_enable`, `function aspeed_g6_clk_disable`, `function aspeed_g6_reset_deassert`, `function aspeed_g6_reset_assert`, `function aspeed_g6_reset_status`, `function aspeed_g6_clk_probe`.
- 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.