drivers/clk/bcm/clk-bcm53573-ilp.c
Source file repositories/reference/linux-study-clean/drivers/clk/bcm/clk-bcm53573-ilp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/clk/bcm/clk-bcm53573-ilp.c- Extension
.c- Size
- 3428 bytes
- Lines
- 146
- 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/clk-provider.hlinux/err.hlinux/io.hlinux/mfd/syscon.hlinux/of.hlinux/of_address.hlinux/regmap.hlinux/slab.h
Detected Declarations
struct bcm53573_ilpfunction bcm53573_ilp_enablefunction bcm53573_ilp_disablefunction bcm53573_ilp_recalc_ratefunction bcm53573_ilp_init
Annotated Snippet
struct bcm53573_ilp {
struct clk_hw hw;
struct regmap *regmap;
};
static int bcm53573_ilp_enable(struct clk_hw *hw)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0x10199);
regmap_write(ilp->regmap, 0x674, 0x10000);
return 0;
}
static void bcm53573_ilp_disable(struct clk_hw *hw)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
regmap_write(ilp->regmap, PMU_SLOW_CLK_PERIOD, 0);
regmap_write(ilp->regmap, 0x674, 0);
}
static unsigned long bcm53573_ilp_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct bcm53573_ilp *ilp = container_of(hw, struct bcm53573_ilp, hw);
struct regmap *regmap = ilp->regmap;
u32 last_val, cur_val;
int sum = 0, num = 0, loop_num = 0;
int avg;
/* Enable measurement */
regmap_write(regmap, PMU_XTAL_FREQ_RATIO, XTAL_CTL_EN);
/* Read initial value */
regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &last_val);
last_val &= XTAL_ALP_PER_4ILP;
/*
* At minimum we should loop for a bit to let hardware do the
* measurement. This isn't very accurate however, so for a better
* precision let's try getting 20 different values and use average.
*/
while (num < 20) {
regmap_read(regmap, PMU_XTAL_FREQ_RATIO, &cur_val);
cur_val &= XTAL_ALP_PER_4ILP;
if (cur_val != last_val) {
/* Got different value, use it */
sum += cur_val;
num++;
loop_num = 0;
last_val = cur_val;
} else if (++loop_num > 5000) {
/* Same value over and over, give up */
sum += cur_val;
num++;
break;
}
cpu_relax();
}
/* Disable measurement to save power */
regmap_write(regmap, PMU_XTAL_FREQ_RATIO, 0x0);
avg = sum / num;
return parent_rate * 4 / avg;
}
static const struct clk_ops bcm53573_ilp_clk_ops = {
.enable = bcm53573_ilp_enable,
.disable = bcm53573_ilp_disable,
.recalc_rate = bcm53573_ilp_recalc_rate,
};
static void bcm53573_ilp_init(struct device_node *np)
{
struct bcm53573_ilp *ilp;
struct clk_init_data init = { };
const char *parent_name;
int err;
ilp = kzalloc_obj(*ilp);
if (!ilp)
return;
parent_name = of_clk_get_parent_name(np, 0);
Annotation
- Immediate include surface: `linux/clk-provider.h`, `linux/err.h`, `linux/io.h`, `linux/mfd/syscon.h`, `linux/of.h`, `linux/of_address.h`, `linux/regmap.h`, `linux/slab.h`.
- Detected declarations: `struct bcm53573_ilp`, `function bcm53573_ilp_enable`, `function bcm53573_ilp_disable`, `function bcm53573_ilp_recalc_rate`, `function bcm53573_ilp_init`.
- 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.