summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@kernel.org>2018-10-15 10:01:41 -0700
committerStephen Boyd <sboyd@kernel.org>2018-10-15 10:01:41 -0700
commit6df9543da2b2a2f98f8a6ebbf9530bd3546b7268 (patch)
treee5552001d2e2a809dc7c20712ab59aa181f89c5f /drivers/clk
parent5b394b2ddf0347bef56e50c69a58773c94343ff3 (diff)
parent9dbcfe1ace4e9c57b819df1054eaeceb9bfd34f5 (diff)
Merge tag 'clk-v4.20-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into clk-samsung
Pull Samsung clk driver updates from Sylwester Nawrocki: - consolidation of system suspend related code in Exynos, S5P, S3C SoC clk drivers, - fixes of system suspend support on Exynos542x (Odroid boards) and Exynos5433 SoC, - removal of obsoleted Exynos4212 ISP clock definitions, - correction of Exynos CPU clock implementation, - addition of SPDX license identifiers. * tag 'clk-v4.20-samsung' of git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk: dt-bindings: clock: samsung: Add SPDX license identifiers clk: samsung: Use clk_hw API for calling clk framework from clk notifiers clk: samsung: exynos5420: Enable PERIS clocks for suspend clk: samsung: exynos5420: Define CLK_SECKEY gate clock only or Exynos5420 clk: samsung: exynos5433: Keep sclk_uart clocks enabled in suspend clk: samsung: Remove obsolete code for Exynos4412 ISP clocks clk: samsung: exynos5433: Add suspend state for TOP, CPIF & PERIC CMUs clk: samsung: Use NOIRQ stage for Exynos5433 clocks suspend/resume clk: samsung: exynos5420: Use generic helper for handling suspend/resume clk: samsung: exynos4: Use generic helper for handling suspend/resume clk: samsung: Add support for setting registers state before suspend clk: samsung: exynos5250: Use generic helper for handling suspend/resume clk: samsung: s5pv210: Use generic helper for handling suspend/resume clk: samsung: s3c64xx: Use generic helper for handling suspend/resume clk: samsung: s3c2443: Use generic helper for handling suspend/resume clk: samsung: s3c2412: Use generic helper for handling suspend/resume clk: samsung: s3c2410: Use generic helper for handling suspend/resume clk: samsung: Remove excessive include
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/samsung/clk-cpu.c6
-rw-r--r--drivers/clk/samsung/clk-cpu.h2
-rw-r--r--drivers/clk/samsung/clk-exynos-audss.c1
-rw-r--r--drivers/clk/samsung/clk-exynos3250.c1
-rw-r--r--drivers/clk/samsung/clk-exynos4.c226
-rw-r--r--drivers/clk/samsung/clk-exynos5250.c42
-rw-r--r--drivers/clk/samsung/clk-exynos5420.c76
-rw-r--r--drivers/clk/samsung/clk-exynos5433.c33
-rw-r--r--drivers/clk/samsung/clk-s3c2410.c43
-rw-r--r--drivers/clk/samsung/clk-s3c2412.c43
-rw-r--r--drivers/clk/samsung/clk-s3c2443.c43
-rw-r--r--drivers/clk/samsung/clk-s3c64xx.c66
-rw-r--r--drivers/clk/samsung/clk-s5pv210.c41
-rw-r--r--drivers/clk/samsung/clk.c23
-rw-r--r--drivers/clk/samsung/clk.h18
15 files changed, 103 insertions, 561 deletions
diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c
index d2c99d8916b8..a5fddebbe530 100644
--- a/drivers/clk/samsung/clk-cpu.c
+++ b/drivers/clk/samsung/clk-cpu.c
@@ -152,7 +152,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
struct exynos_cpuclk *cpuclk, void __iomem *base)
{
const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
- unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+ unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
unsigned long div0, div1 = 0, mux_reg;
unsigned long flags;
@@ -280,7 +280,7 @@ static int exynos5433_cpuclk_pre_rate_change(struct clk_notifier_data *ndata,
struct exynos_cpuclk *cpuclk, void __iomem *base)
{
const struct exynos_cpuclk_cfg_data *cfg_data = cpuclk->cfg;
- unsigned long alt_prate = clk_get_rate(cpuclk->alt_parent);
+ unsigned long alt_prate = clk_hw_get_rate(cpuclk->alt_parent);
unsigned long alt_div = 0, alt_div_mask = DIV_MASK;
unsigned long div0, div1 = 0, mux_reg;
unsigned long flags;
@@ -432,7 +432,7 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
else
cpuclk->clk_nb.notifier_call = exynos_cpuclk_notifier_cb;
- cpuclk->alt_parent = __clk_lookup(alt_parent);
+ cpuclk->alt_parent = __clk_get_hw(__clk_lookup(alt_parent));
if (!cpuclk->alt_parent) {
pr_err("%s: could not lookup alternate parent %s\n",
__func__, alt_parent);
diff --git a/drivers/clk/samsung/clk-cpu.h b/drivers/clk/samsung/clk-cpu.h
index d4b6b517fe1b..bd38c6aa3897 100644
--- a/drivers/clk/samsung/clk-cpu.h
+++ b/drivers/clk/samsung/clk-cpu.h
@@ -49,7 +49,7 @@ struct exynos_cpuclk_cfg_data {
*/
struct exynos_cpuclk {
struct clk_hw hw;
- struct clk *alt_parent;
+ struct clk_hw *alt_parent;
void __iomem *ctrl_base;
spinlock_t *lock;
const struct exynos_cpuclk_cfg_data *cfg;
diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
index f659c5cbf1d5..8f8a0f9fc842 100644
--- a/drivers/clk/samsung/clk-exynos-audss.c
+++ b/drivers/clk/samsung/clk-exynos-audss.c
@@ -15,7 +15,6 @@
#include <linux/clk-provider.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
-#include <linux/syscore_ops.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c
index 27c9d23657b3..0e9a41a4cac8 100644
--- a/drivers/clk/samsung/clk-exynos3250.c
+++ b/drivers/clk/samsung/clk-exynos3250.c
@@ -12,7 +12,6 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
#include <dt-bindings/clock/exynos3250.h>
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 0421960eb963..59d4d46667ce 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -16,7 +16,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include "clk.h"
#include "clk-cpu.h"
@@ -123,10 +122,6 @@
#define CLKOUT_CMU_CPU 0x14a00
#define PWR_CTRL1 0x15020
#define E4X12_PWR_CTRL2 0x15024
-#define E4X12_DIV_ISP0 0x18300
-#define E4X12_DIV_ISP1 0x18304
-#define E4X12_GATE_ISP0 0x18800
-#define E4X12_GATE_ISP1 0x18804
/* Below definitions are used for PWR_CTRL settings */
#define PWR_CTRL1_CORE2_DOWN_RATIO(x) (((x) & 0x7) << 28)
@@ -158,14 +153,6 @@ 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;
-static struct samsung_clk_reg_dump *exynos4_save_pll;
-
-/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
*/
@@ -192,7 +179,7 @@ static const unsigned long exynos4x12_clk_save[] __initconst = {
E4X12_PWR_CTRL2,
};
-static const unsigned long exynos4_clk_pll_regs[] __initconst = {
+static const unsigned long exynos4_clk_regs[] __initconst = {
EPLL_LOCK,
VPLL_LOCK,
EPLL_CON0,
@@ -201,9 +188,6 @@ static const unsigned long exynos4_clk_pll_regs[] __initconst = {
VPLL_CON0,
VPLL_CON1,
VPLL_CON2,
-};
-
-static const unsigned long exynos4_clk_regs[] __initconst = {
SRC_LEFTBUS,
DIV_LEFTBUS,
GATE_IP_LEFTBUS,
@@ -276,6 +260,8 @@ static const unsigned long exynos4_clk_regs[] __initconst = {
};
static const struct samsung_clk_reg_dump src_mask_suspend[] = {
+ { .offset = VPLL_CON0, .value = 0x80600302, },
+ { .offset = EPLL_CON0, .value = 0x806F0302, },
{ .offset = SRC_MASK_TOP, .value = 0x00000001, },
{ .offset = SRC_MASK_CAM, .value = 0x11111111, },
{ .offset = SRC_MASK_TV, .value = 0x00000111, },
@@ -291,123 +277,6 @@ static const struct samsung_clk_reg_dump src_mask_suspend_e4210[] = {
{ .offset = E4210_SRC_MASK_LCD1, .value = 0x00001111, },
};
-#define PLL_ENABLED (1 << 31)
-#define PLL_LOCKED (1 << 29)
-
-static void exynos4_clk_enable_pll(u32 reg)
-{
- u32 pll_con = readl(reg_base + reg);
- pll_con |= PLL_ENABLED;
- writel(pll_con, reg_base + reg);
-
- while (!(pll_con & PLL_LOCKED)) {
- cpu_relax();
- pll_con = readl(reg_base + reg);
- }
-}
-
-static void exynos4_clk_wait_for_pll(u32 reg)
-{
- u32 pll_con;
-
- pll_con = readl(reg_base + reg);
- if (!(pll_con & PLL_ENABLED))
- return;
-
- while (!(pll_con & PLL_LOCKED)) {
- cpu_relax();
- pll_con = readl(reg_base + reg);
- }
-}
-
-static int exynos4_clk_suspend(void)
-{
- samsung_clk_save(reg_base, exynos4_save_common,
- ARRAY_SIZE(exynos4_clk_regs));
- samsung_clk_save(reg_base, exynos4_save_pll,
- ARRAY_SIZE(exynos4_clk_pll_regs));
-
- exynos4_clk_enable_pll(EPLL_CON0);
- exynos4_clk_enable_pll(VPLL_CON0);
-
- if (exynos4_soc == EXYNOS4210) {
- samsung_clk_save(reg_base, exynos4_save_soc,
- ARRAY_SIZE(exynos4210_clk_save));
- samsung_clk_restore(reg_base, src_mask_suspend_e4210,
- ARRAY_SIZE(src_mask_suspend_e4210));
- } else {
- samsung_clk_save(reg_base, exynos4_save_soc,
- ARRAY_SIZE(exynos4x12_clk_save));
- }
-
- samsung_clk_restore(reg_base, src_mask_suspend,
- ARRAY_SIZE(src_mask_suspend));
-
- return 0;
-}
-
-static void exynos4_clk_resume(void)
-{
- samsung_clk_restore(reg_base, exynos4_save_pll,
- ARRAY_SIZE(exynos4_clk_pll_regs));
-
- exynos4_clk_wait_for_pll(EPLL_CON0);
- exynos4_clk_wait_for_pll(VPLL_CON0);
-
- 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 __init 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;
-
- exynos4_save_pll = samsung_clk_alloc_reg_dump(exynos4_clk_pll_regs,
- ARRAY_SIZE(exynos4_clk_pll_regs));
- if (!exynos4_save_pll)
- goto err_soc;
-
- register_syscore_ops(&exynos4_clk_syscore_ops);
- return;
-
-err_soc:
- kfree(exynos4_save_soc);
-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 __init 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", };
@@ -841,18 +710,6 @@ static const struct samsung_div_clock exynos4x12_div_clks[] __initconst = {
DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};
-static struct samsung_div_clock exynos4x12_isp_div_clks[] = {
- DIV_F(CLK_DIV_ISP0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3,
- CLK_GET_RATE_NOCACHE, 0),
- DIV_F(CLK_DIV_ISP1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3,
- CLK_GET_RATE_NOCACHE, 0),
- DIV(0, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
- DIV_F(CLK_DIV_MCUISP0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1,
- 4, 3, CLK_GET_RATE_NOCACHE, 0),
- DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
- 8, 3, CLK_GET_RATE_NOCACHE, 0),
-};
-
/* list of gate clocks supported in all exynos4 soc's */
static const struct samsung_gate_clock exynos4_gate_clks[] __initconst = {
GATE(CLK_PPMULEFT, "ppmuleft", "aclk200", GATE_IP_LEFTBUS, 1, 0, 0),
@@ -1150,61 +1007,6 @@ static const struct samsung_gate_clock exynos4x12_gate_clks[] __initconst = {
0),
};
-static struct samsung_gate_clock exynos4x12_isp_gate_clks[] = {
- GATE(CLK_FIMC_ISP, "isp", "aclk200", E4X12_GATE_ISP0, 0,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_DRC, "drc", "aclk200", E4X12_GATE_ISP0, 1,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_FD, "fd", "aclk200", E4X12_GATE_ISP0, 2,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_LITE0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_FIMC_LITE1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MCUISP, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_GICISP, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_ISP, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_DRC, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_FD, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_LITE0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_LITE1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PPMUISPMX, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PPMUISPX, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MPWM_ISP, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_I2C0_ISP, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_I2C1_ISP, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_MTCADC_ISP, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_PWM_ISP, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_WDT_ISP, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_UART_ISP, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_ASYNCAXIM, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SPI0_ISP, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
- GATE(CLK_SPI1_ISP, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
- CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE, 0),
-};
-
/*
* The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
* resides in chipid register space, outside of the clock controller memory
@@ -1504,8 +1306,6 @@ static void __init exynos4_clk_init(struct device_node *np,
e4210_armclk_d, ARRAY_SIZE(e4210_armclk_d),
CLK_CPU_NEEDS_DEBUG_ALT_DIV | CLK_CPU_HAS_DIV1);
} else {
- struct resource res;
-
samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
ARRAY_SIZE(exynos4x12_mux_clks));
samsung_clk_register_div(ctx, exynos4x12_div_clks,
@@ -1516,14 +1316,6 @@ static void __init exynos4_clk_init(struct device_node *np,
exynos4x12_fixed_factor_clks,
ARRAY_SIZE(exynos4x12_fixed_factor_clks));
- of_address_to_resource(np, 0, &res);
- if (resource_size(&res) > 0x18000) {
- samsung_clk_register_div(ctx, exynos4x12_isp_div_clks,
- ARRAY_SIZE(exynos4x12_isp_div_clks));
- samsung_clk_register_gate(ctx, exynos4x12_isp_gate_clks,
- ARRAY_SIZE(exynos4x12_isp_gate_clks));
- }
-
exynos_register_cpu_clock(ctx, CLK_ARM_CLK, "armclk",
mout_core_p4x12[0], mout_core_p4x12[1], 0x14200,
e4412_armclk_d, ARRAY_SIZE(e4412_armclk_d),
@@ -1532,7 +1324,17 @@ static void __init exynos4_clk_init(struct device_node *np,
if (soc == EXYNOS4X12)
exynos4x12_core_down_clock();
- exynos4_clk_sleep_init();
+
+ samsung_clk_extended_sleep_init(reg_base,
+ exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
+ src_mask_suspend, ARRAY_SIZE(src_mask_suspend));
+ if (exynos4_soc == EXYNOS4210)
+ samsung_clk_extended_sleep_init(reg_base,
+ exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save),
+ src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210));
+ else
+ samsung_clk_sleep_init(reg_base, exynos4x12_clk_save,
+ ARRAY_SIZE(exynos4x12_clk_save));
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 347fd80c351b..f14139bcb0c1 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -14,7 +14,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include "clk.h"
#include "clk-cpu.h"
@@ -111,9 +110,6 @@ enum exynos5250_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.
@@ -172,41 +168,6 @@ static const unsigned long exynos5250_clk_regs[] __initconst = {
GATE_IP_ISP1,
};
-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 __init 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 __init 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", };
@@ -882,7 +843,8 @@ static void __init exynos5250_clk_init(struct device_node *np)
PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO);
__raw_writel(tmp, reg_base + PWR_CTRL2);
- exynos5250_clk_sleep_init();
+ samsung_clk_sleep_init(reg_base, exynos5250_clk_regs,
+ ARRAY_SIZE(exynos5250_clk_regs));
exynos5_subcmus_init(ctx, 1, &exynos5250_disp_subcmu);
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 95e1bf69449b..34cce3c5898f 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -15,7 +15,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include "clk.h"
#include "clk-cpu.h"
@@ -156,10 +155,6 @@ enum exynos5x_plls {
static void __iomem *reg_base;
static enum exynos5x_soc exynos5x_soc;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *exynos5x_save;
-static struct samsung_clk_reg_dump *exynos5800_save;
-
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@@ -281,68 +276,9 @@ static const struct samsung_clk_reg_dump exynos5420_set_clksrc[] = {
{ .offset = GATE_BUS_TOP, .value = 0xffffffff, },
{ .offset = GATE_BUS_DISP1, .value = 0xffffffff, },
{ .offset = GATE_IP_PERIC, .value = 0xffffffff, },
+ { .offset = GATE_IP_PERIS, .value = 0xffffffff, },
};
-static int exynos5420_clk_suspend(void)
-{
- samsung_clk_save(reg_base, exynos5x_save,
- ARRAY_SIZE(exynos5x_clk_regs));
-
- if (exynos5x_soc == EXYNOS5800)
- samsung_clk_save(reg_base, exynos5800_save,
- ARRAY_SIZE(exynos5800_clk_regs));
-
- samsung_clk_restore(reg_base, exynos5420_set_clksrc,
- ARRAY_SIZE(exynos5420_set_clksrc));
-
- return 0;
-}
-
-static void exynos5420_clk_resume(void)
-{
- samsung_clk_restore(reg_base, exynos5x_save,
- ARRAY_SIZE(exynos5x_clk_regs));
-
- if (exynos5x_soc == EXYNOS5800)
- samsung_clk_restore(reg_base, exynos5800_save,
- ARRAY_SIZE(exynos5800_clk_regs));
-}
-
-static struct syscore_ops exynos5420_clk_syscore_ops = {
- .suspend = exynos5420_clk_suspend,
- .resume = exynos5420_clk_resume,
-};
-
-static void __init exynos5420_clk_sleep_init(void)
-{
- exynos5x_save = samsung_clk_alloc_reg_dump(exynos5x_clk_regs,
- ARRAY_SIZE(exynos5x_clk_regs));
- if (!exynos5x_save) {
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
- return;
- }
-
- if (exynos5x_soc == EXYNOS5800) {
- exynos5800_save =
- samsung_clk_alloc_reg_dump(exynos5800_clk_regs,
- ARRAY_SIZE(exynos5800_clk_regs));
- if (!exynos5800_save)
- goto err_soc;
- }
-
- register_syscore_ops(&exynos5420_clk_syscore_ops);
- return;
-err_soc:
- kfree(exynos5x_save);
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
- return;
-}
-#else
-static void __init exynos5420_clk_sleep_init(void) {}
-#endif
-
/* list of all parent clocks */
PNAME(mout_mspll_cpu_p) = {"mout_sclk_cpll", "mout_sclk_dpll",
"mout_sclk_mpll", "mout_sclk_spll"};
@@ -633,6 +569,7 @@ static const struct samsung_div_clock exynos5420_div_clks[] __initconst = {
};
static const struct samsung_gate_clock exynos5420_gate_clks[] __initconst = {
+ GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk",
SRC_MASK_TOP7, 20, CLK_SET_RATE_PARENT, 0),
};
@@ -1162,8 +1099,6 @@ static const struct samsung_gate_clock exynos5x_gate_clks[] __initconst = {
GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_IP_PERIS, 21, 0, 0),
GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_IP_PERIS, 22, 0, 0),
- GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0),
-
/* GEN Block */
GATE(CLK_ROTATOR, "rotator", "mout_user_aclk266", GATE_IP_GEN, 1, 0, 0),
GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0),
@@ -1540,7 +1475,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
mout_kfc_p[0], mout_kfc_p[1], 0x28200,
exynos5420_kfcclk_d, ARRAY_SIZE(exynos5420_kfcclk_d), 0);
- exynos5420_clk_sleep_init();
+ samsung_clk_extended_sleep_init(reg_base,
+ exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs),
+ exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc));
+ if (soc == EXYNOS5800)
+ samsung_clk_sleep_init(reg_base, exynos5800_clk_regs,
+ ARRAY_SIZE(exynos5800_clk_regs));
exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5x_subcmus),
exynos5x_subcmus);
diff --git a/drivers/clk/samsung/clk-exynos5433.c b/drivers/clk/samsung/clk-exynos5433.c
index 162de44df099..751e2c4fb65b 100644
--- a/drivers/clk/samsung/clk-exynos5433.c
+++ b/drivers/clk/samsung/clk-exynos5433.c
@@ -177,6 +177,17 @@ static const unsigned long top_clk_regs[] __initconst = {
ENABLE_CMU_TOP_DIV_STAT,
};
+static const struct samsung_clk_reg_dump top_suspend_regs[] = {
+ /* force all aclk clocks enabled */
+ { ENABLE_ACLK_TOP, 0x67ecffed },
+ /* force all sclk_uart clocks enabled */
+ { ENABLE_SCLK_TOP_PERIC, 0x38 },
+ /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */
+ { ISP_PLL_CON0, 0x85cc0502 },
+ /* ISP PLL has to be enabled for suspend: reset value + ENABLE bit */
+ { AUD_PLL_CON0, 0x84830202 },
+};
+
/* list of all parent clock list */
PNAME(mout_aud_pll_p) = { "oscclk", "fout_aud_pll", };
PNAME(mout_isp_pll_p) = { "oscclk", "fout_isp_pll", };
@@ -792,6 +803,8 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
.nr_clk_ids = TOP_NR_CLK,
.clk_regs = top_clk_regs,
.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
+ .suspend_regs = top_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(top_suspend_regs),
};
static void __init exynos5433_cmu_top_init(struct device_node *np)
@@ -822,6 +835,13 @@ static const unsigned long cpif_clk_regs[] __initconst = {
ENABLE_SCLK_CPIF,
};
+static const struct samsung_clk_reg_dump cpif_suspend_regs[] = {
+ /* force all sclk clocks enabled */
+ { ENABLE_SCLK_CPIF, 0x3ff },
+ /* MPHY PLL has to be enabled for suspend: reset value + ENABLE bit */
+ { MPHY_PLL_CON0, 0x81c70601 },
+};
+
/* list of all parent clock list */
PNAME(mout_mphy_pll_p) = { "oscclk", "fout_mphy_pll", };
@@ -862,6 +882,8 @@ static const struct samsung_cmu_info cpif_cmu_info __initconst = {
.nr_clk_ids = CPIF_NR_CLK,
.clk_regs = cpif_clk_regs,
.nr_clk_regs = ARRAY_SIZE(cpif_clk_regs),
+ .suspend_regs = cpif_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(cpif_suspend_regs),
};
static void __init exynos5433_cmu_cpif_init(struct device_node *np)
@@ -1547,6 +1569,13 @@ static const unsigned long peric_clk_regs[] __initconst = {
ENABLE_IP_PERIC2,
};
+static const struct samsung_clk_reg_dump peric_suspend_regs[] = {
+ /* pclk: sci, pmu, sysreg, gpio_{finger, ese, touch, nfc}, uart2-0 */
+ { ENABLE_PCLK_PERIC0, 0xe00ff000 },
+ /* sclk: uart2-0 */
+ { ENABLE_SCLK_PERIC, 0x7 },
+};
+
static const struct samsung_div_clock peric_div_clks[] __initconst = {
/* DIV_PERIC */
DIV(CLK_DIV_SCLK_SCI, "div_sclk_sci", "oscclk", DIV_PERIC, 4, 4),
@@ -1705,6 +1734,8 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
.nr_clk_ids = PERIC_NR_CLK,
.clk_regs = peric_clk_regs,
.nr_clk_regs = ARRAY_SIZE(peric_clk_regs),
+ .suspend_regs = peric_suspend_regs,
+ .nr_suspend_regs = ARRAY_SIZE(peric_suspend_regs),
};
static void __init exynos5433_cmu_peric_init(struct device_node *np)
@@ -5630,7 +5661,7 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
static const struct dev_pm_ops exynos5433_cmu_pm_ops = {
SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume,
NULL)
- SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
};
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
index a9c887475054..8cb868f06257 100644
--- a/drivers/clk/samsung/clk-s3c2410.c
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -11,7 +11,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include <dt-bindings/clock/s3c2410.h>
@@ -40,9 +39,6 @@ enum s3c2410_plls {
static void __iomem *reg_base;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2410_save;
-
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@@ -57,42 +53,6 @@ static unsigned long s3c2410_clk_regs[] __initdata = {
CAMDIVN,
};
-static int s3c2410_clk_suspend(void)
-{
- samsung_clk_save(reg_base, s3c2410_save,
- ARRAY_SIZE(s3c2410_clk_regs));
-
- return 0;
-}
-
-static void s3c2410_clk_resume(void)
-{
- samsung_clk_restore(reg_base, s3c2410_save,
- ARRAY_SIZE(s3c2410_clk_regs));
-}
-
-static struct syscore_ops s3c2410_clk_syscore_ops = {
- .suspend = s3c2410_clk_suspend,
- .resume = s3c2410_clk_resume,
-};
-
-static void __init s3c2410_clk_sleep_init(void)
-{
- s3c2410_save = samsung_clk_alloc_reg_dump(s3c2410_clk_regs,
- ARRAY_SIZE(s3c2410_clk_regs));
- if (!s3c2410_save) {
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
- return;
- }
-
- register_syscore_ops(&s3c2410_clk_syscore_ops);
- return;
-}
-#else
-static void __init s3c2410_clk_sleep_init(void) {}
-#endif
-
PNAME(fclk_p) = { "mpll", "div_slow" };
static struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
@@ -461,7 +421,8 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
ARRAY_SIZE(s3c244x_common_aliases));
}
- s3c2410_clk_sleep_init();
+ samsung_clk_sleep_init(reg_base, s3c2410_clk_regs,
+ ARRAY_SIZE(s3c2410_clk_regs));
samsung_clk_of_add_provider(np, ctx);
}
diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c
index 6bc94d3aff78..dd1159050a5a 100644
--- a/drivers/clk/samsung/clk-s3c2412.c
+++ b/drivers/clk/samsung/clk-s3c2412.c
@@ -11,7 +11,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <dt-bindings/clock/s3c2412.h>
@@ -29,9 +28,6 @@
static void __iomem *reg_base;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2412_save;
-
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@@ -45,42 +41,6 @@ static unsigned long s3c2412_clk_regs[] __initdata = {
CLKSRC,
};
-static int s3c2412_clk_suspend(void)
-{
- samsung_clk_save(reg_base, s3c2412_save,
- ARRAY_SIZE(s3c2412_clk_regs));
-
- return 0;
-}
-
-static void s3c2412_clk_resume(void)
-{
- samsung_clk_restore(reg_base, s3c2412_save,
- ARRAY_SIZE(s3c2412_clk_regs));
-}
-
-static struct syscore_ops s3c2412_clk_syscore_ops = {
- .suspend = s3c2412_clk_suspend,
- .resume = s3c2412_clk_resume,
-};
-
-static void __init s3c2412_clk_sleep_init(void)
-{
- s3c2412_save = samsung_clk_alloc_reg_dump(s3c2412_clk_regs,
- ARRAY_SIZE(s3c2412_clk_regs));
- if (!s3c2412_save) {
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
- return;
- }
-
- register_syscore_ops(&s3c2412_clk_syscore_ops);
- return;
-}
-#else
-static void __init s3c2412_clk_sleep_init(void) {}
-#endif
-
static struct clk_div_table divxti_d[] = {
{ .val = 0, .div = 1 },
{ .val = 1, .div = 2 },
@@ -278,7 +238,8 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f,
samsung_clk_register_alias(ctx, s3c2412_aliases,
ARRAY_SIZE(s3c2412_aliases));
- s3c2412_clk_sleep_init();
+ samsung_clk_sleep_init(reg_base, s3c2412_clk_regs,
+ ARRAY_SIZE(s3c2412_clk_regs));
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c
index c46e6d5bc9bc..884067e4f1a1 100644
--- a/drivers/clk/samsung/clk-s3c2443.c
+++ b/drivers/clk/samsung/clk-s3c2443.c
@@ -11,7 +11,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <dt-bindings/clock/s3c2443.h>
@@ -43,9 +42,6 @@ enum supported_socs {
static void __iomem *reg_base;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c2443_save;
-
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
@@ -65,42 +61,6 @@ static unsigned long s3c2443_clk_regs[] __initdata = {
SCLKCON,
};
-static int s3c2443_clk_suspend(void)
-{
- samsung_clk_save(reg_base, s3c2443_save,
- ARRAY_SIZE(s3c2443_clk_regs));
-
- return 0;
-}
-
-static void s3c2443_clk_resume(void)
-{
- samsung_clk_restore(reg_base, s3c2443_save,
- ARRAY_SIZE(s3c2443_clk_regs));
-}
-
-static struct syscore_ops s3c2443_clk_syscore_ops = {
- .suspend = s3c2443_clk_suspend,
- .resume = s3c2443_clk_resume,
-};
-
-static void __init s3c2443_clk_sleep_init(void)
-{
- s3c2443_save = samsung_clk_alloc_reg_dump(s3c2443_clk_regs,
- ARRAY_SIZE(s3c2443_clk_regs));
- if (!s3c2443_save) {
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
- return;
- }
-
- register_syscore_ops(&s3c2443_clk_syscore_ops);
- return;
-}
-#else
-static void __init s3c2443_clk_sleep_init(void) {}
-#endif
-
PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" };
PNAME(esysclk_p) = { "epllref", "epll" };
PNAME(mpllref_p) = { "xti", "mdivclk" };
@@ -450,7 +410,8 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
break;
}
- s3c2443_clk_sleep_init();
+ samsung_clk_sleep_init(reg_base, s3c2443_clk_regs,
+ ARRAY_SIZE(s3c2443_clk_regs));
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c
index 6db01cf5ab83..54916c7bdb06 100644
--- a/drivers/clk/samsung/clk-s3c64xx.c
+++ b/drivers/clk/samsung/clk-s3c64xx.c
@@ -12,7 +12,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include <dt-bindings/clock/samsung,s3c64xx-clock.h>
@@ -59,10 +58,6 @@
static void __iomem *reg_base;
static bool is_s3c6400;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s3c64xx_save_common;
-static struct samsung_clk_reg_dump *s3c64xx_save_soc;
-
/*
* List of controller registers to be saved and restored during
* a suspend/resume cycle.
@@ -89,60 +84,6 @@ static unsigned long s3c6410_clk_regs[] __initdata = {
MEM0_GATE,
};
-static int s3c64xx_clk_suspend(void)
-{
- samsung_clk_save(reg_base, s3c64xx_save_common,
- ARRAY_SIZE(s3c64xx_clk_regs));
-
- if (!is_s3c6400)
- samsung_clk_save(reg_base, s3c64xx_save_soc,
- ARRAY_SIZE(s3c6410_clk_regs));
-
- return 0;
-}
-
-static void s3c64xx_clk_resume(void)
-{
- samsung_clk_restore(reg_base, s3c64xx_save_common,
- ARRAY_SIZE(s3c64xx_clk_regs));
-
- if (!is_s3c6400)
- samsung_clk_restore(reg_base, s3c64xx_save_soc,
- ARRAY_SIZE(s3c6410_clk_regs));
-}
-
-static struct syscore_ops s3c64xx_clk_syscore_ops = {
- .suspend = s3c64xx_clk_suspend,
- .resume = s3c64xx_clk_resume,
-};
-
-static void __init s3c64xx_clk_sleep_init(void)
-{
- s3c64xx_save_common = samsung_clk_alloc_reg_dump(s3c64xx_clk_regs,
- ARRAY_SIZE(s3c64xx_clk_regs));
- if (!s3c64xx_save_common)
- goto err_warn;
-
- if (!is_s3c6400) {
- s3c64xx_save_soc = samsung_clk_alloc_reg_dump(s3c6410_clk_regs,
- ARRAY_SIZE(s3c6410_clk_regs));
- if (!s3c64xx_save_soc)
- goto err_soc;
- }
-
- register_syscore_ops(&s3c64xx_clk_syscore_ops);
- return;
-
-err_soc:
- kfree(s3c64xx_save_common);
-err_warn:
- pr_warn("%s: failed to allocate sleep save data, no sleep support!\n",
- __func__);
-}
-#else
-static void __init s3c64xx_clk_sleep_init(void) {}
-#endif
-
/* List of parent clocks common for all S3C64xx SoCs. */
PNAME(spi_mmc_p) = { "mout_epll", "dout_mpll", "fin_pll", "clk27m" };
PNAME(uart_p) = { "mout_epll", "dout_mpll" };
@@ -508,7 +449,12 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
samsung_clk_register_alias(ctx, s3c64xx_clock_aliases,
ARRAY_SIZE(s3c64xx_clock_aliases));
- s3c64xx_clk_sleep_init();
+
+ samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs,
+ ARRAY_SIZE(s3c64xx_clk_regs));
+ if (!is_s3c6400)
+ samsung_clk_sleep_init(reg_base, s3c6410_clk_regs,
+ ARRAY_SIZE(s3c6410_clk_regs));
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c
index fd2725710a6f..41d2337fe030 100644
--- a/drivers/clk/samsung/clk-s5pv210.c
+++ b/drivers/clk/samsung/clk-s5pv210.c
@@ -14,7 +14,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/syscore_ops.h>
#include "clk.h"
#include "clk-pll.h"
@@ -83,9 +82,6 @@ enum {
static void __iomem *reg_base;
-#ifdef CONFIG_PM_SLEEP
-static struct samsung_clk_reg_dump *s5pv210_clk_dump;
-
/* List of registers that need to be preserved across suspend/resume. */
static unsigned long s5pv210_clk_regs[] __initdata = {
CLK_SRC0,
@@ -132,40 +128,6 @@ static unsigned long s5pv210_clk_regs[] __initdata = {
CLK_OUT,
};
-static int s5pv210_clk_suspend(void)
-{
- samsung_clk_save(reg_base, s5pv210_clk_dump,
- ARRAY_SIZE(s5pv210_clk_regs));
- return 0;
-}
-
-static void s5pv210_clk_resume(void)
-{
- samsung_clk_restore(reg_base, s5pv210_clk_dump,
- ARRAY_SIZE(s5pv210_clk_regs));
-}
-
-static struct syscore_ops s5pv210_clk_syscore_ops = {
- .suspend = s5pv210_clk_suspend,
- .resume = s5pv210_clk_resume,
-};
-
-static void s5pv210_clk_sleep_init(void)
-{
- s5pv210_clk_dump =
- samsung_clk_alloc_reg_dump(s5pv210_clk_regs,
- ARRAY_SIZE(s5pv210_clk_regs));
- if (!s5pv210_clk_dump) {
- pr_warn("%s: Failed to allocate sleep save data\n", __func__);
- return;
- }
-
- register_syscore_ops(&s5pv210_clk_syscore_ops);
-}
-#else
-static inline void s5pv210_clk_sleep_init(void) { }
-#endif
-
/* Mux parent lists. */
static const char *const fin_pll_p[] __initconst = {
"xxti",
@@ -822,7 +784,8 @@ static void __init __s5pv210_clk_init(struct device_node *np,
samsung_clk_register_alias(ctx, s5pv210_aliases,
ARRAY_SIZE(s5pv210_aliases));
- s5pv210_clk_sleep_init();
+ samsung_clk_sleep_init(reg_base, s5pv210_clk_regs,
+ ARRAY_SIZE(s5pv210_clk_regs));
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index 8634884aa11c..1f6e47cd327d 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -290,9 +290,12 @@ static int samsung_clk_suspend(void)
{
struct samsung_clock_reg_cache *reg_cache;
- list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
+ list_for_each_entry(reg_cache, &clock_reg_cache_list, node) {
samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
reg_cache->rd_num);
+ samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend,
+ reg_cache->rsuspend_num);
+ }
return 0;
}
@@ -310,9 +313,11 @@ static struct syscore_ops samsung_clk_syscore_ops = {
.resume = samsung_clk_resume,
};
-void samsung_clk_sleep_init(void __iomem *reg_base,
+void samsung_clk_extended_sleep_init(void __iomem *reg_base,
const unsigned long *rdump,
- unsigned long nr_rdump)
+ unsigned long nr_rdump,
+ const struct samsung_clk_reg_dump *rsuspend,
+ unsigned long nr_rsuspend)
{
struct samsung_clock_reg_cache *reg_cache;
@@ -330,13 +335,10 @@ void samsung_clk_sleep_init(void __iomem *reg_base,
reg_cache->reg_base = reg_base;
reg_cache->rd_num = nr_rdump;
+ reg_cache->rsuspend = rsuspend;
+ reg_cache->rsuspend_num = nr_rsuspend;
list_add_tail(&reg_cache->node, &clock_reg_cache_list);
}
-
-#else
-void samsung_clk_sleep_init(void __iomem *reg_base,
- const unsigned long *rdump,
- unsigned long nr_rdump) {}
#endif
/*
@@ -380,8 +382,9 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
cmu->nr_fixed_factor_clks);
if (cmu->clk_regs)
- samsung_clk_sleep_init(reg_base, cmu->clk_regs,
- cmu->nr_clk_regs);
+ samsung_clk_extended_sleep_init(reg_base,
+ cmu->clk_regs, cmu->nr_clk_regs,
+ cmu->suspend_regs, cmu->nr_suspend_regs);
samsung_clk_of_add_provider(np, ctx);
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 3880d2f9d582..c3f309d7100d 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -279,6 +279,8 @@ struct samsung_clock_reg_cache {
void __iomem *reg_base;
struct samsung_clk_reg_dump *rdump;
unsigned int rd_num;
+ const struct samsung_clk_reg_dump *rsuspend;
+ unsigned int rsuspend_num;
};
struct samsung_cmu_info {
@@ -358,9 +360,21 @@ extern struct samsung_clk_provider __init *samsung_cmu_register_one(
extern unsigned long _get_rate(const char *clk_name);
-extern void samsung_clk_sleep_init(void __iomem *reg_base,
+#ifdef CONFIG_PM_SLEEP
+extern void samsung_clk_extended_sleep_init(void __iomem *reg_base,
const unsigned long *rdump,
- unsigned long nr_rdump);
+ unsigned long nr_rdump,
+ const struct samsung_clk_reg_dump *rsuspend,
+ unsigned long nr_rsuspend);
+#else
+static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
+ const unsigned long *rdump,
+ unsigned long nr_rdump,
+ const struct samsung_clk_reg_dump *rsuspend,
+ unsigned long nr_rsuspend) {}
+#endif
+#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
+ samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
extern void samsung_clk_save(void __iomem *base,
struct samsung_clk_reg_dump *rd,