* Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/export.h>
 #include <linux/slab.h>
        gate_ops->disable(gate_hw);
 }
 
+static void clk_periph_restore_context(struct clk_hw *hw)
+{
+       struct tegra_clk_periph *periph = to_clk_periph(hw);
+       const struct clk_ops *div_ops = periph->div_ops;
+       struct clk_hw *div_hw = &periph->divider.hw;
+       int parent_id;
+
+       parent_id = clk_hw_get_parent_index(hw);
+       if (WARN_ON(parent_id < 0))
+               return;
+
+       if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
+               div_ops->restore_context(div_hw);
+
+       clk_periph_set_parent(hw, parent_id);
+}
+
 const struct clk_ops tegra_clk_periph_ops = {
        .get_parent = clk_periph_get_parent,
        .set_parent = clk_periph_set_parent,
        .is_enabled = clk_periph_is_enabled,
        .enable = clk_periph_enable,
        .disable = clk_periph_disable,
+       .restore_context = clk_periph_restore_context,
 };
 
 static const struct clk_ops tegra_clk_periph_nodiv_ops = {
        .is_enabled = clk_periph_is_enabled,
        .enable = clk_periph_enable,
        .disable = clk_periph_disable,
+       .restore_context = clk_periph_restore_context,
 };
 
 static const struct clk_ops tegra_clk_periph_no_gate_ops = {
        .recalc_rate = clk_periph_recalc_rate,
        .round_rate = clk_periph_round_rate,
        .set_rate = clk_periph_set_rate,
+       .restore_context = clk_periph_restore_context,
 };
 
 static struct clk *_tegra_clk_register_periph(const char *name,
 
        gate_ops->disable(gate_hw);
 }
 
+static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
+{
+       struct clk_hw *parent = clk_hw_get_parent(hw);
+       unsigned long parent_rate = clk_hw_get_rate(parent);
+       unsigned long rate = clk_hw_get_rate(hw);
+       int parent_id;
+
+       parent_id = clk_hw_get_parent_index(hw);
+       if (WARN_ON(parent_id < 0))
+               return;
+
+       clk_sdmmc_mux_set_parent(hw, parent_id);
+       clk_sdmmc_mux_set_rate(hw, rate, parent_rate);
+}
+
 static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
        .get_parent = clk_sdmmc_mux_get_parent,
        .set_parent = clk_sdmmc_mux_set_parent,
        .is_enabled = clk_sdmmc_mux_is_enabled,
        .enable = clk_sdmmc_mux_enable,
        .disable = clk_sdmmc_mux_disable,
+       .restore_context = clk_sdmmc_mux_restore_context,
 };
 
 struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,