From 3ccefbd2291d6ee59f242c05266e241c5e33667e Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Fri, 14 Feb 2014 08:16:00 +0900 Subject: clk: samsung: Provide common helpers for register save/restore As suspend/resume handlers are being moved to SoC specific code, due to differencies in suspend/resume handling of particular SoCs, to minimize code duplication this patch provides common register save/restore helpers that save/restore given list of registers of clock controller. Signed-off-by: Tomasz Figa Acked-by: Kyungmin Park Acked-by: Heiko Stuebner Reviewed-by: Thomas Abraham Reviewed-by: Sylwester Nawrocki Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/clk/samsung/clk.h') diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 31b4174e7a5b..ec8d46ba8178 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -340,4 +340,14 @@ extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, extern unsigned long _get_rate(const char *clk_name); +extern void samsung_clk_save(void __iomem *base, + struct samsung_clk_reg_dump *rd, + unsigned int num_regs); +extern void samsung_clk_restore(void __iomem *base, + const struct samsung_clk_reg_dump *rd, + unsigned int num_regs); +extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( + unsigned long *rdump, + unsigned long nr_rdump); + #endif /* __SAMSUNG_CLK_H */ -- cgit v1.2.3 From c3b6c1d7015a5a19d87725fe22b58aeea9a88f3c Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Fri, 14 Feb 2014 08:16:00 +0900 Subject: clk: samsung: exynos5250: Move suspend/resume handling to SoC driver 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 Acked-by: Kyungmin Park Reviewed-by: Thomas Abraham Reviewed-by: Sylwester Nawrocki Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5250.c | 49 ++++++++++++++++++++++++++++++++---- drivers/clk/samsung/clk.c | 5 ++-- drivers/clk/samsung/clk.h | 4 +-- 3 files changed, 49 insertions(+), 9 deletions(-) (limited to 'drivers/clk/samsung/clk.h') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index ff4beebe1f0b..b3cccf044607 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "clk.h" @@ -85,6 +86,11 @@ enum exynos5250_plls { nr_plls /* number of PLLs */ }; +static void __iomem *reg_base; + +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos5250_save; + /* * list of controller registers to be saved and restored during a * suspend/resume cycle. @@ -137,6 +143,41 @@ static unsigned long exynos5250_clk_regs[] __initdata = { GATE_IP_ACP, }; +static int exynos5250_clk_suspend(void) +{ + samsung_clk_save(reg_base, exynos5250_save, + ARRAY_SIZE(exynos5250_clk_regs)); + + return 0; +} + +static void exynos5250_clk_resume(void) +{ + samsung_clk_restore(reg_base, exynos5250_save, + ARRAY_SIZE(exynos5250_clk_regs)); +} + +static struct syscore_ops exynos5250_clk_syscore_ops = { + .suspend = exynos5250_clk_suspend, + .resume = exynos5250_clk_resume, +}; + +static void exynos5250_clk_sleep_init(void) +{ + exynos5250_save = samsung_clk_alloc_reg_dump(exynos5250_clk_regs, + ARRAY_SIZE(exynos5250_clk_regs)); + if (!exynos5250_save) { + pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", + __func__); + return; + } + + register_syscore_ops(&exynos5250_clk_syscore_ops); +} +#else +static void exynos5250_clk_sleep_init(void) {} +#endif + /* list of all parent clock list */ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; @@ -645,8 +686,6 @@ static struct of_device_id ext_clk_match[] __initdata = { /* register exynox5250 clocks */ static void __init exynos5250_clk_init(struct device_node *np) { - void __iomem *reg_base; - if (np) { reg_base = of_iomap(np, 0); if (!reg_base) @@ -655,9 +694,7 @@ static void __init exynos5250_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, CLK_NR_CLKS, - exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs), - NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), ext_clk_match); @@ -685,6 +722,8 @@ static void __init exynos5250_clk_init(struct device_node *np) samsung_clk_register_gate(exynos5250_gate_clks, ARRAY_SIZE(exynos5250_gate_clks)); + exynos5250_clk_sleep_init(); + pr_info("Exynos5250: clock setup completed, armclk=%ld\n", _get_rate("div_arm2")); } diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index c0a716b94a66..ec761e344fd0 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -38,8 +38,9 @@ void samsung_clk_restore(void __iomem *base, writel(rd->value, base + rd->offset); } -struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(unsigned long *rdump, - unsigned long nr_rdump) +struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( + const unsigned long *rdump, + unsigned long nr_rdump) { struct samsung_clk_reg_dump *rd; unsigned int i; diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index ec8d46ba8178..93cb8a0deb7b 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -347,7 +347,7 @@ extern void samsung_clk_restore(void __iomem *base, const struct samsung_clk_reg_dump *rd, unsigned int num_regs); extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( - unsigned long *rdump, - unsigned long nr_rdump); + const unsigned long *rdump, + unsigned long nr_rdump); #endif /* __SAMSUNG_CLK_H */ -- cgit v1.2.3 From 3efb25116774f69f0649fd6774fd46306cabdb56 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Fri, 14 Feb 2014 08:16:01 +0900 Subject: clk: samsung: Drop old suspend/resume code Since all SoC drivers have been moved to local suspend/resume handling, the old code can be safely dropped. Signed-off-by: Tomasz Figa Acked-by: Kyungmin Park Acked-by: Heiko Stuebner Reviewed-by: Thomas Abraham Reviewed-by: Sylwester Nawrocki Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 2 +- drivers/clk/samsung/clk-exynos5250.c | 2 +- drivers/clk/samsung/clk-exynos5420.c | 2 +- drivers/clk/samsung/clk-exynos5440.c | 2 +- drivers/clk/samsung/clk-s3c64xx.c | 2 +- drivers/clk/samsung/clk.c | 54 +----------------------------------- drivers/clk/samsung/clk.h | 4 +-- 7 files changed, 7 insertions(+), 61 deletions(-) (limited to 'drivers/clk/samsung/clk.h') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 325f29248af5..b620a8375b7f 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1122,7 +1122,7 @@ static void __init exynos4_clk_init(struct device_node *np, if (!reg_base) panic("%s: failed to map registers\n", __func__); - samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS); samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, ARRAY_SIZE(exynos4_fixed_rate_ext_clks), diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index b3cccf044607..e7ee4420da81 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -694,7 +694,7 @@ static void __init exynos5250_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS); samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 8ce078049fb4..60b26819bed5 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -786,7 +786,7 @@ static void __init exynos5420_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS); samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index cbc15b56891d..2bfad5a993d0 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -101,7 +101,7 @@ static void __init exynos5440_clk_init(struct device_node *np) return; } - samsung_clk_init(np, reg_base, CLK_NR_CLKS, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, CLK_NR_CLKS); samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index d3fbfa566974..8bda658137a8 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -465,7 +465,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS, NULL, 0, NULL, 0); + samsung_clk_init(np, reg_base, NR_CLKS); /* Register external clocks. */ if (!np) diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index ec761e344fd0..91bec3ebdc8f 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -21,7 +21,6 @@ static void __iomem *reg_base; static struct clk_onecell_data clk_data; #endif -#ifdef CONFIG_PM_SLEEP void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -55,63 +54,12 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( return rd; } -static struct samsung_clk_reg_dump *reg_dump; -static unsigned long nr_reg_dump; - -static int samsung_clk_suspend(void) -{ - struct samsung_clk_reg_dump *rd = reg_dump; - unsigned long i; - - for (i = 0; i < nr_reg_dump; i++, rd++) - rd->value = __raw_readl(reg_base + rd->offset); - - return 0; -} - -static void samsung_clk_resume(void) -{ - struct samsung_clk_reg_dump *rd = reg_dump; - unsigned long i; - - for (i = 0; i < nr_reg_dump; i++, rd++) - __raw_writel(rd->value, reg_base + rd->offset); -} - -static struct syscore_ops samsung_clk_syscore_ops = { - .suspend = samsung_clk_suspend, - .resume = samsung_clk_resume, -}; -#endif /* CONFIG_PM_SLEEP */ - /* setup the essentials required to support clock lookup using ccf */ void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks, unsigned long *rdump, - unsigned long nr_rdump, unsigned long *soc_rdump, - unsigned long nr_soc_rdump) + unsigned long nr_clks) { reg_base = base; -#ifdef CONFIG_PM_SLEEP - if (rdump && nr_rdump) { - unsigned int idx; - reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump) - * (nr_rdump + nr_soc_rdump), GFP_KERNEL); - if (!reg_dump) { - pr_err("%s: memory alloc for register dump failed\n", - __func__); - return; - } - - for (idx = 0; idx < nr_rdump; idx++) - reg_dump[idx].offset = rdump[idx]; - for (idx = 0; idx < nr_soc_rdump; idx++) - reg_dump[nr_rdump + idx].offset = soc_rdump[idx]; - nr_reg_dump = nr_rdump + nr_soc_rdump; - register_syscore_ops(&samsung_clk_syscore_ops); - } -#endif - clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); if (!clk_table) panic("could not allocate clock lookup table\n"); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 93cb8a0deb7b..c7141ba826e0 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -313,9 +313,7 @@ struct samsung_pll_clock { _lock, _con, _rtable, _alias) extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks, unsigned long *rdump, - unsigned long nr_rdump, unsigned long *soc_rdump, - unsigned long nr_soc_rdump); + unsigned long nr_clks); extern void __init samsung_clk_of_register_fixed_ext( struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, -- cgit v1.2.3