drivers/clk/clk-pwm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-pwm.c
Extension
.c
Size
4179 bytes
Lines
184
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

struct clk_pwm {
	struct clk_hw hw;
	struct pwm_device *pwm;
	struct pwm_state state;
	u32 fixed_rate;
};

static inline struct clk_pwm *to_clk_pwm(struct clk_hw *hw)
{
	return container_of(hw, struct clk_pwm, hw);
}

static int clk_pwm_enable(struct clk_hw *hw)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);

	return pwm_apply_atomic(clk_pwm->pwm, &clk_pwm->state);
}

static void clk_pwm_disable(struct clk_hw *hw)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);
	struct pwm_state state = clk_pwm->state;

	state.enabled = false;

	pwm_apply_atomic(clk_pwm->pwm, &state);
}

static int clk_pwm_prepare(struct clk_hw *hw)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);

	return pwm_apply_might_sleep(clk_pwm->pwm, &clk_pwm->state);
}

static void clk_pwm_unprepare(struct clk_hw *hw)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);

	pwm_disable(clk_pwm->pwm);
}

static unsigned long clk_pwm_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);

	return clk_pwm->fixed_rate;
}

static int clk_pwm_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty)
{
	struct clk_pwm *clk_pwm = to_clk_pwm(hw);
	struct pwm_state state;
	int ret;

	ret = pwm_get_state_hw(clk_pwm->pwm, &state);
	if (ret)
		return ret;

	duty->num = state.duty_cycle;
	duty->den = state.period;

	return 0;
}

static const struct clk_ops clk_pwm_ops_atomic = {
	.enable = clk_pwm_enable,
	.disable = clk_pwm_disable,
	.recalc_rate = clk_pwm_recalc_rate,
	.get_duty_cycle = clk_pwm_get_duty_cycle,
};

static const struct clk_ops clk_pwm_ops = {
	.prepare = clk_pwm_prepare,
	.unprepare = clk_pwm_unprepare,
	.recalc_rate = clk_pwm_recalc_rate,
	.get_duty_cycle = clk_pwm_get_duty_cycle,
};

static int clk_pwm_probe(struct platform_device *pdev)
{
	struct device_node *node = pdev->dev.of_node;
	struct clk_init_data init;
	struct clk_pwm *clk_pwm;
	struct pwm_device *pwm;
	struct pwm_args pargs;
	const char *clk_name;
	int ret;

Annotation

Implementation Notes