コード例 #1
0
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);
}
コード例 #2
0
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);
}
コード例 #3
0
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");
}
コード例 #4
0
ファイル: suspend.c プロジェクト: swrite/ali_kernel
/**
 * 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;
}
コード例 #5
0
ファイル: suspend.c プロジェクト: 08opt/linux
/**
 * 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;
}
コード例 #6
0
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();
}
コード例 #7
0
ファイル: main.c プロジェクト: qkdang/m462
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;
}
コード例 #8
0
ファイル: pm.c プロジェクト: AdamRLukaitis/prex
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);
    }
}
コード例 #9
0
ファイル: suspend.c プロジェクト: 0-T-0/ps4-linux
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;
}
コード例 #10
0
ファイル: pm.c プロジェクト: sarnobat/knoppix
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;
}
コード例 #11
0
static int  __init rk3288_pm_dbg(void)
{
#if 1    
        console_suspend_enabled=0;
        do{
            pm_suspend(PM_SUSPEND_MEM);
        }
        while(1);
        
#endif

}
コード例 #12
0
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;
}
コード例 #13
0
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();
}
コード例 #14
0
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;
	}
}
コード例 #15
0
ファイル: rk3288.c プロジェクト: Astralix/kernel
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
}
コード例 #16
0
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");
	}
}
コード例 #17
0
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();
}
コード例 #18
0
ファイル: pm.c プロジェクト: AdamRLukaitis/prex
/*
 * 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;
}
コード例 #19
0
ファイル: autosleep.c プロジェクト: hallometa/Gear_S_Kernel
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();
}
コード例 #20
0
ファイル: pm.c プロジェクト: AdamRLukaitis/prex
/*
 * 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;
        }
    }
}
コード例 #21
0
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);
}