Quoting Chris Zhong (2014-11-07 05:49:33) > save and restore some clks, which might be changed in suspend. > > Signed-off-by: Tony Xie <xxx at rock-chips.com> > Signed-off-by: Chris Zhong <zyw at rock-chips.com> > Reviewed-by: Doug Anderson <dianders at chromium.org> > Tested-by: Doug Anderson <dianders at chromium.org> Looks good to me. Regards, Mike > > --- > > Changes in v7: None > Changes in v6: > - modify comments > > Changes in v5: > - modify comments > > Changes in v4: None > Changes in v3: None > Changes in v2: > - __raw_readl/__raw_writel replaced by readl_relaxed/writel_relaxed > > drivers/clk/rockchip/clk-rk3288.c | 60 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 60 insertions(+) > > diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c > index 2327829..66a9cb0 100644 > --- a/drivers/clk/rockchip/clk-rk3288.c > +++ b/drivers/clk/rockchip/clk-rk3288.c > @@ -16,6 +16,7 @@ > #include <linux/clk-provider.h> > #include <linux/of.h> > #include <linux/of_address.h> > +#include <linux/syscore_ops.h> > #include <dt-bindings/clock/rk3288-cru.h> > #include "clk.h" > > @@ -762,6 +763,64 @@ static const char *rk3288_critical_clocks[] __initconst = { > "hclk_peri", > }; > > +#ifdef CONFIG_PM_SLEEP > +static void __iomem *rk3288_cru_base; > + > +/* Some CRU registers will be reset in maskrom when the system > + * wakes up from fastboot. > + * So save them before suspend, restore them after resume. > + */ > +static const int rk3288_saved_cru_reg_ids[] = { > + RK3288_MODE_CON, > + RK3288_CLKSEL_CON(0), > + RK3288_CLKSEL_CON(1), > + RK3288_CLKSEL_CON(10), > + RK3288_CLKSEL_CON(33), > + RK3288_CLKSEL_CON(37), > +}; > + > +static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; > + > +static int rk3288_clk_suspend(void) > +{ > + int i, reg_id; > + > + for (i = 0; i < ARRAY_SIZE(rk3288_saved_cru_reg_ids); i++) { > + reg_id = rk3288_saved_cru_reg_ids[i]; > + > + rk3288_saved_cru_regs[i] = > + readl_relaxed(rk3288_cru_base + reg_id); > + } > + return 0; > +} > + > +static void rk3288_clk_resume(void) > +{ > + int i, reg_id; > + > + for (i = ARRAY_SIZE(rk3288_saved_cru_reg_ids) - 1; i >= 0; i--) { > + reg_id = rk3288_saved_cru_reg_ids[i]; > + > + writel_relaxed(rk3288_saved_cru_regs[i] | 0xffff0000, > + rk3288_cru_base + reg_id); > + } > +} > + > +static struct syscore_ops rk3288_clk_syscore_ops = { > + .suspend = rk3288_clk_suspend, > + .resume = rk3288_clk_resume, > +}; > + > +static void rk3288_clk_sleep_init(void __iomem *reg_base) > +{ > + rk3288_cru_base = reg_base; > + register_syscore_ops(&rk3288_clk_syscore_ops); > +} > + > +#else /* CONFIG_PM_SLEEP */ > +static void rk3288_clk_sleep_init(void __iomem *reg_base) {} > +#endif > + > static void __init rk3288_clk_init(struct device_node *np) > { > void __iomem *reg_base; > @@ -810,5 +869,6 @@ static void __init rk3288_clk_init(struct device_node *np) > ROCKCHIP_SOFTRST_HIWORD_MASK); > > rockchip_register_restart_notifier(RK3288_GLB_SRST_FST); > + rk3288_clk_sleep_init(reg_base); > } > CLK_OF_DECLARE(rk3288_cru, "rockchip,rk3288-cru", rk3288_clk_init); > -- > 1.9.1 >