diff options
Diffstat (limited to 'drivers/clk/tegra/clk-periph.c')
| -rw-r--r-- | drivers/clk/tegra/clk-periph.c | 74 | 
1 files changed, 29 insertions, 45 deletions
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index b2309d37a96..9e899c18af8 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -111,46 +111,6 @@ static void clk_periph_disable(struct clk_hw *hw)  	gate_ops->disable(gate_hw);  } -void tegra_periph_reset_deassert(struct clk *c) -{ -	struct clk_hw *hw = __clk_get_hw(c); -	struct tegra_clk_periph *periph = to_clk_periph(hw); -	struct tegra_clk_periph_gate *gate; - -	if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { -		gate = to_clk_periph_gate(hw); -		if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { -			WARN_ON(1); -			return; -		} -	} else { -		gate = &periph->gate; -	} - -	tegra_periph_reset(gate, 0); -} -EXPORT_SYMBOL(tegra_periph_reset_deassert); - -void tegra_periph_reset_assert(struct clk *c) -{ -	struct clk_hw *hw = __clk_get_hw(c); -	struct tegra_clk_periph *periph = to_clk_periph(hw); -	struct tegra_clk_periph_gate *gate; - -	if (periph->magic != TEGRA_CLK_PERIPH_MAGIC) { -		gate = to_clk_periph_gate(hw); -		if (gate->magic != TEGRA_CLK_PERIPH_GATE_MAGIC) { -			WARN_ON(1); -			return; -		} -	} else { -		gate = &periph->gate; -	} - -	tegra_periph_reset(gate, 1); -} -EXPORT_SYMBOL(tegra_periph_reset_assert); -  const struct clk_ops tegra_clk_periph_ops = {  	.get_parent = clk_periph_get_parent,  	.set_parent = clk_periph_set_parent, @@ -162,7 +122,7 @@ const struct clk_ops tegra_clk_periph_ops = {  	.disable = clk_periph_disable,  }; -const struct clk_ops tegra_clk_periph_nodiv_ops = { +static const struct clk_ops tegra_clk_periph_nodiv_ops = {  	.get_parent = clk_periph_get_parent,  	.set_parent = clk_periph_set_parent,  	.is_enabled = clk_periph_is_enabled, @@ -170,27 +130,50 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = {  	.disable = clk_periph_disable,  }; +static const struct clk_ops tegra_clk_periph_no_gate_ops = { +	.get_parent = clk_periph_get_parent, +	.set_parent = clk_periph_set_parent, +	.recalc_rate = clk_periph_recalc_rate, +	.round_rate = clk_periph_round_rate, +	.set_rate = clk_periph_set_rate, +}; +  static struct clk *_tegra_clk_register_periph(const char *name,  			const char **parent_names, int num_parents,  			struct tegra_clk_periph *periph, -			void __iomem *clk_base, u32 offset, bool div, +			void __iomem *clk_base, u32 offset,  			unsigned long flags)  {  	struct clk *clk;  	struct clk_init_data init; +	struct tegra_clk_periph_regs *bank; +	bool div = !(periph->gate.flags & TEGRA_PERIPH_NO_DIV); + +	if (periph->gate.flags & TEGRA_PERIPH_NO_DIV) { +		flags |= CLK_SET_RATE_PARENT; +		init.ops = &tegra_clk_periph_nodiv_ops; +	} else if (periph->gate.flags & TEGRA_PERIPH_NO_GATE) +		init.ops = &tegra_clk_periph_no_gate_ops; +	else +		init.ops = &tegra_clk_periph_ops;  	init.name = name; -	init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops;  	init.flags = flags;  	init.parent_names = parent_names;  	init.num_parents = num_parents; +	bank = get_reg_bank(periph->gate.clk_num); +	if (!bank) +		return ERR_PTR(-EINVAL); +  	/* Data in .init is copied by clk_register(), so stack variable OK */  	periph->hw.init = &init;  	periph->magic = TEGRA_CLK_PERIPH_MAGIC;  	periph->mux.reg = clk_base + offset;  	periph->divider.reg = div ? (clk_base + offset) : NULL;  	periph->gate.clk_base = clk_base; +	periph->gate.regs = bank; +	periph->gate.enable_refcnt = periph_clk_enb_refcnt;  	clk = clk_register(NULL, &periph->hw);  	if (IS_ERR(clk)) @@ -209,7 +192,7 @@ struct clk *tegra_clk_register_periph(const char *name,  		u32 offset, unsigned long flags)  {  	return _tegra_clk_register_periph(name, parent_names, num_parents, -			periph, clk_base, offset, true, flags); +			periph, clk_base, offset, flags);  }  struct clk *tegra_clk_register_periph_nodiv(const char *name, @@ -217,6 +200,7 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,  		struct tegra_clk_periph *periph, void __iomem *clk_base,  		u32 offset)  { +	periph->gate.flags |= TEGRA_PERIPH_NO_DIV;  	return _tegra_clk_register_periph(name, parent_names, num_parents, -			periph, clk_base, offset, false, CLK_SET_RATE_PARENT); +			periph, clk_base, offset, CLK_SET_RATE_PARENT);  }  | 
