mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
clk: composite: Add support to change brother clock rate
Some composite clocks may have the same parent clock, if one clock change the parent clock rate, the other clock rate may too large, so add a brother clock in composite that the other clock also can be changed when parent rate is changed. Change-Id: I2c6749e578b76d6780cecdcd9ff1b5fd4f25a0ba Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
* Copyright (c) 2013 NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -149,8 +150,32 @@ static int clk_composite_set_rate_and_parent(struct clk_hw *hw,
|
||||
const struct clk_ops *mux_ops = composite->mux_ops;
|
||||
struct clk_hw *rate_hw = composite->rate_hw;
|
||||
struct clk_hw *mux_hw = composite->mux_hw;
|
||||
struct clk_hw *brother_hw = composite->brother_hw;
|
||||
unsigned long temp_rate;
|
||||
|
||||
if (brother_hw) {
|
||||
struct clk_composite *bcomposite = to_clk_composite(brother_hw);
|
||||
const struct clk_ops *brate_ops = bcomposite->rate_ops;
|
||||
struct clk_hw *brate_hw = bcomposite->rate_hw;
|
||||
struct clk_hw *parent_hw = clk_hw_get_parent(brother_hw);
|
||||
struct clk_hw *new_parent_hw = clk_hw_get_parent(hw);
|
||||
|
||||
__clk_hw_set_clk(brate_hw, brother_hw);
|
||||
|
||||
temp_rate = brate_ops->recalc_rate(brate_hw, parent_rate);
|
||||
if (temp_rate > rate)
|
||||
brate_ops->set_rate(brate_hw, rate, parent_rate);
|
||||
if (clk_hw_is_prepared(brother_hw)) {
|
||||
clk_prepare_enable(new_parent_hw->clk);
|
||||
clk_enable(brother_hw->clk);
|
||||
}
|
||||
clk_hw_reparent(brother_hw, new_parent_hw);
|
||||
if (clk_hw_is_prepared(brother_hw)) {
|
||||
clk_disable(brother_hw->clk);
|
||||
clk_disable_unprepare(parent_hw->clk);
|
||||
}
|
||||
}
|
||||
|
||||
__clk_hw_set_clk(rate_hw, hw);
|
||||
__clk_hw_set_clk(mux_hw, hw);
|
||||
|
||||
|
||||
@@ -1035,6 +1035,9 @@ extern const struct clk_ops clk_multiplier_ops;
|
||||
* @mux_hw: handle between composite and hardware-specific mux clock
|
||||
* @rate_hw: handle between composite and hardware-specific rate clock
|
||||
* @gate_hw: handle between composite and hardware-specific gate clock
|
||||
* @brother_hw: a member of clk_composite who has the common parent clocks
|
||||
* with another clk_composite, and it's also a handle between
|
||||
* common and hardware-specific interfaces
|
||||
* @mux_ops: clock ops for mux
|
||||
* @rate_ops: clock ops for rate
|
||||
* @gate_ops: clock ops for gate
|
||||
@@ -1046,6 +1049,7 @@ struct clk_composite {
|
||||
struct clk_hw *mux_hw;
|
||||
struct clk_hw *rate_hw;
|
||||
struct clk_hw *gate_hw;
|
||||
struct clk_hw *brother_hw;
|
||||
|
||||
const struct clk_ops *mux_ops;
|
||||
const struct clk_ops *rate_ops;
|
||||
|
||||
Reference in New Issue
Block a user