This patch implements save and restore context for clk_super_mux and clk_super. During system supend, core power goes off the and context of Tegra CAR registers is lost. So during suspend entry, context of super clock registers are saved through save_context clk_ops and are restored through restore_context clk_ops to have them in same state as before suspend. Signed-off-by: Sowjanya Komatineni <skomatineni@xxxxxxxxxx> --- drivers/clk/tegra/clk-super.c | 40 ++++++++++++++++++++++++++++++++++++++++ drivers/clk/tegra/clk.h | 1 + 2 files changed, 41 insertions(+) diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index d73c587e4853..84492afd3f1d 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -121,9 +121,27 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index) return err; } +static int clk_super_mux_save_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); + + mux->parent_index_ctx = clk_super_get_parent(hw); + + return 0; +} + +static void clk_super_mux_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *mux = to_clk_super_mux(hw); + + clk_super_set_parent(hw, mux->parent_index_ctx); +} + static const struct clk_ops tegra_clk_super_mux_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, + .save_context = clk_super_mux_save_context, + .restore_context = clk_super_mux_restore_context, }; static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate, @@ -159,12 +177,34 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate, return super->div_ops->set_rate(div_hw, rate, parent_rate); } +static int clk_super_save_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); + struct clk_hw *div_hw = &super->frac_div.hw; + + super->parent_index_ctx = clk_super_get_parent(hw); + + return super->div_ops->save_context(div_hw); +} + +static void clk_super_restore_context(struct clk_hw *hw) +{ + struct tegra_clk_super_mux *super = to_clk_super_mux(hw); + struct clk_hw *div_hw = &super->frac_div.hw; + + clk_super_set_parent(hw, super->parent_index_ctx); + + super->div_ops->restore_context(div_hw); +} + const struct clk_ops tegra_clk_super_ops = { .get_parent = clk_super_get_parent, .set_parent = clk_super_set_parent, .set_rate = clk_super_set_rate, .round_rate = clk_super_round_rate, .recalc_rate = clk_super_recalc_rate, + .save_context = clk_super_save_context, + .restore_context = clk_super_restore_context, }; struct clk *tegra_clk_register_super_mux(const char *name, diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h index c357b49e49b0..562a3ee2d537 100644 --- a/drivers/clk/tegra/clk.h +++ b/drivers/clk/tegra/clk.h @@ -708,6 +708,7 @@ struct tegra_clk_super_mux { u8 div2_index; u8 pllx_index; spinlock_t *lock; + u8 parent_index_ctx; }; #define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw) -- 2.7.4