171b9114dSArnd Bergmann // SPDX-License-Identifier: GPL-2.0 271b9114dSArnd Bergmann // 371b9114dSArnd Bergmann // Copyright (C) 2013 Samsung Electronics Co., Ltd. 471b9114dSArnd Bergmann // Tomasz Figa <t.figa@samsung.com> 571b9114dSArnd Bergmann // Copyright (C) 2008 Openmoko, Inc. 671b9114dSArnd Bergmann // Copyright (C) 2004-2008 Simtec Electronics 771b9114dSArnd Bergmann // Ben Dooks <ben@simtec.co.uk> 871b9114dSArnd Bergmann // http://armlinux.simtec.co.uk/ 971b9114dSArnd Bergmann // 1071b9114dSArnd Bergmann // Samsung common power management helper functions. 1171b9114dSArnd Bergmann 1271b9114dSArnd Bergmann #include <linux/io.h> 1371b9114dSArnd Bergmann #include <linux/kernel.h> 1471b9114dSArnd Bergmann 15*c6ff132dSArnd Bergmann #include "pm-common.h" 1671b9114dSArnd Bergmann 1771b9114dSArnd Bergmann /* helper functions to save and restore register state */ 1871b9114dSArnd Bergmann 1971b9114dSArnd Bergmann /** 2071b9114dSArnd Bergmann * s3c_pm_do_save() - save a set of registers for restoration on resume. 2171b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 2271b9114dSArnd Bergmann * @count: Size of the ptr array. 2371b9114dSArnd Bergmann * 2471b9114dSArnd Bergmann * Run through the list of registers given, saving their contents in the 2571b9114dSArnd Bergmann * array for later restoration when we wakeup. 2671b9114dSArnd Bergmann */ 2771b9114dSArnd Bergmann void s3c_pm_do_save(struct sleep_save *ptr, int count) 2871b9114dSArnd Bergmann { 2971b9114dSArnd Bergmann for (; count > 0; count--, ptr++) { 3071b9114dSArnd Bergmann ptr->val = readl_relaxed(ptr->reg); 3171b9114dSArnd Bergmann S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); 3271b9114dSArnd Bergmann } 3371b9114dSArnd Bergmann } 3471b9114dSArnd Bergmann 3571b9114dSArnd Bergmann /** 3671b9114dSArnd Bergmann * s3c_pm_do_restore() - restore register values from the save list. 3771b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 3871b9114dSArnd Bergmann * @count: Size of the ptr array. 3971b9114dSArnd Bergmann * 4071b9114dSArnd Bergmann * Restore the register values saved from s3c_pm_do_save(). 4171b9114dSArnd Bergmann * 4271b9114dSArnd Bergmann * Note, we do not use S3C_PMDBG() in here, as the system may not have 4371b9114dSArnd Bergmann * restore the UARTs state yet 4471b9114dSArnd Bergmann */ 4571b9114dSArnd Bergmann 4671b9114dSArnd Bergmann void s3c_pm_do_restore(const struct sleep_save *ptr, int count) 4771b9114dSArnd Bergmann { 4871b9114dSArnd Bergmann for (; count > 0; count--, ptr++) { 4971b9114dSArnd Bergmann pr_debug("restore %p (restore %08lx, was %08x)\n", 5071b9114dSArnd Bergmann ptr->reg, ptr->val, readl_relaxed(ptr->reg)); 5171b9114dSArnd Bergmann 5271b9114dSArnd Bergmann writel_relaxed(ptr->val, ptr->reg); 5371b9114dSArnd Bergmann } 5471b9114dSArnd Bergmann } 5571b9114dSArnd Bergmann 5671b9114dSArnd Bergmann /** 5771b9114dSArnd Bergmann * s3c_pm_do_restore_core() - early restore register values from save list. 5871b9114dSArnd Bergmann * @ptr: Pointer to an array of registers. 5971b9114dSArnd Bergmann * @count: Size of the ptr array. 6071b9114dSArnd Bergmann * 6171b9114dSArnd Bergmann * This is similar to s3c_pm_do_restore() except we try and minimise the 6271b9114dSArnd Bergmann * side effects of the function in case registers that hardware might need 6371b9114dSArnd Bergmann * to work has been restored. 6471b9114dSArnd Bergmann * 6571b9114dSArnd Bergmann * WARNING: Do not put any debug in here that may effect memory or use 6671b9114dSArnd Bergmann * peripherals, as things may be changing! 6771b9114dSArnd Bergmann */ 6871b9114dSArnd Bergmann 6971b9114dSArnd Bergmann void s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) 7071b9114dSArnd Bergmann { 7171b9114dSArnd Bergmann for (; count > 0; count--, ptr++) 7271b9114dSArnd Bergmann writel_relaxed(ptr->val, ptr->reg); 7371b9114dSArnd Bergmann } 74