#!/bin/sh
#===============================================================================
#
#  suspend
#
#  Copyright (C) 2009-2021 by Digi International Inc.
#  All rights reserved.
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License version 2 as published by
#  the Free Software Foundation.
#
#
#  !Description: suspend system to RAM
#
#===============================================================================

scriptname="$(basename ${0})"
syspower="/sys/power/state"

usage() {
	printf "\nSuspend system to RAM memory\n"
	printf "\nUsage: ${scriptname} [OPTIONS]\n
	-h      Show this help
	\n"
}

suspend_system_time() {
	if [ "$(echo /sys/class/rtc/rtc*)" != "/sys/class/rtc/rtc*" ]; then
		hwclock -w
	fi
}

suspend_interfaces() {
	# 'wlan0' interface on some platforms (ccwmx5xjs, cwme9210, ccardwmx28js)
	# has problems on suspend-resume, so we workaround it by bringing the
	# interface down before suspend and bring it up again after resume.
	# (#35777, #40082)
	if grep -qs '^wlan0' /var/run/ifstate; then
		ifdown wlan0 && up_wlan_on_resume="1" && sleep 0.5
	fi
	# AR6233 Wireless module
	[ -e /sys/module/ath6kl_sdio ] && rmmod ath6kl_sdio && wlan_device_id="301"
	# QCA6564 Wireless module
	[ -e /sys/module/wlan ] && rmmod wlan && wlan_device_id="50A"
}

resume_interfaces() {
	# 'wlan0' interface on some platforms (ccwmx5xjs, cwme9210, ccardwmx28js)
	# has problems on suspend-resume, so we workaround it by bringing the
	# interface down before suspend and bring it up again after resume.
	# (#35777, #40082)
	if ! grep -qs '^wlan0' /var/run/ifstate; then
		if [ -n "${up_wlan_on_resume}" ]; then
			if [ -n "${wlan_device_id}" ]; then
				udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d0${wlan_device_id}"
				timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null
			fi
			ifup wlan0
		fi
	fi
}

resume_system_time() {
	if [ "$(echo /sys/class/rtc/rtc*)" != "/sys/class/rtc/rtc*" ]; then
		hwclock -s
	fi
}

while getopts "h" c; do
	case "${c}" in
		h) usage; exit;;
	esac
done

if [ -f "${syspower}" ]; then
	# Pre-suspend actions
	suspend_system_time
	suspend_interfaces

	# Suspend the device
	printf "mem" > ${syspower}
	sleep .5

	# Post-resume actions
	resume_interfaces
	resume_system_time
else
	printf "\n[ERROR] File ${syspower} not found\n\n"
fi
