drivers/clk/clk-vt8500.c
Source file repositories/reference/linux-study-clean/drivers/clk/clk-vt8500.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/clk-vt8500.c- Extension
.c- Size
- 18383 bytes
- Lines
- 756
- 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/io.hlinux/of.hlinux/of_address.hlinux/slab.hlinux/bitops.hlinux/clkdev.hlinux/clk-provider.h
Detected Declarations
struct clk_devicestruct clk_pllfunction vtwm_set_pmc_basefunction vt8500_pmc_wait_busyfunction vt8500_dclk_enablefunction vt8500_dclk_disablefunction vt8500_dclk_is_enabledfunction vt8500_dclk_recalc_ratefunction vt8500_dclk_determine_ratefunction vt8500_dclk_set_ratefunction vtwm_device_clk_initfunction vt8500_find_pll_bitsfunction rangesfunction wm8750_get_filterfunction wm8750_find_pll_bitsfunction wm8850_find_pll_bitsfunction vtwm_pll_set_ratefunction vtwm_pll_determine_ratefunction vtwm_pll_recalc_ratefunction vtwm_pll_clk_initfunction vt8500_pll_initfunction wm8650_pll_initfunction wm8750_pll_initfunction wm8850_pll_init
Annotated Snippet
struct clk_device {
struct clk_hw hw;
void __iomem *div_reg;
unsigned int div_mask;
void __iomem *en_reg;
int en_bit;
spinlock_t *lock;
};
/*
* Add new PLL_TYPE_x definitions here as required. Use the first known model
* to support the new type as the name.
* Add case statements to vtwm_pll_recalc_rate(), vtwm_pll_round_round() and
* vtwm_pll_set_rate() to handle the new PLL_TYPE_x
*/
#define PLL_TYPE_VT8500 0
#define PLL_TYPE_WM8650 1
#define PLL_TYPE_WM8750 2
#define PLL_TYPE_WM8850 3
struct clk_pll {
struct clk_hw hw;
void __iomem *reg;
spinlock_t *lock;
int type;
};
static void __iomem *pmc_base;
static __init void vtwm_set_pmc_base(void)
{
struct device_node *np =
of_find_compatible_node(NULL, NULL, "via,vt8500-pmc");
if (np)
pmc_base = of_iomap(np, 0);
else
pmc_base = ioremap(LEGACY_PMC_BASE, 0x1000);
of_node_put(np);
if (!pmc_base)
pr_err("%s:of_iomap(pmc) failed\n", __func__);
}
#define to_clk_device(_hw) container_of(_hw, struct clk_device, hw)
#define VT8500_PMC_BUSY_MASK 0x18
static void vt8500_pmc_wait_busy(void)
{
while (readl(pmc_base) & VT8500_PMC_BUSY_MASK)
cpu_relax();
}
static int vt8500_dclk_enable(struct clk_hw *hw)
{
struct clk_device *cdev = to_clk_device(hw);
u32 en_val;
unsigned long flags = 0;
spin_lock_irqsave(cdev->lock, flags);
en_val = readl(cdev->en_reg);
en_val |= BIT(cdev->en_bit);
writel(en_val, cdev->en_reg);
spin_unlock_irqrestore(cdev->lock, flags);
return 0;
}
static void vt8500_dclk_disable(struct clk_hw *hw)
{
struct clk_device *cdev = to_clk_device(hw);
u32 en_val;
unsigned long flags = 0;
spin_lock_irqsave(cdev->lock, flags);
en_val = readl(cdev->en_reg);
en_val &= ~BIT(cdev->en_bit);
writel(en_val, cdev->en_reg);
spin_unlock_irqrestore(cdev->lock, flags);
}
static int vt8500_dclk_is_enabled(struct clk_hw *hw)
{
struct clk_device *cdev = to_clk_device(hw);
u32 en_val = (readl(cdev->en_reg) & BIT(cdev->en_bit));
Annotation
- Immediate include surface: `linux/io.h`, `linux/of.h`, `linux/of_address.h`, `linux/slab.h`, `linux/bitops.h`, `linux/clkdev.h`, `linux/clk-provider.h`.
- Detected declarations: `struct clk_device`, `struct clk_pll`, `function vtwm_set_pmc_base`, `function vt8500_pmc_wait_busy`, `function vt8500_dclk_enable`, `function vt8500_dclk_disable`, `function vt8500_dclk_is_enabled`, `function vt8500_dclk_recalc_rate`, `function vt8500_dclk_determine_rate`, `function vt8500_dclk_set_rate`.
- 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.