From d9d95e78cff80c3fe43e757ba90644cd766302ac Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 13 Jul 2018 15:44:45 +0200 Subject: clk: mvebu: armada-37xx-periph: save the IP base address in the driver data Prepare the introduction of suspend/resume hooks by having an easy way to access all the registers in one go just from a device: add the IP base address in the driver data. Signed-off-by: Miquel Raynal Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/clk/mvebu') diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 499f5962c8b0..78048c2e3774 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -56,6 +56,7 @@ struct clk_periph_driver_data { struct clk_hw_onecell_data *hw_data; spinlock_t lock; + void __iomem *reg; }; struct clk_double_div { @@ -680,7 +681,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int num_periph = 0, i, ret; struct resource *res; - void __iomem *reg; data = of_device_get_match_data(dev); if (!data) @@ -689,11 +689,6 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) while (data[num_periph].name) num_periph++; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - reg = devm_ioremap_resource(dev, res); - if (IS_ERR(reg)) - return PTR_ERR(reg); - driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL); if (!driver_data) return -ENOMEM; @@ -706,12 +701,16 @@ static int armada_3700_periph_clock_probe(struct platform_device *pdev) return -ENOMEM; driver_data->hw_data->num = num_periph; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + driver_data->reg = devm_ioremap_resource(dev, res); + if (IS_ERR(driver_data->reg)) + return PTR_ERR(driver_data->reg); + spin_lock_init(&driver_data->lock); for (i = 0; i < num_periph; i++) { struct clk_hw **hw = &driver_data->hw_data->hws[i]; - - if (armada_3700_add_composite_clk(&data[i], reg, + if (armada_3700_add_composite_clk(&data[i], driver_data->reg, &driver_data->lock, dev, hw)) dev_err(dev, "Can't register periph clock %s\n", data[i].name); -- cgit v1.2.3 From 5beb1e60dba973e0b9cfb54d9735d5d4385b9d90 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Fri, 13 Jul 2018 15:44:46 +0200 Subject: 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 Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/armada-37xx-periph.c | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/clk/mvebu') 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 { struct clk_hw_onecell_data *hw_data; spinlock_t lock; void __iomem *reg; + + /* Storage registers for suspend/resume operations */ + u32 tbg_sel; + u32 div_sel0; + u32 div_sel1; + u32 div_sel2; + u32 clk_sel; + u32 clk_dis; }; struct clk_double_div { @@ -673,6 +681,40 @@ static int armada_3700_add_composite_clk(const struct clk_periph_data *data, return PTR_ERR_OR_ZERO(*hw); } +static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + data->tbg_sel = readl(data->reg + TBG_SEL); + data->div_sel0 = readl(data->reg + DIV_SEL0); + data->div_sel1 = readl(data->reg + DIV_SEL1); + data->div_sel2 = readl(data->reg + DIV_SEL2); + data->clk_sel = readl(data->reg + CLK_SEL); + data->clk_dis = readl(data->reg + CLK_DIS); + + return 0; +} + +static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev) +{ + struct clk_periph_driver_data *data = dev_get_drvdata(dev); + + /* Follow the same order than what the Cortex-M3 does (ATF code) */ + writel(data->clk_dis, data->reg + CLK_DIS); + writel(data->div_sel0, data->reg + DIV_SEL0); + writel(data->div_sel1, data->reg + DIV_SEL1); + writel(data->div_sel2, data->reg + DIV_SEL2); + writel(data->tbg_sel, data->reg + TBG_SEL); + writel(data->clk_sel, data->reg + CLK_SEL); + + return 0; +} + +static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend, + armada_3700_periph_clock_resume) +}; + static int armada_3700_periph_clock_probe(struct platform_device *pdev) { struct clk_periph_driver_data *driver_data; @@ -748,6 +790,7 @@ static struct platform_driver armada_3700_periph_clock_driver = { .driver = { .name = "marvell-armada-3700-periph-clock", .of_match_table = armada_3700_periph_clock_of_match, + .pm = &armada_3700_periph_clock_pm_ops, }, }; -- cgit v1.2.3 From 6ffeddd6bca4cb838623d0bf4134c0eb06ad7485 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 12 Sep 2018 17:35:49 +0200 Subject: clk: mvebu: ap806: Remove superfluous of_clk_add_provider While applying the commit a8309cedcdce ("clk: apn806: Add eMMC clock to system controller driver"), of_clk_add_provider was added wheres it was already present in the probe function. This extraneous call is harmless but not useful so remove it. Signed-off-by: Gregory CLEMENT Signed-off-by: Stephen Boyd --- drivers/clk/mvebu/ap806-system-controller.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/clk/mvebu') diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c index fa2fbd2cef4a..cfc6b82d2448 100644 --- a/drivers/clk/mvebu/ap806-system-controller.c +++ b/drivers/clk/mvebu/ap806-system-controller.c @@ -155,7 +155,6 @@ static int ap806_syscon_common_probe(struct platform_device *pdev, goto fail4; } - of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); ret = of_clk_add_provider(np, of_clk_src_onecell_get, &ap806_clk_data); if (ret) goto fail_clk_add; -- cgit v1.2.3