void
apm_thread(void *v)
{
	struct pxa2x0_apm_softc *sc = v;
	u_int	type;

	for (;;) {
		APM_LOCK(sc);

		while (1) {
			if (apm_get_event(sc, &type) != 0)
				break;
			if (apm_handle_event(sc, type) != 0)
				break;
		}
		if (apm_suspends || apm_userstandbys /* || apm_battlow*/) {
			apm_suspend(sc);
			apm_resume(sc);
		}
		apm_battlow = apm_suspends = apm_userstandbys = 0;

		APM_UNLOCK(sc);
		tsleep(&lbolt, PWAIT, "apmev", 0);
	}
}
Exemple #2
0
int
apm_periodic_check(struct apm_softc *sc)
{
	struct apmregs regs;
	int ret = 0;

	if (apm_op_inprog)
		apm_set_powstate(APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);

	while (1) {
		if (apm_get_event(&regs) != 0) {
			/* i think some bioses combine the error codes */
			if (!(APM_ERR_CODE(&regs) & APM_ERR_NOEVENTS))
				apm_perror("get event", &regs);
			break;
		}

		/* If the APM BIOS tells us to suspend, don't do it twice */
		if (regs.bx == APM_SUSPEND_REQ)
			apm_lidclose = 0;
		if (apm_handle_event(sc, &regs))
			break;
	}

	if (apm_error || APM_ERR_CODE(&regs) == APM_ERR_NOTCONN)
		ret = -1;

	if (apm_lidclose) {
		apm_lidclose = 0;
		/* Fake a suspend request */
		regs.bx = APM_SUSPEND_REQ;
		apm_handle_event(sc, &regs);
	}
	if (apm_suspends /*|| (apm_battlow && apm_userstandbys)*/) {
		apm_op_inprog = 0;
		apm_suspend(APM_SYS_SUSPEND);
	} else if (apm_standbys || apm_userstandbys) {
		apm_op_inprog = 0;
		apm_suspend(APM_SYS_STANDBY);
	}
	apm_suspends = apm_standbys = apm_battlow = apm_userstandbys = 0;
	apm_error = 0;

	if (apm_resumes)
		apm_resumes--;
	return (ret);
}