+display_on_with_checks() {
+ # after turning on the display, we don't want lowpower state
+ # (which could be active because of some races)
+ if [ "$powerstate" = "buttonlowpower" -o "$powerstate" = "lidlowpower" -o \
+ -e /tmp/oldspeed ]
+ then
+ lowPowerOff
+ else
+ display_on
+ fi
+}
+
+show_message() {
+ # TODO: check if desktop is visible; maybe use layer3?
+ xfceuser=$(ps u -C xfce4-session | tail -n1 | awk '{print $1}')
+ cmd="DISPLAY=:0.0 zenity --info --text \"$1\" --timeout 10"
+ su -c "$cmd" $xfceuser
+}
+
+suspend_real() {
+ delay=0
+
+ if ! [ -e /sys/power/state ]; then
+ # no kernel suspend support
+ return 1
+ fi
+
+ current_now="$(cat /sys/class/power_supply/bq27500-0/current_now)"
+
+ if [ $current_now -gt 0 ]; then
+ return 1
+ #don't suspend while unit is charging
+ fi
+
+ # can't suspend while SGX is in use due to bugs
+ # (prevents low power states and potential lockup)
+ if lsof -t /dev/pvrsrvkm > /dev/null; then
+ return 1
+ fi
+
+ if ! grep -q 'mmc_core.removable=0' /proc/cmdline; then
+ # must unmount cards because they will be "ejected" on suspend
+ # (some filesystems may even deadlock if we don't do this due to bugs)
+ mounts="$(grep "/dev/mmcblk" /proc/mounts | awk '{print $1}' | xargs echo)"
+ for mnt in $mounts; do
+ if ! umount $mnt; then
+ show_message "Could not unmount $mnt, using partial suspend only"
+ return 1
+ fi
+ done
+ swaps="$(grep "/dev/mmcblk" /proc/swaps | awk '{print $1}' | xargs echo)"
+ for swp in $swaps; do
+ if ! swapoff $swp; then
+ show_message "Could not unmount $swp, using partial suspend only"
+ return 1
+ fi
+ done
+ else
+ if [ ! -e /etc/pandora/suspend-warned ]; then
+ show_message "Pandora will now suspend.\n\n\
+Please do not remove SD cards while pandora is suspended, doing so will corrupt them."
+ touch /etc/pandora/suspend-warned
+ fi
+ fi
+
+ # FIXME: fix the kernel and get rid of this
+ suspend_net
+
+ # get rid of modules that prevent suspend due to bugs
+ modules="$(lsmod | awk '{print $1}' | xargs echo)"
+ blacklist="g_zero g_audio g_ether g_serial g_midi gadgetfs g_file_storage
+ g_mass_storage g_printer g_cdc g_multi g_hid g_dbgp g_nokia g_webcam g_ncm g_acm_ms
+ ehci_hcd bridgedriver"
+ restore_list=""
+ for mod in $modules; do
+ if echo $blacklist | grep -q "\<$mod\>"; then
+ restore_list="$restore_list $mod"
+ rmmod $mod
+ delay=1 # enough?
+ fi
+ done
+
+ sleep $delay
+ sync
+ echo mem > /sys/power/state
+
+ # if we are here, either we already resumed or the suspend failed
+ if [ -n "$restore_list" ]; then
+ modprobe $restore_list
+ fi
+
+ display_on
+ resume_net
+ echo 255 > /sys/class/leds/pandora\:\:power/brightness
+
+ # wait here a bit to prevent this script from running again (keep op_power.lock)
+ # in case user did resume using the power switch.
+ sleep 2
+
+ return 0
+}
+
+suspend_() {
+ # dim power LED
+ echo 16 > /sys/class/leds/pandora\:\:power/brightness
+
+ if suspend_real; then
+ # resumed already
+ powerstate="on"
+ else
+ lowPowerOn
+ fi
+}
+
+resume() {
+ if [ "$powerstate" = "on" ]; then
+ # nothing to do
+ echo "resume called unexpectedly" >&2
+ else
+ lowPowerOff
+ fi
+}
+