Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4ff832d authored by Vikram Mulukutla's avatar Vikram Mulukutla
Browse files

msm: clock-generic: Introduce an ext_clk clock type



Some clock controllers have input clock signals from
other clock controllers or hardware blocks. To model
these exterior signals, introduce an ext_clk type that
just passes requests to its parent clock. The clock
controller using the ext_clk type will have to do a
clk_get to get a handle to the external clock, and set
that as the parent on the ext_clk clock.

Change-Id: I762f7b4663d5a55d95e5d3b6808004b77b58e2da
Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
parent 54938e72
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -500,3 +500,45 @@ struct clk_ops clk_ops_slave_div = {
	.set_rate = slave_div_set_rate,
	.handoff = div_handoff,
};


/**
 * External clock
 * Some clock controllers have input clock signal that come from outside the
 * clock controller. That input clock signal might then be used as a source for
 * several clocks inside the clock controller. This external clock
 * implementation models this input clock signal by just passing on the requests
 * to the clock's parent, the original external clock source. The driver for the
 * clock controller should clk_get() the original external clock in the probe
 * function and set is as a parent to this external clock..
 */

static long ext_round_rate(struct clk *c, unsigned long rate)
{
	return clk_round_rate(c->parent, rate);
}

static int ext_set_rate(struct clk *c, unsigned long rate)
{
	return clk_set_rate(c->parent, rate);
}

static int ext_set_parent(struct clk *c, struct clk *p)
{
	return clk_set_parent(c->parent, p);
}

static enum handoff ext_handoff(struct clk *c)
{
	c->rate = clk_get_rate(c->parent);
	/* Similar reasoning applied in div_handoff, see comment there. */
	return HANDOFF_DISABLED_CLK;
}

struct clk_ops clk_ops_ext = {
	.handoff = ext_handoff,
	.round_rate = ext_round_rate,
	.set_rate = ext_set_rate,
	.set_parent = ext_set_parent,
};
+16 −0
Original line number Diff line number Diff line
@@ -106,6 +106,12 @@ static inline struct div_clk *to_div_clk(struct clk *c)
extern struct clk_ops clk_ops_div;
extern struct clk_ops clk_ops_slave_div;

struct ext_clk {
	struct clk c;
};

extern struct clk_ops clk_ops_ext;

#define DEFINE_FIXED_DIV_CLK(clk_name, _div, _parent) \
static struct div_clk clk_name = {	\
	.div = _div,				\
@@ -128,4 +134,14 @@ static struct div_clk clk_name = { \
	}					\
}

#define DEFINE_EXT_CLK(clk_name, _parent) \
static struct ext_clk clk_name = {		\
	.c = {					\
		.parent = _parent,		\
		.dbg_name = #clk_name,		\
		.ops = &clk_ops_ext,		\
		CLK_INIT(clk_name.c),		\
	}					\
}

#endif