1*71b9114dSArnd Bergmann // SPDX-License-Identifier: GPL-2.0 2*71b9114dSArnd Bergmann // 3*71b9114dSArnd Bergmann // Copyright (C) 2013 Samsung Electronics Co., Ltd. 4*71b9114dSArnd Bergmann // Tomasz Figa <t.figa@samsung.com> 5*71b9114dSArnd Bergmann // Copyright (C) 2008 Openmoko, Inc. 6*71b9114dSArnd Bergmann // Copyright (C) 2004-2008 Simtec Electronics 7*71b9114dSArnd Bergmann // Ben Dooks <ben@simtec.co.uk> 8*71b9114dSArnd Bergmann // http://armlinux.simtec.co.uk/ 9*71b9114dSArnd Bergmann // 10*71b9114dSArnd Bergmann // Samsung common power management helper functions. 11*71b9114dSArnd Bergmann 12*71b9114dSArnd Bergmann #include <linux/io.h> 13*71b9114dSArnd Bergmann #include <linux/kernel.h> 14*71b9114dSArnd Bergmann 15*71b9114dSArnd Bergmann #include <plat/pm-common.h> 16*71b9114dSArnd Bergmann 17*71b9114dSArnd Bergmann /* helper functions to save and restore register state */ 18*71b9114dSArnd Bergmann 19*71b9114dSArnd Bergmann /** 20*71b9114dSArnd Bergmann * s3c_pm_do_save() - save a set of registers for restoration on resume. 21*71b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 22*71b9114dSArnd Bergmann * @count: Size of the ptr array. 23*71b9114dSArnd Bergmann * 24*71b9114dSArnd Bergmann * Run through the list of registers given, saving their contents in the 25*71b9114dSArnd Bergmann * array for later restoration when we wakeup. 26*71b9114dSArnd Bergmann */ 27*71b9114dSArnd Bergmann void s3c_pm_do_save(struct sleep_save *ptr, int count) 28*71b9114dSArnd Bergmann { 29*71b9114dSArnd Bergmann for (; count > 0; count--, ptr++) { 30*71b9114dSArnd Bergmann ptr->val = readl_relaxed(ptr->reg); 31*71b9114dSArnd Bergmann S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); 32*71b9114dSArnd Bergmann } 33*71b9114dSArnd Bergmann } 34*71b9114dSArnd Bergmann 35*71b9114dSArnd Bergmann /** 36*71b9114dSArnd Bergmann * s3c_pm_do_restore() - restore register values from the save list. 37*71b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 38*71b9114dSArnd Bergmann * @count: Size of the ptr array. 39*71b9114dSArnd Bergmann * 40*71b9114dSArnd Bergmann * Restore the register values saved from s3c_pm_do_save(). 41*71b9114dSArnd Bergmann * 42*71b9114dSArnd Bergmann * Note, we do not use S3C_PMDBG() in here, as the system may not have 43*71b9114dSArnd Bergmann * restore the UARTs state yet 44*71b9114dSArnd Bergmann */ 45*71b9114dSArnd Bergmann 46*71b9114dSArnd Bergmann void s3c_pm_do_restore(const struct sleep_save *ptr, int count) 47*71b9114dSArnd Bergmann { 48*71b9114dSArnd Bergmann for (; count > 0; count--, ptr++) { 49*71b9114dSArnd Bergmann pr_debug("restore %p (restore %08lx, was %08x)\n", 50*71b9114dSArnd Bergmann ptr->reg, ptr->val, readl_relaxed(ptr->reg)); 51*71b9114dSArnd Bergmann 52*71b9114dSArnd Bergmann writel_relaxed(ptr->val, ptr->reg); 53*71b9114dSArnd Bergmann } 54*71b9114dSArnd Bergmann } 55*71b9114dSArnd Bergmann 56*71b9114dSArnd Bergmann /** 57*71b9114dSArnd Bergmann * s3c_pm_do_restore_core() - early restore register values from save list. 58*71b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 59*71b9114dSArnd Bergmann * @count: Size of the ptr array. 60*71b9114dSArnd Bergmann * 61*71b9114dSArnd Bergmann * This is similar to s3c_pm_do_restore() except we try and minimise the 62*71b9114dSArnd Bergmann * side effects of the function in case registers that hardware might need 63*71b9114dSArnd Bergmann * to work has been restored. 64*71b9114dSArnd Bergmann * 65*71b9114dSArnd Bergmann * WARNING: Do not put any debug in here that may effect memory or use 66*71b9114dSArnd Bergmann * peripherals, as things may be changing! 67*71b9114dSArnd Bergmann */ 68*71b9114dSArnd Bergmann 69*71b9114dSArnd Bergmann void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) 70*71b9114dSArnd Bergmann { 71*71b9114dSArnd Bergmann for (; count > 0; count--, ptr++) 72*71b9114dSArnd Bergmann writel_relaxed(ptr->val, ptr->reg); 73*71b9114dSArnd Bergmann } 74