162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// Copyright (C) 2013 Samsung Electronics Co., Ltd. 462306a36Sopenharmony_ci// Tomasz Figa <t.figa@samsung.com> 562306a36Sopenharmony_ci// Copyright (C) 2008 Openmoko, Inc. 662306a36Sopenharmony_ci// Copyright (C) 2004-2008 Simtec Electronics 762306a36Sopenharmony_ci// Ben Dooks <ben@simtec.co.uk> 862306a36Sopenharmony_ci// http://armlinux.simtec.co.uk/ 962306a36Sopenharmony_ci// 1062306a36Sopenharmony_ci// Samsung common power management helper functions. 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/io.h> 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include "pm-common.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* helper functions to save and restore register state */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/** 2062306a36Sopenharmony_ci * s3c_pm_do_save() - save a set of registers for restoration on resume. 2162306a36Sopenharmony_ci * @ptr: Pointer to an array of registers. 2262306a36Sopenharmony_ci * @count: Size of the ptr array. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Run through the list of registers given, saving their contents in the 2562306a36Sopenharmony_ci * array for later restoration when we wakeup. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_civoid s3c_pm_do_save(struct sleep_save *ptr, int count) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci for (; count > 0; count--, ptr++) { 3062306a36Sopenharmony_ci ptr->val = readl_relaxed(ptr->reg); 3162306a36Sopenharmony_ci S3C_PMDBG("saved %p value %08lx\n", ptr->reg, ptr->val); 3262306a36Sopenharmony_ci } 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/** 3662306a36Sopenharmony_ci * s3c_pm_do_restore() - restore register values from the save list. 3762306a36Sopenharmony_ci * @ptr: Pointer to an array of registers. 3862306a36Sopenharmony_ci * @count: Size of the ptr array. 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * Restore the register values saved from s3c_pm_do_save(). 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * Note, we do not use S3C_PMDBG() in here, as the system may not have 4362306a36Sopenharmony_ci * restore the UARTs state yet 4462306a36Sopenharmony_ci*/ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_civoid s3c_pm_do_restore(const struct sleep_save *ptr, int count) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci for (; count > 0; count--, ptr++) { 4962306a36Sopenharmony_ci pr_debug("restore %p (restore %08lx, was %08x)\n", 5062306a36Sopenharmony_ci ptr->reg, ptr->val, readl_relaxed(ptr->reg)); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci writel_relaxed(ptr->val, ptr->reg); 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/** 5762306a36Sopenharmony_ci * s3c_pm_do_restore_core() - early restore register values from save list. 5862306a36Sopenharmony_ci * @ptr: Pointer to an array of registers. 5962306a36Sopenharmony_ci * @count: Size of the ptr array. 6062306a36Sopenharmony_ci * 6162306a36Sopenharmony_ci * This is similar to s3c_pm_do_restore() except we try and minimise the 6262306a36Sopenharmony_ci * side effects of the function in case registers that hardware might need 6362306a36Sopenharmony_ci * to work has been restored. 6462306a36Sopenharmony_ci * 6562306a36Sopenharmony_ci * WARNING: Do not put any debug in here that may effect memory or use 6662306a36Sopenharmony_ci * peripherals, as things may be changing! 6762306a36Sopenharmony_ci*/ 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_civoid s3c_pm_do_restore_core(const struct sleep_save *ptr, int count) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci for (; count > 0; count--, ptr++) 7262306a36Sopenharmony_ci writel_relaxed(ptr->val, ptr->reg); 7362306a36Sopenharmony_ci} 74