Skip to content

Commit 2b8cfd6

Browse files
Sowjanya Komatinenithierryreding
authored andcommitted
clk: tegra: periph: Add restore_context support
This patch implements restore_context support for clk-periph and clk-sdmmc-mux clock operations to restore clock parent and rates on system resume. During system suspend, core power goes off and looses the context of the Tegra clock controller registers. So on system resume, clocks parent and rate are restored back to the context before suspend based on cached data. Acked-by: Thierry Reding <[email protected]> Signed-off-by: Sowjanya Komatineni <[email protected]> Signed-off-by: Thierry Reding <[email protected]>
1 parent 50d4da9 commit 2b8cfd6

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

drivers/clk/tegra/clk-periph.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
44
*/
55

6+
#include <linux/clk.h>
67
#include <linux/clk-provider.h>
78
#include <linux/export.h>
89
#include <linux/slab.h>
@@ -99,6 +100,23 @@ static void clk_periph_disable(struct clk_hw *hw)
99100
gate_ops->disable(gate_hw);
100101
}
101102

103+
static void clk_periph_restore_context(struct clk_hw *hw)
104+
{
105+
struct tegra_clk_periph *periph = to_clk_periph(hw);
106+
const struct clk_ops *div_ops = periph->div_ops;
107+
struct clk_hw *div_hw = &periph->divider.hw;
108+
int parent_id;
109+
110+
parent_id = clk_hw_get_parent_index(hw);
111+
if (WARN_ON(parent_id < 0))
112+
return;
113+
114+
if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
115+
div_ops->restore_context(div_hw);
116+
117+
clk_periph_set_parent(hw, parent_id);
118+
}
119+
102120
const struct clk_ops tegra_clk_periph_ops = {
103121
.get_parent = clk_periph_get_parent,
104122
.set_parent = clk_periph_set_parent,
@@ -108,6 +126,7 @@ const struct clk_ops tegra_clk_periph_ops = {
108126
.is_enabled = clk_periph_is_enabled,
109127
.enable = clk_periph_enable,
110128
.disable = clk_periph_disable,
129+
.restore_context = clk_periph_restore_context,
111130
};
112131

113132
static const struct clk_ops tegra_clk_periph_nodiv_ops = {
@@ -116,6 +135,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
116135
.is_enabled = clk_periph_is_enabled,
117136
.enable = clk_periph_enable,
118137
.disable = clk_periph_disable,
138+
.restore_context = clk_periph_restore_context,
119139
};
120140

121141
static const struct clk_ops tegra_clk_periph_no_gate_ops = {
@@ -124,6 +144,7 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
124144
.recalc_rate = clk_periph_recalc_rate,
125145
.round_rate = clk_periph_round_rate,
126146
.set_rate = clk_periph_set_rate,
147+
.restore_context = clk_periph_restore_context,
127148
};
128149

129150
static struct clk *_tegra_clk_register_periph(const char *name,

drivers/clk/tegra/clk-sdmmc-mux.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,21 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw)
194194
gate_ops->disable(gate_hw);
195195
}
196196

197+
static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
198+
{
199+
struct clk_hw *parent = clk_hw_get_parent(hw);
200+
unsigned long parent_rate = clk_hw_get_rate(parent);
201+
unsigned long rate = clk_hw_get_rate(hw);
202+
int parent_id;
203+
204+
parent_id = clk_hw_get_parent_index(hw);
205+
if (WARN_ON(parent_id < 0))
206+
return;
207+
208+
clk_sdmmc_mux_set_parent(hw, parent_id);
209+
clk_sdmmc_mux_set_rate(hw, rate, parent_rate);
210+
}
211+
197212
static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
198213
.get_parent = clk_sdmmc_mux_get_parent,
199214
.set_parent = clk_sdmmc_mux_set_parent,
@@ -203,6 +218,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
203218
.is_enabled = clk_sdmmc_mux_is_enabled,
204219
.enable = clk_sdmmc_mux_enable,
205220
.disable = clk_sdmmc_mux_disable,
221+
.restore_context = clk_sdmmc_mux_restore_context,
206222
};
207223

208224
struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,

0 commit comments

Comments
 (0)