arch/mips/alchemy/common/clock.c
Source file repositories/reference/linux-study-clean/arch/mips/alchemy/common/clock.c
File Facts
- System
- Linux kernel
- Corpus path
arch/mips/alchemy/common/clock.c- Extension
.c- Size
- 27535 bytes
- Lines
- 1121
- Domain
- Architecture Layer
- Bucket
- arch/mips
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- 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.
- 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/init.hlinux/io.hlinux/clk.hlinux/clk-provider.hlinux/clkdev.hlinux/slab.hlinux/spinlock.hlinux/types.hasm/mach-au1x00/au1000.h
Detected Declarations
struct alchemy_auxpll_clkstruct alchemy_fgcs_clkfunction alchemy_clk_cpu_recalcfunction alchemy_set_lpjfunction alchemy_clk_aux_recalcfunction alchemy_clk_aux_setrfunction alchemy_clk_aux_determine_ratefunction alchemy_calc_divfunction alchemy_clk_fgcs_detrfunction alchemy_clk_fgv1_enfunction alchemy_clk_fgv1_isenfunction alchemy_clk_fgv1_disfunction alchemy_clk_fgv1_setpfunction alchemy_clk_fgv1_getpfunction alchemy_clk_fgv1_setrfunction alchemy_clk_fgv1_recalcfunction alchemy_clk_fgv1_detrfunction __alchemy_clk_fgv2_enfunction alchemy_clk_fgv2_enfunction alchemy_clk_fgv2_isenfunction alchemy_clk_fgv2_disfunction alchemy_clk_fgv2_setpfunction alchemy_clk_fgv2_getpfunction alchemy_clk_fgv2_setrfunction alchemy_clk_fgv2_recalcfunction alchemy_clk_fgv2_detrfunction alchemy_clk_init_fgensfunction alchemy_clk_csrc_isenfunction __alchemy_clk_csrc_enfunction alchemy_clk_csrc_enfunction alchemy_clk_csrc_disfunction alchemy_clk_csrc_setpfunction alchemy_clk_csrc_getpfunction alchemy_clk_csrc_recalcfunction alchemy_clk_csrc_setrfunction alchemy_clk_csrc_detrfunction alchemy_clk_setup_imuxfunction alchemy_clk_init
Annotated Snippet
struct alchemy_auxpll_clk {
struct clk_hw hw;
unsigned long reg; /* au1300 has also AUXPLL2 */
int maxmult; /* max multiplier */
};
#define to_auxpll_clk(x) container_of(x, struct alchemy_auxpll_clk, hw)
static unsigned long alchemy_clk_aux_recalc(struct clk_hw *hw,
unsigned long parent_rate)
{
struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
return (alchemy_rdsys(a->reg) & 0xff) * parent_rate;
}
static int alchemy_clk_aux_setr(struct clk_hw *hw,
unsigned long rate,
unsigned long parent_rate)
{
struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
unsigned long d = rate;
if (rate)
d /= parent_rate;
else
d = 0;
/* minimum is 84MHz, max is 756-1032 depending on variant */
if (((d < 7) && (d != 0)) || (d > a->maxmult))
return -EINVAL;
alchemy_wrsys(d, a->reg);
return 0;
}
static int alchemy_clk_aux_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct alchemy_auxpll_clk *a = to_auxpll_clk(hw);
unsigned long mult;
if (!req->rate || !req->best_parent_rate) {
req->rate = 0;
return 0;
}
mult = req->rate / req->best_parent_rate;
if (mult && (mult < 7))
mult = 7;
if (mult > a->maxmult)
mult = a->maxmult;
req->rate = req->best_parent_rate * mult;
return 0;
}
static const struct clk_ops alchemy_clkops_aux = {
.recalc_rate = alchemy_clk_aux_recalc,
.set_rate = alchemy_clk_aux_setr,
.determine_rate = alchemy_clk_aux_determine_rate,
};
static struct clk __init *alchemy_clk_setup_aux(const char *parent_name,
char *name, int maxmult,
unsigned long reg)
{
struct clk_init_data id;
struct clk *c;
struct alchemy_auxpll_clk *a;
a = kzalloc_obj(*a);
if (!a)
return ERR_PTR(-ENOMEM);
id.name = name;
id.parent_names = &parent_name;
id.num_parents = 1;
id.flags = CLK_GET_RATE_NOCACHE;
id.ops = &alchemy_clkops_aux;
a->reg = reg;
a->maxmult = maxmult;
a->hw.init = &id;
c = clk_register(NULL, &a->hw);
if (!IS_ERR(c))
clk_register_clkdev(c, name, NULL);
Annotation
- Immediate include surface: `linux/init.h`, `linux/io.h`, `linux/clk.h`, `linux/clk-provider.h`, `linux/clkdev.h`, `linux/slab.h`, `linux/spinlock.h`, `linux/types.h`.
- Detected declarations: `struct alchemy_auxpll_clk`, `struct alchemy_fgcs_clk`, `function alchemy_clk_cpu_recalc`, `function alchemy_set_lpj`, `function alchemy_clk_aux_recalc`, `function alchemy_clk_aux_setr`, `function alchemy_clk_aux_determine_rate`, `function alchemy_calc_div`, `function alchemy_clk_fgcs_detr`, `function alchemy_clk_fgv1_en`.
- Atlas domain: Architecture Layer / arch/mips.
- 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.