static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) { static char err_readtime[] __initdata = KERN_ERR "PM: can't read %s time, err %d\n"; static char err_wakealarm [] __initdata = KERN_ERR "PM: can't set %s wakealarm, err %d\n"; static char err_suspend[] __initdata = KERN_ERR "PM: suspend test failed, error %d\n"; static char info_test[] __initdata = KERN_INFO "PM: test RTC wakeup from '%s' suspend\n"; unsigned long now; struct rtc_wkalrm alm; int status; /* this may fail if the RTC hasn't been initialized */ status = rtc_read_time(rtc, &alm.time); if (status < 0) { printk(err_readtime, dev_name(&rtc->dev), status); return; } rtc_tm_to_time(&alm.time, &now); memset(&alm, 0, sizeof alm); rtc_time_to_tm(now + TEST_SUSPEND_SECONDS, &alm.time); alm.enabled = true; status = rtc_set_alarm(rtc, &alm); if (status < 0) { printk(err_wakealarm, dev_name(&rtc->dev), status); return; } if (state == PM_SUSPEND_MEM) { printk(info_test, pm_states[state]); status = pm_suspend(state); if (status == -ENODEV) state = PM_SUSPEND_STANDBY; } if (state == PM_SUSPEND_STANDBY) { printk(info_test, pm_states[state]); status = pm_suspend(state); } if (status < 0) printk(err_suspend, status); /* Some platforms can't detect that the alarm triggered the * wakeup, or (accordingly) disable it after it afterwards. * It's supposed to give oneshot behavior; cope. */ alm.enabled = false; rtc_set_alarm(rtc, &alm); }
static void __init test_wakealarm(struct rtc_device *rtc, suspend_state_t state) { static char err_readtime[] __initdata = KERN_ERR "PM: can't read %s time, err %d\n"; static char err_wakealarm [] __initdata = KERN_ERR "PM: can't set %s wakealarm, err %d\n"; static char err_suspend[] __initdata = KERN_ERR "PM: suspend test failed, error %d\n"; static char info_test[] __initdata = KERN_INFO "PM: test RTC wakeup from '%s' suspend\n"; unsigned long now; struct rtc_wkalrm alm; int status; status = rtc_read_time(rtc, &alm.time); if (status < 0) { printk(err_readtime, dev_name(&rtc->dev), status); return; } rtc_tm_to_time(&alm.time, &now); memset(&alm, 0, sizeof alm); rtc_time_to_tm(now + TEST_SUSPEND_SECONDS, &alm.time); alm.enabled = true; status = rtc_set_alarm(rtc, &alm); if (status < 0) { printk(err_wakealarm, dev_name(&rtc->dev), status); return; } if (state == PM_SUSPEND_MEM) { printk(info_test, pm_states[state]); status = pm_suspend(state); if (status == -ENODEV) state = PM_SUSPEND_STANDBY; } if (state == PM_SUSPEND_STANDBY) { printk(info_test, pm_states[state]); status = pm_suspend(state); } if (status < 0) printk(err_suspend, status); alm.enabled = false; rtc_set_alarm(rtc, &alm); }
void lab_cmd_suspend(int argc,const char** argv) { lab_puts("Ok byebye!!\r\n"); printk("LAB: We are about to \"go down for the count\", as it were. I'll let you know when we wake up.\n"); pm_suspend(PM_SUSPEND_MEM); printk("LAB: Hi. We're awake. I'm going to return you to the main menu now. As a reminder, I own you.\n"); }
/** * store_hibernate - Initiate partition hibernation * @classdev: sysdev class struct * @attr: class device attribute struct * @buf: buffer * @count: buffer size * * Write the stream ID received from the HMC to this file * to trigger hibernating the partition * * Return value: * number of bytes printed to buffer / other on failure **/ static ssize_t store_hibernate(struct sysdev_class *classdev, const char *buf, size_t count) { int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; stream_id = simple_strtoul(buf, NULL, 16); do { rc = pseries_suspend_begin(PM_SUSPEND_MEM); if (rc == -EAGAIN) ssleep(1); } while (rc == -EAGAIN); if (!rc) { stop_topology_update(); rc = pm_suspend(PM_SUSPEND_MEM); start_topology_update(); } stream_id = 0; if (!rc) rc = count; return rc; }
/** * store_hibernate - Initiate partition hibernation * @dev: subsys root device * @attr: device attribute struct * @buf: buffer * @count: buffer size * * Write the stream ID received from the HMC to this file * to trigger hibernating the partition * * Return value: * number of bytes printed to buffer / other on failure **/ static ssize_t store_hibernate(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int rc; if (!capable(CAP_SYS_ADMIN)) return -EPERM; stream_id = simple_strtoul(buf, NULL, 16); do { rc = pseries_suspend_begin(PM_SUSPEND_MEM); if (rc == -EAGAIN) ssleep(1); } while (rc == -EAGAIN); if (!rc) rc = pm_suspend(PM_SUSPEND_MEM); stream_id = 0; if (!rc) rc = count; return rc; }
static void try_to_suspend(struct work_struct *work) { unsigned int initial_count, final_count; if (!pm_get_wakeup_count(&initial_count, true)) { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[P] suspend abort, wakeup event nonzero\n"); htc_print_active_wakeup_sources(); #endif goto out; } mutex_lock(&autosleep_lock); if (!pm_save_wakeup_count(initial_count)) { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[P] suspend abort, events not matched or being processed\n"); #endif mutex_unlock(&autosleep_lock); goto out; } if (autosleep_state == PM_SUSPEND_ON) { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[P] suspend abort, autosleep_state is ON\n"); #endif mutex_unlock(&autosleep_lock); return; } if (autosleep_state >= PM_SUSPEND_MAX) hibernate(); else { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[R] suspend start\n"); #endif pm_suspend(autosleep_state); } mutex_unlock(&autosleep_lock); if (!pm_get_wakeup_count(&final_count, false)) { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[R] resume end\n"); #endif goto out; } if (final_count == initial_count) { #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[P] wakeup occured for an unknown reason, wait HZ/2\n"); #endif schedule_timeout_uninterruptible(HZ / 2); } #ifdef CONFIG_HTC_POWER_DEBUG pr_info("[R] resume end\n"); #endif out: queue_up_suspend_work(); }
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { suspend_state_t state; int error; error = pm_autosleep_lock(); if (error) return error; if (pm_autosleep_state() > PM_SUSPEND_ON) { error = -EBUSY; goto out; } state = decode_state(buf, n); if (state < PM_SUSPEND_MAX) error = pm_suspend(state); else if (state == PM_SUSPEND_MAX) error = hibernate(); else error = -EINVAL; out: pm_autosleep_unlock(); return error ? error : n; }
static void pm_timeout(void *arg) { struct pm_softc *sc = arg; int s, reload; s = splhigh(); sc->idlecnt++; splx(s); DPRINTF(("pm: idlecnt=%d\n", sc->idlecnt)); if (sc->sustime != 0 && sc->idlecnt >= sc->sustime) { #ifdef CONFIG_CONS cons_puts("\nThe system is about to suspend..."); #endif pm_suspend(); } else { reload = 0; if (sc->dimtime != 0 && sc->idlecnt >= sc->dimtime) { pm_lcd_off(); if (sc->sustime != 0) reload = 1; } else reload = 1; if (reload) timer_callout(&sc->timer, 1000, &pm_timeout, sc); } }
static int agent_thread_fn(void *data) { while (1) { wait_event_interruptible(agent_wq, pci_pm_state >= 2); try_to_freeze(); if (signal_pending(current) || pci_pm_state < 2) continue; /* With a preemptible kernel (or SMP), this could race with * a userspace-driven suspend request. It's probably best * to avoid mixing the two with such a configuration (or * else fix it by adding a mutex to state_store that we can * synchronize with). */ wake_from_pci = 1; pm_suspend(pci_pm_state == 3 ? PM_SUSPEND_MEM : PM_SUSPEND_STANDBY); wake_from_pci = 0; } return 0; }
static int pm_sysctl_proc_handler(ctl_table *ctl, int write, struct file *filp, void *buffer, size_t *lenp) { int ret = -EIO; printk("PM: task %s (pid %d) uses deprecated sysctl PM interface\n", current->comm, current->pid); if (write) ret = pm_suspend(PM_SUSPEND_MEM); return ret; }
static int __init rk3288_pm_dbg(void) { #if 1 console_suspend_enabled=0; do{ pm_suspend(PM_SUSPEND_MEM); } while(1); #endif }
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { suspend_state_t state; struct timespec ts_entry, ts_exit; u64 elapsed_msecs64; u32 elapsed_msecs32; int error; error = pm_autosleep_lock(); if (error) return error; if (pm_autosleep_state() > PM_SUSPEND_ON) { error = -EBUSY; goto out; } state = decode_state(buf, n); if (state < PM_SUSPEND_MAX) { /* * We want to prevent system from frequent periodic wake-ups * when sleeping time is less or equival certain interval. * It's done in order to save power in certain cases, one of * the examples is GPS tracking, but not only. */ getnstimeofday(&ts_entry); error = pm_suspend(state); getnstimeofday(&ts_exit); elapsed_msecs64 = timespec_to_ns(&ts_exit) - timespec_to_ns(&ts_entry); do_div(elapsed_msecs64, NSEC_PER_MSEC); elapsed_msecs32 = elapsed_msecs64; if (elapsed_msecs32 <= SBO_SLEEP_MSEC) { if (suspend_short_count == SBO_CNT) suspend_backoff(); else suspend_short_count++; } else { suspend_short_count = 0; } } else if (state == PM_SUSPEND_MAX) error = hibernate(); else error = -EINVAL; out: pm_autosleep_unlock(); return error ? error : n; }
static void try_to_suspend(struct work_struct *work) { unsigned int initial_count, final_count; int error = 0; if (!pm_get_wakeup_count(&initial_count, true)) goto out; mutex_lock(&autosleep_lock); if (!pm_save_wakeup_count(initial_count) || system_state != SYSTEM_RUNNING) { mutex_unlock(&autosleep_lock); goto out; } if (autosleep_state == PM_SUSPEND_ON) { mutex_unlock(&autosleep_lock); return; } if (autosleep_state >= PM_SUSPEND_MAX) hibernate(); else error = pm_suspend(autosleep_state); mutex_unlock(&autosleep_lock); #ifdef CONFIG_SEC_PM if (error) goto out; #endif if (!pm_get_wakeup_count(&final_count, false)) goto out; /* * If the wakeup occured for an unknown reason, wait to prevent the * system from trying to suspend and waking up in a tight loop. */ if (final_count == initial_count) schedule_timeout_uninterruptible(HZ / 2); out: #ifdef CONFIG_SEC_PM if (error) { pr_info("PM: suspend returned(%d)\n", error); schedule_timeout_uninterruptible(HZ / 2); } #endif queue_up_suspend_work(); }
static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n) { #ifdef CONFIG_SUSPEND #ifdef CONFIG_EARLYSUSPEND suspend_state_t state = PM_SUSPEND_ON; #else suspend_state_t state = PM_SUSPEND_STANDBY; #endif const char * const *s; #endif char *p; int len; int error = -EINVAL; if (factory_mode == 0) { p = memchr(buf, '\n', n); len = p ? p - buf : n; /* First, check if we are requested to hibernate */ if (len == 4 && !strncmp(buf, "disk", len)) { error = hibernate(); goto Exit; } #ifdef CONFIG_SUSPEND for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) { if (*s && len == strlen(*s) && !strncmp(buf, *s, len)) { #ifdef CONFIG_EARLYSUSPEND if (state == PM_SUSPEND_ON || valid_state(state)) { error = 0; request_suspend_state(state); break; } #else error = pm_suspend(state); #endif } } #endif Exit: return error ? error : n; } else { return 0; } }
static void rk3288_init_suspend(void) { printk("%s\n",__FUNCTION__); rockchip_suspend_init(); //rkpm_pie_init(); rk3288_suspend_init(); rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); #if 0 console_suspend_enabled=0; do{ pm_suspend(PM_SUSPEND_MEM); } while(1); #endif }
static void da9052_power_button( struct da9052 *da9052 , int value ) { struct da9052_ssc_msg ssc_msg; unsigned int ret; if( system_state != SYSTEM_RUNNING) return; switch (pwron_state){ case PWRON_FROM_RESUME: // Are we waking up from a non power button suspend // and this is the falling edge already? if( !value ) pwron_state = PWRON_FROM_RESUME; else // Skipping falling edge pwron_state = PWRON_FALLING_EDGE; break; case PWRON_FALLING_EDGE: // Suspend on rising edge pm_suspend(PM_SUSPEND_MEM); // Did we wake by a power button press? da9052_lock(da9052); ssc_msg.addr = DA9052_EVENTB_REG; ret = da9052->read(da9052, &ssc_msg); if (ret) { da9052_unlock(da9052); pwron_state = PWRON_FROM_RESUME; return; } da9052_unlock(da9052); if( ssc_msg.data | DA9052_EVENTB_ENONKEY ) pwron_state = PWRON_FROM_SUSPEND; else // Waken by other source pwron_state = PWRON_FROM_RESUME; break; case PWRON_FROM_SUSPEND: // Ignoring raising edge pwron_state = PWRON_FROM_RESUME; break; default: pr_err("power_on_evt_handler: Unitialized state\n"); } }
static void try_to_suspend(struct work_struct *work) { unsigned int initial_count, final_count; if (!pm_get_wakeup_count(&initial_count, true)) goto out; mutex_lock(&autosleep_lock); if (!pm_save_wakeup_count(initial_count)) { mutex_unlock(&autosleep_lock); goto out; } if (autosleep_state == PM_SUSPEND_ON) { mutex_unlock(&autosleep_lock); return; } if (autosleep_state >= PM_SUSPEND_MAX) hibernate(); else pm_suspend(autosleep_state); mutex_unlock(&autosleep_lock); if (!pm_get_wakeup_count(&final_count, false)) goto out; /* * If the wakeup occured for an unknown reason, wait to prevent the * system from trying to suspend and waking up in a tight loop. */ if (final_count == initial_count) schedule_timeout_uninterruptible(HZ / 2); out: queue_up_suspend_work(); }
/* * PM service for other drivers. */ int pm_set_power(int state) { int error; switch (state) { case PWR_ON: error = pm_resume(); break; case PWR_SUSPEND: error = pm_suspend(); break; case PWR_OFF: error = pm_poweroff(); break; case PWR_REBOOT: error = pm_reboot(); break; default: error = EINVAL; } return error; }
static void try_to_suspend(struct work_struct *work) { unsigned int initial_count, final_count; int error = 0; #ifdef CONFIG_PM_SLEEP_HISTORY int i; static unsigned int autosleep_active; static struct wakeup_source *last_ws[4]; struct timespec ts; if (autosleep_active == 0) { autosleep_active = 1; getnstimeofday(&ts); sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_ENTRY, &ts, NULL); } #endif if (!pm_get_wakeup_count(&initial_count, true)) goto out; mutex_lock(&autosleep_lock); if (!pm_save_wakeup_count(initial_count)) { mutex_unlock(&autosleep_lock); goto out; } #ifdef CONFIG_PM_SLEEP_HISTORY memset(last_ws, 0, sizeof(last_ws)); pm_get_last_wakeup_sources(&last_ws[0], sizeof(last_ws)/sizeof(struct wakeup_source *)); autosleep_active = 0; getnstimeofday(&ts); if (last_ws[0]) { sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, &ts, last_ws[0]); for (i = 1; last_ws[i] && i < sizeof(last_ws)/sizeof(struct wakeup_source *); i++) sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, NULL, last_ws[i]); memset(last_ws, 0, sizeof(last_ws)); } else sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, &ts, autosleep_ws); #endif if (autosleep_state == PM_SUSPEND_ON) { mutex_unlock(&autosleep_lock); return; } if (autosleep_state >= PM_SUSPEND_MAX) hibernate(); else error = pm_suspend(autosleep_state); mutex_unlock(&autosleep_lock); #ifdef CONFIG_PM_SLEEP_HISTORY if (autosleep_active == 0) { autosleep_active = 1; getnstimeofday(&ts); sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_ENTRY, &ts, NULL); } if (error) goto out; if (!pm_get_wakeup_count(&final_count, false)) { __pm_wakeup_event(autosleep_ws, AUTOSLEEP_SUSPEND_BLOCK_TIME); goto out; } #else if (error) goto out; if (!pm_get_wakeup_count(&final_count, false)) { __pm_wakeup_event(autosleep_ws, AUTOSLEEP_SUSPEND_BLOCK_TIME); goto out; } #endif /* * If the wakeup occured for an unknown reason, wait to prevent the * system from trying to suspend and waking up in a tight loop. */ if (final_count == initial_count) schedule_timeout_uninterruptible(HZ / 2); out: #ifdef CONFIG_PM_SLEEP_HISTORY memset(last_ws, 0, sizeof(last_ws)); pm_get_last_wakeup_sources(&last_ws[0], sizeof(last_ws)/sizeof(struct wakeup_source *)); if (autosleep_state == PM_SUSPEND_ON) { autosleep_active = 0; getnstimeofday(&ts); if (last_ws[0]) { sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, &ts, last_ws[0]); for (i = 1; last_ws[i] && i < sizeof(last_ws)/sizeof(struct wakeup_source *); i++) sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, NULL, last_ws[i]); memset(last_ws, 0, sizeof(last_ws)); } else sleep_history_marker(SLEEP_HISTORY_AUTOSLEEP_EXIT, &ts, autosleep_ws); } #endif /* * If the device failed to suspend, wait to prevent the * system from trying to suspend and waking up in a tight loop. */ if (error) { pr_info("PM: suspend returned(%d)\n", error); schedule_timeout_uninterruptible(HZ / 2); } queue_up_suspend_work(); }
/* * PM event notification. */ void pm_notify(int event) { struct pm_softc *sc = pm_softc; int s; if (event == PME_USER_ACTIVITY) { /* * Reload suspend timer for user activity. */ s = splhigh(); sc->idlecnt = 0; splx(s); if (!sc->lcd_on) pm_lcd_on(); return; } DPRINTF(("pm: notify %d\n", event)); if (sc->powtask != TASK_NULL) { /* * Power server exists. */ switch (event) { case PME_PWRBTN_PRESS: case PME_SLPBTN_PRESS: case PME_LOW_BATTERY: case PME_LCD_CLOSE: /* * Post an exception to the power server. * Then, the power server will query PM event. */ sc->lastevt = event; DPRINTF(("pm: post %d\n", event)); exception_post(sc->powtask, SIGPWR); break; case PME_LCD_OPEN: sc->lastevt = PME_NO_EVENT; pm_lcd_on(); break; } } else { /* * No power server. * Map power event to default action. */ switch (event) { case PME_PWRBTN_PRESS: pm_poweroff(); break; case PME_SLPBTN_PRESS: case PME_LOW_BATTERY: pm_suspend(); break; case PME_LCD_OPEN: pm_lcd_on(); break; case PME_LCD_CLOSE: pm_lcd_off(); break; } } }
int main(int argc, char **argv) { int c; char display_name[MAXNAMELEN + 9] = "DISPLAY="; char xauthority[MAXPATHLEN + 12] = "XAUTHORITY="; struct passwd *pw; (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGINT, SIG_IGN); (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTSTP, SIG_IGN); (void) signal(SIGTTIN, SIG_IGN); (void) signal(SIGTTOU, SIG_IGN); /* * If suspend is invoked from a daemon (case 1 above), it * will not have a working stdin, stdout and stderr. We need * these to print proper error messages and possibly get user * input. We attach them to console and hope that attachment * works. */ if (ttyname(0) == NULL) { no_tty = 1; (void) dup2(open("/dev/console", O_RDONLY), 0); (void) dup2(open("/dev/console", O_WRONLY), 1); (void) dup2(open("/dev/console", O_WRONLY), 2); } while ((c = getopt(argc, argv, "fnxhtd:")) != EOF) { switch (c) { case 'f': /* * Force machine to poweroff if * suspend fails */ flags |= FORCE; break; case 'n': /* No warning popups - Obsolete */ flags |= NO_WARN; break; case 'x': /* Don't try to screenlock */ flags |= NO_XLOCK; break; case 'h': /* Do a shutdown instead of suspend */ flags |= SHUTDOWN; break; case 'd': /* Needswork */ /* Set the DISPLAY value in the environment */ if (strlen(optarg) >= MAXNAMELEN) { (void) printf(gettext("Error: " "display name is too long.\n")); return (1); } (void) strcat(display_name, optarg); if (putenv(display_name) != 0) { (void) printf(gettext("Error: " "unable to set DISPLAY " "environment variable.\n")); return (1); } break; case 't': /* Test, don't actually do any operation */ flags |= TEST; break; default: (void) printf(gettext("USAGE: suspend " "[-fnxh] [-d <display>]\n")); return (1); } } /* * The action of pressing power key and power button on a MOU-3 machine * causes suspend being invoked with SYSSUSPENDDODEFAULT * enviromental variable set - indicating the default action is machine * dependent: for MOU-3 type machine, "LowPower" mode is the default, * for all the rest, "Suspend" is the default. Existing suspend * flags works the same. */ if (getenv("SYSSUSPENDDODEFAULT")) if (is_mou3()) flags |= LOWPOWER; if ((flags & FORCE) && (flags & LOWPOWER)) flags &= ~LOWPOWER; /* * Flag "-h" overrides flag "-f". */ if ((flags & SHUTDOWN) && (flags & FORCE)) flags &= ~(FORCE | LOWPOWER); if (flags & FORCE) flags |= NO_WARN; /* * Check initally if the user has the authorizations to * do either a suspend or shutdown. pm_suspend() will also * make this test, so we could defer till then, but if we * do it now, we at least prevent a lot of unneeded setup. */ pw = getpwuid(getuid()); (void) strncpy(user, pw->pw_name, NMAX); if ((flags & (FORCE|SHUTDOWN)) && (chkauthattr(AUTHNAME_SHUTDOWN, pw->pw_name) != 1)) { (void) printf(gettext("User does not have correct " "authorizations to shutdown the machine.\n")); exit(1); } if (!(flags & SHUTDOWN) && (chkauthattr(AUTHNAME_SUSPEND, pw->pw_name) != 1)) { (void) printf(gettext("User does not have correct " "authorizations to suspend.\n")); exit(1); } /* * If we are only shutting down, there isn't much to do, just * call pm_poweroff(), and let it do all the work. */ if (flags & SHUTDOWN) { /* * pm_poweroff either powers off or exits, * so there is no return. */ if (flags & TEST) { (void) printf("TEST: This machine would have " "powered off\n"); exit(1); } else { pm_poweroff(); } /* NOTREACHED */ } /* * If XAUTHORITY environment variable is not set, try to set * one up. */ if (getenv("XAUTHORITY") == NULL) (void) putenv(get_xauthority(xauthority)); /* * In case of "suspend" being called from daemon "powerd", * signal SIGALRM is blocked so use "sigset()" instead of "signal()". */ (void) sigset(SIGALRM, alarm_handler); /* Call the "suspend" function to do the last of the work */ pm_suspend(); if (refresh_dt() == -1) { (void) printf("%s: Failed to refresh screen.\n", argv[0]); return (1); } return (0); }