106 lines
2.6 KiB
Bash
Executable File
106 lines
2.6 KiB
Bash
Executable File
#!/bin/sh
|
|
#===============================================================================
|
|
#
|
|
# suspend
|
|
#
|
|
# Copyright (C) 2016, 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 interfaces
|
|
if [ -d "/proc/device-tree/wireless" ]; then
|
|
for i in $(sed -ne 's,^\(wlan[0-9]\)=.*,\1,g;T;p' /var/run/ifstate | sort -r); do
|
|
ifdown "${i}" && RESUME_IFACES="${RESUME_IFACES:+${RESUME_IFACES} }${i}"
|
|
done
|
|
grep -qs '^wlan' /proc/modules && rmmod wlan
|
|
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 interfaces
|
|
if [ -d "/proc/device-tree/wireless" ]; then
|
|
# Trigger wireless module loading event, and wait until the interface exists
|
|
udevadm trigger --action=add --attr-match="modalias=sdio:c00v0271d050A"
|
|
timeout -t 5 sh -c "while [ ! -d /sys/class/net/wlan0 ]; do sleep .2; done" 2>/dev/null
|
|
|
|
# Bring up the interfaces that were bring down on suspend
|
|
for i in $(echo ${RESUME_IFACES} | tr ' ' '\n' | sort); do
|
|
grep -qs "^${i}" /var/run/ifstate || ifup "${i}"
|
|
done
|
|
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}
|
|
|
|
# Post-resume actions
|
|
resume_interfaces
|
|
|
|
exit_critical_section
|
|
else
|
|
printf "\n[ERROR] File ${syspower} not found\n\n"
|
|
fi
|