drivers/clk/davinci/da8xx-cfgchip.c

Source file repositories/reference/linux-study-clean/drivers/clk/davinci/da8xx-cfgchip.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/davinci/da8xx-cfgchip.c
Extension
.c
Size
19717 bytes
Lines
788
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

struct da8xx_cfgchip_gate_clk_info {
	const char *name;
	u32 cfgchip;
	u32 bit;
	u32 flags;
};

struct da8xx_cfgchip_gate_clk {
	struct clk_hw hw;
	struct regmap *regmap;
	u32 reg;
	u32 mask;
};

#define to_da8xx_cfgchip_gate_clk(_hw) \
	container_of((_hw), struct da8xx_cfgchip_gate_clk, hw)

static int da8xx_cfgchip_gate_clk_enable(struct clk_hw *hw)
{
	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);

	return regmap_write_bits(clk->regmap, clk->reg, clk->mask, clk->mask);
}

static void da8xx_cfgchip_gate_clk_disable(struct clk_hw *hw)
{
	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);

	regmap_write_bits(clk->regmap, clk->reg, clk->mask, 0);
}

static int da8xx_cfgchip_gate_clk_is_enabled(struct clk_hw *hw)
{
	struct da8xx_cfgchip_gate_clk *clk = to_da8xx_cfgchip_gate_clk(hw);
	unsigned int val;

	regmap_read(clk->regmap, clk->reg, &val);

	return !!(val & clk->mask);
}

static unsigned long da8xx_cfgchip_div4p5_recalc_rate(struct clk_hw *hw,
						      unsigned long parent_rate)
{
	/* this clock divides by 4.5 */
	return parent_rate * 2 / 9;
}

static const struct clk_ops da8xx_cfgchip_gate_clk_ops = {
	.enable		= da8xx_cfgchip_gate_clk_enable,
	.disable	= da8xx_cfgchip_gate_clk_disable,
	.is_enabled	= da8xx_cfgchip_gate_clk_is_enabled,
};

static const struct clk_ops da8xx_cfgchip_div4p5_clk_ops = {
	.enable		= da8xx_cfgchip_gate_clk_enable,
	.disable	= da8xx_cfgchip_gate_clk_disable,
	.is_enabled	= da8xx_cfgchip_gate_clk_is_enabled,
	.recalc_rate	= da8xx_cfgchip_div4p5_recalc_rate,
};

static struct da8xx_cfgchip_gate_clk * __init
da8xx_cfgchip_gate_clk_register(struct device *dev,
				const struct da8xx_cfgchip_gate_clk_info *info,
				struct regmap *regmap)
{
	struct clk *parent;
	const char *parent_name;
	struct da8xx_cfgchip_gate_clk *gate;
	struct clk_init_data init;
	int ret;

	parent = devm_clk_get(dev, NULL);
	if (IS_ERR(parent))
		return ERR_CAST(parent);

	parent_name = __clk_get_name(parent);

	gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
	if (!gate)
		return ERR_PTR(-ENOMEM);

	init.name = info->name;
	if (info->flags & DA8XX_GATE_CLOCK_IS_DIV4P5)
		init.ops = &da8xx_cfgchip_div4p5_clk_ops;
	else
		init.ops = &da8xx_cfgchip_gate_clk_ops;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	init.flags = 0;

Annotation

Implementation Notes