diff options
author | Arnd Bergmann <arnd@arndb.de> | 2014-12-04 18:46:43 +0300 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2014-12-04 18:46:43 +0300 |
commit | ab64920c3742ba992a3bf0b06f9750d1cad9d050 (patch) | |
tree | 3391e85b0bb7372d7d34775047e9d8c894042938 /drivers/clk | |
parent | 756f80cee766574ae282baa97fdcf9cc6d0cc70c (diff) | |
parent | 6e6db2bea3ea9424a0cb19d89d47664bc13e31bc (diff) | |
download | linux-ab64920c3742ba992a3bf0b06f9750d1cad9d050.tar.xz |
Merge tag 'mvebu-soc-suspend-3.19' of git://git.infradead.org/linux-mvebu into next/soc
Pull "mvebu SoC suspend changes for v3.19" from Jason Cooper:
- Armada 370/XP suspend/resume support
- mvebu SoC driver suspend/resume support
- irqchip
- clocksource
- mbus
- clk
* tag 'mvebu-soc-suspend-3.19' of git://git.infradead.org/linux-mvebu:
ARM: mvebu: add SDRAM controller description for Armada XP
ARM: mvebu: adjust mbus controller description on Armada 370/XP
ARM: mvebu: add suspend/resume DT information for Armada XP GP
ARM: mvebu: synchronize secondary CPU clocks on resume
ARM: mvebu: make sure MMU is disabled in armada_370_xp_cpu_resume
ARM: mvebu: Armada XP GP specific suspend/resume code
ARM: mvebu: reserve the first 10 KB of each memory bank for suspend/resume
ARM: mvebu: implement suspend/resume support for Armada XP
clk: mvebu: add suspend/resume for gatable clocks
bus: mvebu-mbus: provide a mechanism to save SDRAM window configuration
bus: mvebu-mbus: suspend/resume support
clocksource: time-armada-370-xp: add suspend/resume support
irqchip: armada-370-xp: Add suspend/resume support
Documentation: dt-bindings: minimal documentation for MVEBU SDRAM controller
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/mvebu/common.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index b7fcb469c87a..0d4d1216f2dd 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -19,6 +19,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/syscore_ops.h> #include "common.h" @@ -177,14 +178,17 @@ struct clk_gating_ctrl { spinlock_t *lock; struct clk **gates; int num_gates; + void __iomem *base; + u32 saved_reg; }; #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) +static struct clk_gating_ctrl *ctrl; + static struct clk *clk_gating_get_src( struct of_phandle_args *clkspec, void *data) { - struct clk_gating_ctrl *ctrl = (struct clk_gating_ctrl *)data; int n; if (clkspec->args_count < 1) @@ -199,15 +203,35 @@ static struct clk *clk_gating_get_src( return ERR_PTR(-ENODEV); } +static int mvebu_clk_gating_suspend(void) +{ + ctrl->saved_reg = readl(ctrl->base); + return 0; +} + +static void mvebu_clk_gating_resume(void) +{ + writel(ctrl->saved_reg, ctrl->base); +} + +static struct syscore_ops clk_gate_syscore_ops = { + .suspend = mvebu_clk_gating_suspend, + .resume = mvebu_clk_gating_resume, +}; + void __init mvebu_clk_gating_setup(struct device_node *np, const struct clk_gating_soc_desc *desc) { - struct clk_gating_ctrl *ctrl; struct clk *clk; void __iomem *base; const char *default_parent = NULL; int n; + if (ctrl) { + pr_err("mvebu-clk-gating: cannot instantiate more than one gatable clock device\n"); + return; + } + base = of_iomap(np, 0); if (WARN_ON(!base)) return; @@ -225,6 +249,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np, /* lock must already be initialized */ ctrl->lock = &ctrl_gating_lock; + ctrl->base = base; + /* Count, allocate, and register clock gates */ for (n = 0; desc[n].name;) n++; @@ -246,6 +272,8 @@ void __init mvebu_clk_gating_setup(struct device_node *np, of_clk_add_provider(np, clk_gating_get_src, ctrl); + register_syscore_ops(&clk_gate_syscore_ops); + return; gates_out: kfree(ctrl); |