diff mbox

[3/9] clk: samsung: exynos4: Move suspend/resume handling to SoC driver

Message ID 1381921698-5060-4-git-send-email-t.figa@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Tomasz Figa Oct. 16, 2013, 11:08 a.m. UTC
Since there are multiple differences in how suspend/resume of particular
Exynos SoCs must be handled, SoC driver is better place for
suspend/resume handlers and so this patch moves them.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c | 90 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 80 insertions(+), 10 deletions(-)

Comments

Yadwinder Singh Brar Oct. 17, 2013, 1:42 p.m. UTC | #1
Hi Tomasz,

[ ... ]
>  /*
>   * list of controller registers to be saved and restored during a
>   * suspend/resume cycle.
> @@ -288,6 +299,70 @@ static unsigned long exynos4_clk_regs[] __initdata = {
>         GATE_IP_CPU,
>  };
>
> +static int exynos4_clk_suspend(void)
> +{
> +       samsung_clk_save(reg_base, exynos4_save_common,
> +                               ARRAY_SIZE(exynos4_clk_regs));

a doubt here, Is sizeof(exynos4_clk_regs) works with
exynos4_clk_regs[] as __initdata ?

> +
> +       if (exynos4_soc == EXYNOS4210)
> +               samsung_clk_save(reg_base, exynos4_save_soc,
> +                                       ARRAY_SIZE(exynos4210_clk_save));

[ ... ]
> +static void exynos4_clk_sleep_init(void)

I think, this fuction can be placed in __init section.

Same in other patches as well.

Regards,
Yadwinder
Tomasz Figa Oct. 17, 2013, 2:16 p.m. UTC | #2
On Thursday 17 of October 2013 19:12:08 Yadwinder Singh Brar wrote:
> Hi Tomasz,
> 
> [ ... ]
> >  /*
> >   * list of controller registers to be saved and restored during a
> >   * suspend/resume cycle.
> > @@ -288,6 +299,70 @@ static unsigned long exynos4_clk_regs[] __initdata = {
> >         GATE_IP_CPU,
> >  };
> >
> > +static int exynos4_clk_suspend(void)
> > +{
> > +       samsung_clk_save(reg_base, exynos4_save_common,
> > +                               ARRAY_SIZE(exynos4_clk_regs));
> 
> a doubt here, Is sizeof(exynos4_clk_regs) works with
> exynos4_clk_regs[] as __initdata ?

Hmm, this is a compile time constant, so I don't see why it couldn't work.

> > +
> > +       if (exynos4_soc == EXYNOS4210)
> > +               samsung_clk_save(reg_base, exynos4_save_soc,
> > +                                       ARRAY_SIZE(exynos4210_clk_save));
> 
> [ ... ]
> > +static void exynos4_clk_sleep_init(void)
> 
> I think, this fuction can be placed in __init section.

That's right. Thanks for pointing this out.

Best regards,
Tomasz
Yadwinder Singh Brar Oct. 17, 2013, 2:22 p.m. UTC | #3
On Thu, Oct 17, 2013 at 7:46 PM, Tomasz Figa <t.figa@samsung.com> wrote:
> On Thursday 17 of October 2013 19:12:08 Yadwinder Singh Brar wrote:
>> Hi Tomasz,
>>
>> [ ... ]
>> >  /*
>> >   * list of controller registers to be saved and restored during a
>> >   * suspend/resume cycle.
>> > @@ -288,6 +299,70 @@ static unsigned long exynos4_clk_regs[] __initdata = {
>> >         GATE_IP_CPU,
>> >  };
>> >
>> > +static int exynos4_clk_suspend(void)
>> > +{
>> > +       samsung_clk_save(reg_base, exynos4_save_common,
>> > +                               ARRAY_SIZE(exynos4_clk_regs));
>>
>> a doubt here, Is sizeof(exynos4_clk_regs) works with
>> exynos4_clk_regs[] as __initdata ?
>
> Hmm, this is a compile time constant, so I don't see why it couldn't work.
>

why this doubt came in mind is sizeof() is a operator.. like we can
use sizeof(x++).
diff mbox

Patch

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index a29bb87..1de7346 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -15,6 +15,7 @@ 
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/syscore_ops.h>
 
 #include "clk.h"
 
@@ -191,6 +192,16 @@  enum exynos4_clks {
 	nr_clks,
 };
 
+static void __iomem *reg_base;
+static enum exynos4_soc exynos4_soc;
+
+/*
+ * Support for CMU save/restore across system suspends
+ */
+#ifdef CONFIG_PM_SLEEP
+static struct samsung_clk_reg_dump *exynos4_save_common;
+static struct samsung_clk_reg_dump *exynos4_save_soc;
+
 /*
  * list of controller registers to be saved and restored during a
  * suspend/resume cycle.
@@ -288,6 +299,70 @@  static unsigned long exynos4_clk_regs[] __initdata = {
 	GATE_IP_CPU,
 };
 
+static int exynos4_clk_suspend(void)
+{
+	samsung_clk_save(reg_base, exynos4_save_common,
+				ARRAY_SIZE(exynos4_clk_regs));
+
+	if (exynos4_soc == EXYNOS4210)
+		samsung_clk_save(reg_base, exynos4_save_soc,
+					ARRAY_SIZE(exynos4210_clk_save));
+	else
+		samsung_clk_save(reg_base, exynos4_save_soc,
+					ARRAY_SIZE(exynos4x12_clk_save));
+
+	return 0;
+}
+
+static void exynos4_clk_resume(void)
+{
+	samsung_clk_restore(reg_base, exynos4_save_common,
+				ARRAY_SIZE(exynos4_clk_regs));
+
+	if (exynos4_soc == EXYNOS4210)
+		samsung_clk_restore(reg_base, exynos4_save_soc,
+					ARRAY_SIZE(exynos4210_clk_save));
+	else
+		samsung_clk_restore(reg_base, exynos4_save_soc,
+					ARRAY_SIZE(exynos4x12_clk_save));
+}
+
+static struct syscore_ops exynos4_clk_syscore_ops = {
+	.suspend = exynos4_clk_suspend,
+	.resume = exynos4_clk_resume,
+};
+
+static void exynos4_clk_sleep_init(void)
+{
+	exynos4_save_common = samsung_clk_alloc_reg_dump(exynos4_clk_regs,
+					ARRAY_SIZE(exynos4_clk_regs));
+	if (!exynos4_save_common)
+		goto err_warn;
+
+	if (exynos4_soc == EXYNOS4210)
+		exynos4_save_soc = samsung_clk_alloc_reg_dump(
+					exynos4210_clk_save,
+					ARRAY_SIZE(exynos4210_clk_save));
+	else
+		exynos4_save_soc = samsung_clk_alloc_reg_dump(
+					exynos4x12_clk_save,
+					ARRAY_SIZE(exynos4x12_clk_save));
+	if (!exynos4_save_soc)
+		goto err_common;
+
+	register_syscore_ops(&exynos4_clk_syscore_ops);
+	return;
+
+err_common:
+	kfree(exynos4_save_common);
+err_warn:
+	pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
+		__func__);
+}
+#else
+static void exynos4_clk_sleep_init(void) {}
+#endif
+
 /* list of all parent clock list */
 PNAME(mout_apll_p)	= { "fin_pll", "fout_apll", };
 PNAME(mout_mpll_p)	= { "fin_pll", "fout_mpll", };
@@ -1091,22 +1166,15 @@  static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
 
 /* register exynos4 clocks */
 static void __init exynos4_clk_init(struct device_node *np,
-				    enum exynos4_soc exynos4_soc)
+				    enum exynos4_soc soc)
 {
-	void __iomem *reg_base;
+	exynos4_soc = soc;
 
 	reg_base = of_iomap(np, 0);
 	if (!reg_base)
 		panic("%s: failed to map registers\n", __func__);
 
-	if (exynos4_soc == EXYNOS4210)
-		samsung_clk_init(np, reg_base, nr_clks,
-			exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
-			exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save));
-	else
-		samsung_clk_init(np, reg_base, nr_clks,
-			exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
-			exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save));
+	samsung_clk_init(np, reg_base, nr_clks, NULL, 0, NULL, 0);
 
 	samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
@@ -1179,6 +1247,8 @@  static void __init exynos4_clk_init(struct device_node *np,
 	samsung_clk_register_alias(exynos4_aliases,
 			ARRAY_SIZE(exynos4_aliases));
 
+	exynos4_clk_sleep_init();
+
 	pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
 		"\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
 		exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",