drivers/clk/stm32/clk-stm32-core.c

Source file repositories/reference/linux-study-clean/drivers/clk/stm32/clk-stm32-core.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/stm32/clk-stm32-core.c
Extension
.c
Size
17741 bytes
Lines
697
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (IS_ERR(hw)) {
			dev_err(dev, "Can't register clk %d: %ld\n", n,
				PTR_ERR(hw));
			return PTR_ERR(hw);
		}

		if (cfg_clock->id != NO_ID)
			hws[cfg_clock->id] = hw;
	}

	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
}

int stm32_rcc_init(struct device *dev, const struct of_device_id *match_data,
		   void __iomem *base)
{
	const struct stm32_rcc_match_data *rcc_match_data;
	const struct of_device_id *match;
	int err;

	match = of_match_node(match_data, dev_of_node(dev));
	if (!match) {
		dev_err(dev, "match data not found\n");
		return -ENODEV;
	}

	rcc_match_data = match->data;

	/* RCC Reset Configuration */
	err = stm32_rcc_reset_init(dev, rcc_match_data->reset_data, base);
	if (err) {
		pr_err("stm32 reset failed to initialize\n");
		return err;
	}

	/* RCC Clock Configuration */
	err = stm32_rcc_clock_init(dev, match, base);
	if (err) {
		pr_err("stm32 clock failed to initialize\n");
		return err;
	}

	return 0;
}

static u8 stm32_mux_get_parent(void __iomem *base,
			       struct clk_stm32_clock_data *data,
			       u16 mux_id)
{
	const struct stm32_mux_cfg *mux = &data->muxes[mux_id];
	u32 mask = BIT(mux->width) - 1;
	u32 val;

	val = readl(base + mux->offset) >> mux->shift;
	val &= mask;

	return val;
}

static int stm32_mux_set_parent(void __iomem *base,
				struct clk_stm32_clock_data *data,
				u16 mux_id, u8 index)
{
	const struct stm32_mux_cfg *mux = &data->muxes[mux_id];

	u32 mask = BIT(mux->width) - 1;
	u32 reg = readl(base + mux->offset);
	u32 val = index << mux->shift;

	reg &= ~(mask << mux->shift);
	reg |= val;

	writel(reg, base + mux->offset);

	return 0;
}

static void stm32_gate_endisable(void __iomem *base,
				 struct clk_stm32_clock_data *data,
				 u16 gate_id, int enable)
{
	const struct stm32_gate_cfg *gate = &data->gates[gate_id];
	void __iomem *addr = base + gate->offset;

	if (enable) {
		if (data->gate_cpt[gate_id]++ > 0)
			return;

		if (gate->set_clr != 0)
			writel(BIT(gate->bit_idx), addr);

Annotation

Implementation Notes