summaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/divider.c
diff options
context:
space:
mode:
authorRuss Dill <Russ.Dill@ti.com>2018-09-04 08:49:37 +0200
committerTero Kristo <t-kristo@ti.com>2018-10-03 14:29:19 +0200
commitd6e7bbc148f9fbec8a0117b0d0f420c9710e6d81 (patch)
treefa2ac59eb7d2afd4b8af48d59dc30d673dd5f2f7 /drivers/clk/ti/divider.c
parentclk: clk: Add clk_gate_restore_context function (diff)
downloadlinux-d6e7bbc148f9fbec8a0117b0d0f420c9710e6d81.tar.xz
linux-d6e7bbc148f9fbec8a0117b0d0f420c9710e6d81.zip
clk: ti: Add functions to save/restore clk context
SoCs like AM43XX lose clock registers context during RTC-only suspend. Hence add functions to save/restore the clock registers context. Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Russ Dill <Russ.Dill@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Tero Kristo <t-kristo@ti.com>
Diffstat (limited to 'drivers/clk/ti/divider.c')
-rw-r--r--drivers/clk/ti/divider.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index ccfb4d9a152a..373f620f49cb 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -268,10 +268,46 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+/**
+ * clk_divider_save_context - Save the divider value
+ * @hw: pointer struct clk_hw
+ *
+ * Save the divider value
+ */
+static int clk_divider_save_context(struct clk_hw *hw)
+{
+ struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+ u32 val;
+
+ val = ti_clk_ll_ops->clk_readl(&divider->reg) >> divider->shift;
+ divider->context = val & div_mask(divider);
+
+ return 0;
+}
+
+/**
+ * clk_divider_restore_context - restore the saved the divider value
+ * @hw: pointer struct clk_hw
+ *
+ * Restore the saved the divider value
+ */
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+ struct clk_omap_divider *divider = to_clk_omap_divider(hw);
+ u32 val;
+
+ val = ti_clk_ll_ops->clk_readl(&divider->reg);
+ val &= ~(div_mask(divider) << divider->shift);
+ val |= divider->context << divider->shift;
+ ti_clk_ll_ops->clk_writel(val, &divider->reg);
+}
+
const struct clk_ops ti_clk_divider_ops = {
.recalc_rate = ti_clk_divider_recalc_rate,
.round_rate = ti_clk_divider_round_rate,
.set_rate = ti_clk_divider_set_rate,
+ .save_context = clk_divider_save_context,
+ .restore_context = clk_divider_restore_context,
};
static struct clk *_register_divider(struct device *dev, const char *name,