Exemple #1
0
static void
apm_standby(struct apm_softc *sc)
{
	int error;

	if (sc->sc_power_state == PWR_STANDBY) {
#ifdef APMDEBUG
		aprint_debug_dev(sc->sc_dev,
		    "apm_standby: already standing by?\n");
#endif
		return;
	}
	sc->sc_power_state = PWR_STANDBY;

	if (!(sc->sc_hwflags & APM_F_DONT_RUN_HOOKS)) {
		pmf_system_suspend(PMF_Q_NONE);
		apm_spl = splhigh();
	}
	error = (*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS,
	    APM_SYS_STANDBY);
	if (error)
		apm_resume(sc, 0, 0);
	else
		apm_resume(sc, APM_SYS_STANDBY_RESUME, 0);
}
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 #3
0
static void
apm_event_handle(struct apm_softc *sc, u_int event_code, u_int event_info)
{
	int error;
	const char *code;
	struct apm_power_info pi;

	switch (event_code) {
	case APM_USER_STANDBY_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: user standby request\n"));
		if (apm_do_standby) {
			if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
				apm_userstandbys++;
			apm_op_inprog++;
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		} else {
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED);
			/* in case BIOS hates being spurned */
			(*sc->sc_ops->aa_enable)(sc->sc_cookie, 1);
		}
		break;

	case APM_STANDBY_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby request\n"));
		if (apm_op_inprog) {
			DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
			    ("damn fool BIOS did not wait for answer\n"));
			/* just give up the fight */
			apm_damn_fool_bios = 1;
		}
		if (apm_do_standby) {
			if (apm_op_inprog == 0 &&
			    apm_record_event(sc, event_code))
				apm_standbys++;
			apm_op_inprog++;
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		} else {
			(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
			    APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED);
			/* in case BIOS hates being spurned */
			(*sc->sc_ops->aa_enable)(sc->sc_cookie, 1);
		}
		break;

	case APM_USER_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: user suspend request\n"));
		if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
			apm_suspends++;
		apm_op_inprog++;
		(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
		    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		break;

	case APM_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system suspend request\n"));
		if (apm_op_inprog) {
			DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM,
			    ("damn fool BIOS did not wait for answer\n"));
			/* just give up the fight */
			apm_damn_fool_bios = 1;
		}
		if (apm_op_inprog == 0 && apm_record_event(sc, event_code))
			apm_suspends++;
		apm_op_inprog++;
		(void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie,
		    APM_DEV_ALLDEVS, APM_LASTREQ_INPROG);
		break;

	case APM_POWER_CHANGE:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: power status change\n"));
		error = (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi);
#ifdef APM_POWER_PRINT
		/* only print if nobody is catching events. */
		if (error == 0 &&
		    (sc->sc_flags & (SCFLAG_OREAD|SCFLAG_OWRITE)) == 0)
			apm_power_print(sc, &pi);
#else
		__USE(error);
