#!/bin/sh
#===============================================================================
#
#  suspend
#
#  Copyright (C) 2009-2017 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"
lockfile="/var/lock/${scriptname}.lock"
lockfd="9"

BT_INIT="/etc/init.d/bluetooth-init"
BT_DAEMON="/etc/init.d/bluetooth"

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

suspend_interfaces() {
	# Suspend wireless interface
	if grep -qs '^wlan0' /var/run/ifstate; then
		ifdown wlan0 && up_wlan_on_resume="1" && sleep 0.5 && rmmod ath6kl_sdio
	fi

	# Suspend bluetooth interface
	hciconfig hci0 2>&1 | grep -qs UP && up_bt_on_resume="1"
	${BT_DAEMON} stop >/dev/null
	${BT_INIT} stop >/dev/null
}

resume_interfaces() {
	# Resume wireless interface
	if ! grep -qs '^wlan0' /var/run/ifstate; then
		[ -n "${up_wlan_on_resume}" ] && modprobe ath6kl_sdio && sleep 0.5 && ifup wlan0
	fi

	# Resume bluetooth interface
	if [ -n "${up_bt_on_resume}" ]; then
		${BT_INIT} start >/dev/null
		${BT_DAEMON} start >/dev/null
	fi
}

enter_critical_section() {
	# Create lock file
	eval "exec ${lockfd}>${lockfile}"

	# Acquire the lock in non blocking mode. Otherwise, additional calls
	# to the script will be queued and the system will endlessly go in
	# and out of suspend to ram
	flock -n "${lockfd}" || exit 0
}

exit_critical_section() {
	# Release the lock
	flock -u "${lockfd}"
}

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

if [ -f "${syspower}" ]; then
	# Avoid running multiple instances of this script in parallel
	enter_critical_section

	# Pre-suspend actions
	suspend_interfaces

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

	# Post-resume actions
	resume_interfaces

	exit_critical_section
else
	printf "\n[ERROR] File ${syspower} not found\n\n"
fi
