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); } }
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(®s) != 0) { /* i think some bioses combine the error codes */ if (!(APM_ERR_CODE(®s) & APM_ERR_NOEVENTS)) apm_perror("get event", ®s); 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, ®s)) break; } if (apm_error || APM_ERR_CODE(®s) == APM_ERR_NOTCONN) ret = -1; if (apm_lidclose) { apm_lidclose = 0; /* Fake a suspend request */ regs.bx = APM_SUSPEND_REQ; apm_handle_event(sc, ®s); } 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); }