#endif
		apm_record_event(sc, event_code);
		break;

	case APM_NORMAL_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: resume system\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_CRIT_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: critical resume system"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_SYS_STANDBY_RESUME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby resume\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_UPDATE_TIME:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: update time\n"));
		apm_resume(sc, event_code, event_info);
		break;

	case APM_CRIT_SUSPEND_REQ:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: critical system suspend\n"));
		apm_record_event(sc, event_code);
		apm_suspend(sc);
		break;

	case APM_BATTERY_LOW:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: battery low\n"));
		apm_battlow++;
		apm_record_event(sc, event_code);
		break;

	case APM_CAP_CHANGE:
		DPRINTF(APMDEBUG_EVENTS, ("apmev: capability change\n"));
		if (apm_minver < 2) {
			DPRINTF(APMDEBUG_EVENTS, ("apm: unexpected event\n"));
		} else {
			u_int numbatts, capflags;
			(*sc->sc_ops->aa_get_capabilities)(sc->sc_cookie,
			    &numbatts, &capflags);
			(*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi);
		}
		break;

	default:
		switch (event_code >> 8) {
			case 0:
				code = "reserved system";
				break;
			case 1:
				code = "reserved device";
				break;
			case 2:
				code = "OEM defined";
				break;
			default:
				code = "reserved";
				break;
		}
		printf("APM: %s event code %x\n", code, event_code);
	}
}
Exemple #4
0
int
apm_handle_event(struct apm_softc *sc, struct apmregs *regs)
{
	struct apmregs nregs;
	int ret = 0;

	switch (regs->bx) {
	case APM_NOEVENT:
		ret++;
		break;

	case APM_USER_STANDBY_REQ:
		if (apm_resumes || apm_op_inprog)
			break;
		DPRINTF(("user wants STANDBY--fat chance\n"));
		apm_op_inprog++;
		if (apm_record_event(sc, regs->bx)) {
			DPRINTF(("standby ourselves\n"));
			apm_userstandbys++;
		}
		break;
	case APM_STANDBY_REQ:
		if (apm_resumes || apm_op_inprog)
			break;
		DPRINTF(("standby requested\n"));
		if (apm_standbys || apm_suspends) {
			DPRINTF(("premature standby\n"));
			apm_error++;
			ret++;
		}
		apm_op_inprog++;
		if (apm_record_event(sc, regs->bx)) {
			DPRINTF(("standby ourselves\n"));
			apm_standbys++;
		}
		break;
	case APM_USER_SUSPEND_REQ:
		if (apm_resumes || apm_op_inprog)
			break;
		DPRINTF(("user wants suspend--fat chance!\n"));
		apm_op_inprog++;
		if (apm_record_event(sc, regs->bx)) {
			DPRINTF(("suspend ourselves\n"));
			apm_suspends++;
		}
		break;
	case APM_SUSPEND_REQ:
		if (apm_resumes || apm_op_inprog)
			break;
		DPRINTF(("suspend requested\n"));
		if (apm_standbys || apm_suspends) {
			DPRINTF(("premature suspend\n"));
			apm_error++;
			ret++;
		}
		apm_op_inprog++;
		if (apm_record_event(sc, regs->bx)) {
			DPRINTF(("suspend ourselves\n"));
			apm_suspends++;
		}
		break;
	case APM_POWER_CHANGE:
		DPRINTF(("power status change\n"));
		apm_get_powstat(&nregs);
		apm_record_event(sc, regs->bx);
		break;
	case APM_NORMAL_RESUME:
		DPRINTF(("system resumed\n"));
		apm_resume(sc, regs);
		break;
	case APM_CRIT_RESUME:
		DPRINTF(("system resumed without us!\n"));
		apm_resume(sc, regs);
		break;
	case APM_SYS_STANDBY_RESUME:
		DPRINTF(("system standby resume\n"));
		apm_resume(sc, regs);
		break;
	case APM_UPDATE_TIME:
		DPRINTF(("update time, please\n"));
		inittodr(time_second);
		apm_record_event(sc, regs->bx);
		break;
	case APM_CRIT_SUSPEND_REQ:
		DPRINTF(("suspend required immediately\n"));
		apm_record_event(sc, regs->bx);
		apm_suspend(APM_SYS_SUSPEND);
		break;
	case APM_BATTERY_LOW:
		DPRINTF(("Battery low!\n"));
		apm_battlow++;
		apm_record_event(sc, regs->bx);
		break;
	case APM_CAPABILITY_CHANGE:
		DPRINTF(("capability change\n"));
		if (apm_minver < 2) {
			DPRINTF(("adult event\n"));
		} else {
			if (apmcall(APM_GET_CAPABILITIES, APM_DEV_APM_BIOS,
			    &nregs) != 0) {
				apm_perror("get capabilities", &nregs);
			} else {
				apm_get_powstat(&nregs);
			}
		}
		break;
	default: {
#ifdef APMDEBUG
		char *p;
		switch (regs->bx >> 8) {
		case 0:	p = "reserved system";	break;
		case 1:	p = "reserved device";	break;
		case 2:	p = "OEM defined";	break;
		default:p = "reserved";		break;
		}
#endif
		DPRINTF(("apm_handle_event: %s event, code %d\n", p, regs->bx));
	    }
	}
	return ret;
}