diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-06-30 01:09:48 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2006-06-30 01:09:48 +0000 |
commit | ebe8d416e75b4cbceb89cc2f924f2a5c42165e5a (patch) | |
tree | 8d79b980763dcbf6df4cfd57ffdc30386af986dd /sys/dev | |
parent | 7d9a8fed4bad8e4c27534848faa648237caafb9d (diff) |
Added offset argument for acpi read/write pmreg routines (new GPE code)
ok marco@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpi/acpi.c | 153 | ||||
-rw-r--r-- | sys/dev/acpi/acpivar.h | 4 |
2 files changed, 89 insertions, 68 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index d1acf1e89ab..b75deb613af 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.51 2006/05/31 10:34:54 todd Exp $ */ +/* $OpenBSD: acpi.c,v 1.52 2006/06/30 01:09:47 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -55,8 +55,8 @@ int acpi_print(void *, const char *); void acpi_map_pmregs(struct acpi_softc *); void acpi_unmap_pmregs(struct acpi_softc *); -int acpi_read_pmreg(struct acpi_softc *, int); -void acpi_write_pmreg(struct acpi_softc *, int, int); +int acpi_read_pmreg(struct acpi_softc *, int, int); +void acpi_write_pmreg(struct acpi_softc *, int, int, int); void acpi_foundpss(struct aml_node *, void *); void acpi_foundhid(struct aml_node *, void *); @@ -78,6 +78,9 @@ int acpi_filtread(struct knote *, long); #define ACPI_LOCK(sc) #define ACPI_UNLOCK(sc) +#define GPE0_LEN(sc) (sc->sc_pmregs[ACPIREG_GPE0_EN].size >> 3) +#define GPE1_LEN(sc) (sc->sc_pmregs[ACPIREG_GPE1_EN].size >> 3) + /* XXX move this into dsdt softc at some point */ extern struct aml_node aml_root; @@ -379,26 +382,28 @@ acpi_unmap_pmregs(struct acpi_softc *sc) /* Read from power management register */ int -acpi_read_pmreg(struct acpi_softc *sc, int reg) +acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) { bus_space_handle_t ioh; bus_size_t size; int regval; /* Special cases: 1A/1B blocks can be OR'ed together */ - if (reg == ACPIREG_PM1_EN) { - return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN) | - acpi_read_pmreg(sc, ACPIREG_PM1B_EN)); - } - else if (reg == ACPIREG_PM1_STS) { - return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS) | - acpi_read_pmreg(sc, ACPIREG_PM1B_STS)); - } - else if (reg == ACPIREG_PM1_CNT) { - return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT) | - acpi_read_pmreg(sc, ACPIREG_PM1B_CNT)); + switch (reg) { + case ACPIREG_PM1_EN: + return (acpi_read_pmreg(sc, ACPIREG_PM1A_EN, offset) | + acpi_read_pmreg(sc, ACPIREG_PM1B_EN, offset)); + case ACPIREG_PM1_STS: + return (acpi_read_pmreg(sc, ACPIREG_PM1A_STS, offset) | + acpi_read_pmreg(sc, ACPIREG_PM1B_STS, offset)); + case ACPIREG_PM1_CNT: + return (acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, offset) | + acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, offset)); + case ACPIREG_GPE_STS: + case ACPIREG_GPE_EN: + break; } - + if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) return (0); @@ -410,41 +415,43 @@ acpi_read_pmreg(struct acpi_softc *sc, int reg) switch (size) { case 1: - regval = bus_space_read_1(sc->sc_iot, ioh, 0); + regval = bus_space_read_1(sc->sc_iot, ioh, offset); break; case 2: - regval = bus_space_read_2(sc->sc_iot, ioh, 0); + regval = bus_space_read_2(sc->sc_iot, ioh, offset); break; case 4: - regval = bus_space_read_4(sc->sc_iot, ioh, 0); + regval = bus_space_read_4(sc->sc_iot, ioh, offset); break; } - dnprintf(30, "acpi_readpm: %s = %.4x %x\n", + dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", sc->sc_pmregs[reg].name, - sc->sc_pmregs[reg].addr, regval); + sc->sc_pmregs[reg].addr, offset, regval); return (regval); } /* Write to power management register */ void -acpi_write_pmreg(struct acpi_softc *sc, int reg, int regval) +acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) { bus_space_handle_t ioh; bus_size_t size; /* Special cases: 1A/1B blocks can be written with same value */ - if (reg == ACPIREG_PM1_EN) { - acpi_write_pmreg(sc, ACPIREG_PM1A_EN, regval); - acpi_write_pmreg(sc, ACPIREG_PM1B_EN, regval); - } - else if (reg == ACPIREG_PM1_STS) { - acpi_write_pmreg(sc, ACPIREG_PM1A_STS, regval); - acpi_write_pmreg(sc, ACPIREG_PM1B_STS, regval); - } - else if (reg == ACPIREG_PM1_CNT) { - acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, regval); - acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, regval); + switch (reg) { + case ACPIREG_PM1_EN: + acpi_write_pmreg(sc, ACPIREG_PM1A_EN, offset, regval); + acpi_write_pmreg(sc, ACPIREG_PM1B_EN, offset, regval); + break; + case ACPIREG_PM1_STS: + acpi_write_pmreg(sc, ACPIREG_PM1A_STS, offset, regval); + acpi_write_pmreg(sc, ACPIREG_PM1B_STS, offset, regval); + break; + case ACPIREG_PM1_CNT: + acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, offset, regval); + acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, offset, regval); + break; } /* All special case return here */ @@ -457,19 +464,20 @@ acpi_write_pmreg(struct acpi_softc *sc, int reg, int regval) size = 4; switch (size) { case 1: - bus_space_write_1(sc->sc_iot, ioh, 0, regval); + bus_space_write_1(sc->sc_iot, ioh, offset, regval); break; case 2: - bus_space_write_2(sc->sc_iot, ioh, 0, regval); + bus_space_write_2(sc->sc_iot, ioh, offset, regval); break; case 4: - bus_space_write_4(sc->sc_iot, ioh, 0, regval); + bus_space_write_4(sc->sc_iot, ioh, offset, regval); break; } - dnprintf(30, "acpi_writepm: %s = %.4x %x\n", + dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, + offset, regval); } @@ -754,14 +762,14 @@ acpi_attach(struct device *parent, struct device *self, void *aux) #ifdef ACPI_ENABLE int idx; - acpi_write_pmreg(sc, ACPIREG_SMICMD, sc->sc_fadt->acpi_enable); + acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable); idx = 0; do { if (idx++ > ACPIEN_RETRIES) { printf(": can't enable ACPI\n"); return; } - } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT) & ACPI_PM1_SCI_EN)); + } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN)); #endif acpi_attach_machdep(sc); @@ -998,13 +1006,13 @@ acpi_interrupt(void *arg) ec = 0; processed = 0; - sts = acpi_read_pmreg(sc, ACPIREG_GPE0_STS); - en = acpi_read_pmreg(sc, ACPIREG_GPE0_EN); + sts = acpi_read_pmreg(sc, ACPIREG_GPE0_STS, 0); + en = acpi_read_pmreg(sc, ACPIREG_GPE0_EN, 0); if (sts & en) { dnprintf(10, "GPE interrupt: %.8x %.8x %.8x\n", sts, en, sts & en); /* disable interrupts until handled */ - acpi_write_pmreg(sc, ACPIREG_GPE0_EN, en & ~sts); + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0, en & ~sts); sc->sc_gpe_sts = sts; sc->sc_gpe_en = en; @@ -1016,13 +1024,13 @@ acpi_interrupt(void *arg) } } - sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS); - en = acpi_read_pmreg(sc, ACPIREG_PM1_EN); + sts = acpi_read_pmreg(sc, ACPIREG_PM1_STS, 0); + en = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); if (sts & en) { dnprintf(10,"GEN interrupt: %.4x\n", sts & en); - acpi_write_pmreg(sc, ACPIREG_PM1_EN, en & ~sts); - acpi_write_pmreg(sc, ACPIREG_PM1_STS, en); - acpi_write_pmreg(sc, ACPIREG_PM1_EN, en); + acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en & ~sts); + acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, en); + acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, en); if (sts & ACPI_PM1_PWRBTN_STS) sc->sc_powerbtn = 1; if (sts & ACPI_PM1_SLPBTN_STS) @@ -1035,11 +1043,11 @@ acpi_interrupt(void *arg) processed = 1; sts = sc->sc_ec_gpemask; - en = acpi_read_pmreg(sc, ACPIREG_GPE0_EN); + en = acpi_read_pmreg(sc, ACPIREG_GPE0_EN, 0); /* enable SCI once again */ - acpi_write_pmreg(sc, ACPIREG_GPE0_STS, sts); - acpi_write_pmreg(sc, ACPIREG_GPE0_EN, en | sts); + acpi_write_pmreg(sc, ACPIREG_GPE0_STS, 0, sts); + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0, en | sts); } if (processed) { @@ -1086,8 +1094,8 @@ acpi_enable_gpe(struct acpi_softc *sc, u_int32_t gpemask) { u_int32_t mask; dnprintf(10, "acpi_enable_gpe: mask 0x%08x\n", gpemask); - mask = acpi_read_pmreg(sc, ACPIREG_GPE0_EN); - acpi_write_pmreg(sc, ACPIREG_GPE0_EN, mask | gpemask); + mask = acpi_read_pmreg(sc, ACPIREG_GPE0_EN, 0); + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0, mask | gpemask); dnprintf(10, "acpi_enable_gpe: GPE 0x%08x\n", mask | gpemask); } @@ -1181,28 +1189,28 @@ acpi_enter_sleep_state(struct acpi_softc *sc, int state) disable_intr(); /* Clear WAK_STS bit */ - acpi_write_pmreg(sc, ACPIREG_PM1_STS, ACPI_PM1_WAK_STS); + acpi_write_pmreg(sc, ACPIREG_PM1_STS, 0, ACPI_PM1_WAK_STS); /* Write SLP_TYPx values */ - rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT); - regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT); + rega = acpi_read_pmreg(sc, ACPIREG_PM1A_CNT, 0); + regb = acpi_read_pmreg(sc, ACPIREG_PM1B_CNT, 0); rega &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); regb &= ~(ACPI_PM1_SLP_TYPX_MASK | ACPI_PM1_SLP_EN); rega |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typa); regb |= ACPI_PM1_SLP_TYPX(sc->sc_sleeptype[state].slp_typb); - acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, rega); - acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, regb); + acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); + acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); /* Set SLP_EN bit */ rega |= ACPI_PM1_SLP_EN; regb |= ACPI_PM1_SLP_EN; - acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, rega); - acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, regb); + acpi_write_pmreg(sc, ACPIREG_PM1A_CNT, 0, rega); + acpi_write_pmreg(sc, ACPIREG_PM1B_CNT, 0, regb); /* Loop on WAK_STS */ for (retries = 1000; retries > 0; retries--) { - rega = acpi_read_pmreg(sc, ACPIREG_PM1A_STS); - regb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS); + rega = acpi_read_pmreg(sc, ACPIREG_PM1A_STS, 0); + regb = acpi_read_pmreg(sc, ACPIREG_PM1B_STS, 0); if (rega & ACPI_PM1_WAK_STS || regb & ACPI_PM1_WAK_STS) break; @@ -1414,18 +1422,29 @@ acpi_isr_thread(void *arg) sc->sc_wakeup = 1; /* Enable Sleep/Power buttons if they exist */ - flag = acpi_read_pmreg(sc, ACPIREG_PM1_EN); + flag = acpi_read_pmreg(sc, ACPIREG_PM1_EN, 0); if (!(sc->sc_fadt->flags & FADT_PWR_BUTTON)) { flag |= ACPI_PM1_PWRBTN_EN; } if (!(sc->sc_fadt->flags & FADT_SLP_BUTTON)) { flag |= ACPI_PM1_SLPBTN_EN; } - acpi_write_pmreg(sc, ACPIREG_PM1_EN, flag); + acpi_write_pmreg(sc, ACPIREG_PM1_EN, 0, flag); /* Clear GPE interrupts */ - acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0); - acpi_write_pmreg(sc, ACPIREG_GPE0_STS, -1); +#if 0 + for (idx=0; idx<GPE0_LEN(sc); idx++) { + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, idx, 0); + acpi_write_pmreg(sc, ACPIREG_GPE0_STS, idx, -1); + } + for (idx=0; idx<GPE1_LEN(sc); idx++) { + acpi_write_pmreg(sc, ACPIREG_GPE1_EN, idx, 0); + acpi_write_pmreg(sc, ACPIREG_GPE1_STS, idx, -1); + } +#else + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0, 0); + acpi_write_pmreg(sc, ACPIREG_GPE0_STS, 0, -1); +#endif /* Enable EC interrupt */ if (sc->sc_ec != NULL) @@ -1453,8 +1472,8 @@ acpi_isr_thread(void *arg) aml_eval_object(sc, sc->sc_gpes[gpe].gpe_handler, &res, 0, NULL); } } - acpi_write_pmreg(sc, ACPIREG_GPE0_STS, en & sts); - acpi_write_pmreg(sc, ACPIREG_GPE0_EN, en); + acpi_write_pmreg(sc, ACPIREG_GPE0_STS, 0, en & sts); + acpi_write_pmreg(sc, ACPIREG_GPE0_EN, 0, en); } if (sc->sc_powerbtn) { diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index a977de14c17..90ab5755f41 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: acpivar.h,v 1.23 2006/05/29 00:54:23 canacar Exp $ */ +/* $OpenBSD: acpivar.h,v 1.24 2006/06/30 01:09:47 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -77,6 +77,8 @@ typedef SIMPLEQ_HEAD(, acpi_q) acpi_qhead_t; #define ACPIREG_PM1_STS 0x0E #define ACPIREG_PM1_EN 0x0F #define ACPIREG_PM1_CNT 0x10 +#define ACPIREG_GPE_STS 0x11 +#define ACPIREG_GPE_EN 0x12 struct acpi_parsestate { |