aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/mvebu
diff options
context:
space:
mode:
authorMiquel Raynal <miquel.raynal@bootlin.com>2018-07-13 09:44:46 -0400
committerStephen Boyd <sboyd@kernel.org>2018-08-31 13:47:48 -0400
commit5beb1e60dba973e0b9cfb54d9735d5d4385b9d90 (patch)
tree1ebebd94ce6910f5c481613bb6ef3a43335ea060 /drivers/clk/mvebu
parentd9d95e78cff80c3fe43e757ba90644cd766302ac (diff)
clk: mvebu: armada-37xx-periph: add suspend/resume support
Add suspend/resume hooks in Armada 37xx peripheral clocks driver to handle S2RAM operations. One can think that these hooks are useless by comparing the register values before and after a suspend/resume cycle: they will look the same anyway. This is because of some scripts executed by the Cortex-M3 core during ATF operations to init both the clocks and the DDR. These values could be modified by the BL33 stage or by Linux itself and should be preserved. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/mvebu')
-rw-r--r--drivers/clk/mvebu/armada-37xx-periph.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 78048c2e3774..1f1cff428d78 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -57,6 +57,14 @@ struct clk_periph_driver_data {
57 struct clk_hw_onecell_data *hw_data; 57 struct clk_hw_onecell_data *hw_data;
58 spinlock_t lock; 58 spinlock_t lock;
59 void __iomem *reg; 59 void __iomem *reg;
60
61 /* Storage registers for suspend/resume operations */
62 u32 tbg_sel;
63 u32 div_sel0;
64 u32 div_sel1;
65 u32 div_sel2;
66 u32 clk_sel;
67 u32 clk_dis;
60}; 68};
61 69
62struct clk_double_div { 70struct clk_double_div {
@@ -673,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data,
673 return PTR_ERR_OR_ZERO(*hw); 681 return PTR_ERR_OR_ZERO(*hw);
674} 682}
675 683
684static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev)
685{
686 struct clk_periph_driver_data *data = dev_get_drvdata(dev);
687
688 data->tbg_sel = readl(data->reg + TBG_SEL);
689 data->div_sel0 = readl(data->reg + DIV_SEL0);
690 data->div_sel1 = readl(data->reg + DIV_SEL1);
691 data->div_sel2 = readl(data->reg + DIV_SEL2);
692 data->clk_sel = readl(data->reg + CLK_SEL);
693 data->clk_dis = readl(data->reg + CLK_DIS);
694
695 return 0;
696}
697
698static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev)
699{
700 struct clk_periph_driver_data *data = dev_get_drvdata(dev);
701
702 /* Follow the same order than what the Cortex-M3 does (ATF code) */
703 writel(data->clk_dis, data->reg + CLK_DIS);
704 writel(data->div_sel0, data->reg + DIV_SEL0);
705 writel(data->div_sel1, data->reg + DIV_SEL1);
706 writel(data->div_sel2, data->reg + DIV_SEL2);
707 writel(data->tbg_sel, data->reg + TBG_SEL);
708 writel(data->clk_sel, data->reg + CLK_SEL);
709
710 return 0;
711}
712
713static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = {
714 SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend,
715 armada_3700_periph_clock_resume)
716};
717
676static int armada_3700_periph_clock_probe(struct platform_device *pdev) 718static int armada_3700_periph_clock_probe(struct platform_device *pdev)
677{ 719{
678 struct clk_periph_driver_data *driver_data; 720 struct clk_periph_driver_data *driver_data;
@@ -748,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = {
748 .driver = { 790 .driver = {
749 .name = "marvell-armada-3700-periph-clock", 791 .name = "marvell-armada-3700-periph-clock",
750 .of_match_table = armada_3700_periph_clock_of_match, 792 .of_match_table = armada_3700_periph_clock_of_match,
793 .pm = &armada_3700_periph_clock_pm_ops,
751 }, 794 },
752}; 795};
753 796