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 apmclose(dev_t dev, int flag, int mode, struct lwp *l) { struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev)); int ctl = APM(dev); DPRINTF(APMDEBUG_DEVICE, ("apmclose: pid %d flag %x mode %x\n", l->l_proc->p_pid, flag, mode)); APM_LOCK(sc); switch (ctl) { case APM_CTL: sc->sc_flags &= ~SCFLAG_OWRITE; break; case APM_NORMAL: sc->sc_flags &= ~SCFLAG_OREAD; break; } if ((sc->sc_flags & SCFLAG_OPEN) == 0) { sc->sc_event_count = 0; sc->sc_event_ptr = 0; } APM_UNLOCK(sc); return 0; }
static void filt_apmrdetach(struct knote *kn) { struct apm_softc *sc = kn->kn_hook; APM_LOCK(sc); SLIST_REMOVE(&sc->sc_rsel.sel_klist, kn, knote, kn_selnext); APM_UNLOCK(sc); }
void apm_thread(void *arg) { struct apm_softc *apmsc = arg; /* * Loop forever, doing a periodic check for APM events. */ for (;;) { APM_LOCK(apmsc); apm_periodic_check(apmsc); APM_UNLOCK(apmsc); (void) tsleep(apmsc, PWAIT, "apmev", (8 * hz) / 7); } }
int apmpoll(dev_t dev, int events, struct lwp *l) { struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev)); int revents = 0; APM_LOCK(sc); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_event_count) revents |= events & (POLLIN | POLLRDNORM); else selrecord(l, &sc->sc_rsel); } APM_UNLOCK(sc); return (revents); }
int apmopen(dev_t dev, int flag, int mode, struct lwp *l) { int ctl = APM(dev); int error = 0; struct apm_softc *sc; sc = device_lookup_private(&apm_cd, APMUNIT(dev)); if (!sc) return ENXIO; if (!apm_inited) return ENXIO; DPRINTF(APMDEBUG_DEVICE, ("apmopen: pid %d flag %x mode %x\n", l->l_proc->p_pid, flag, mode)); APM_LOCK(sc); switch (ctl) { case APM_CTL: if (!(flag & FWRITE)) { error = EINVAL; break; } if (sc->sc_flags & SCFLAG_OWRITE) { error = EBUSY; break; } sc->sc_flags |= SCFLAG_OWRITE; break; case APM_NORMAL: if (!(flag & FREAD) || (flag & FWRITE)) { error = EINVAL; break; } sc->sc_flags |= SCFLAG_OREAD; break; default: error = ENXIO; break; } APM_UNLOCK(sc); return (error); }
int apmkqfilter(dev_t dev, struct knote *kn) { struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev)); struct klist *klist; switch (kn->kn_filter) { case EVFILT_READ: klist = &sc->sc_rsel.sel_klist; kn->kn_fop = &apmread_filtops; break; default: return (EINVAL); } kn->kn_hook = sc; APM_LOCK(sc); SLIST_INSERT_HEAD(klist, kn, kn_selnext); APM_UNLOCK(sc); return (0); }
int apmioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) { struct apm_softc *sc = device_lookup_private(&apm_cd, APMUNIT(dev)); struct apm_power_info *powerp; struct apm_event_info *evp; #if 0 struct apm_ctl *actl; #endif int i, error = 0; int batt_flags; struct apm_ctl *actl; APM_LOCK(sc); switch (cmd) { case APM_IOC_STANDBY: if (!apm_do_standby) { error = EOPNOTSUPP; break; } if ((flag & FWRITE) == 0) { error = EBADF; break; } apm_userstandbys++; break; case APM_IOC_DEV_CTL: actl = (struct apm_ctl *)data; if ((flag & FWRITE) == 0) { error = EBADF; break; } #if 0 apm_get_powstate(actl->dev); /* XXX */ #endif error = (*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, actl->dev, actl->mode); apm_suspends++; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) { error = EBADF; break; } apm_suspends++; break; case APM_IOC_NEXTEVENT: if (!sc->sc_event_count) error = EAGAIN; else { evp = (struct apm_event_info *)data; i = sc->sc_event_ptr + APM_NEVENTS - sc->sc_event_count; i %= APM_NEVENTS; *evp = sc->sc_event_list[i]; sc->sc_event_count--; } break; case OAPM_IOC_GETPOWER: case APM_IOC_GETPOWER: powerp = (struct apm_power_info *)data; if ((error = (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, powerp)) != 0) { apm_perror("ioctl get power status", error); error = EIO; break; } switch (apm_minver) { case 0: break; case 1: default: batt_flags = powerp->battery_flags; powerp->battery_state = APM_BATT_UNKNOWN; if (batt_flags & APM_BATT_FLAG_HIGH) powerp->battery_state = APM_BATT_HIGH; else if (batt_flags & APM_BATT_FLAG_LOW) powerp->battery_state = APM_BATT_LOW; else if (batt_flags & APM_BATT_FLAG_CRITICAL) powerp->battery_state = APM_BATT_CRITICAL; else if (batt_flags & APM_BATT_FLAG_CHARGING) powerp->battery_state = APM_BATT_CHARGING; else if (batt_flags & APM_BATT_FLAG_NO_SYSTEM_BATTERY) powerp->battery_state = APM_BATT_ABSENT; break; } break; default: error = ENOTTY; } APM_UNLOCK(sc); return (error); }