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 */
s3c_pm_do_save(struct sleep_save * ptr,int count)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
s3c_pm_do_restore(const struct sleep_save * ptr,int count)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
s3c_pm_do_restore_core(const struct sleep_save * ptr,int count)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