diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2007-02-18 01:37:50 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2007-02-18 01:37:50 +0000 |
commit | 7cd8f62f5a19e0768f3df0e0619f64ba9b3a1c1c (patch) | |
tree | 1abc369db8305dc0eca0ae1d0845e290814c2151 /sys/dev/acpi/acpi.c | |
parent | 63811bcaca08f79dca5938ec3c8ff4a1925c76c5 (diff) |
Shave off another K pre compression.
Shuffle SMALL_KERNEL functions around so that we only have a single #ifndef
Diffstat (limited to 'sys/dev/acpi/acpi.c')
-rw-r--r-- | sys/dev/acpi/acpi.c | 1018 |
1 files changed, 508 insertions, 510 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 9a2e836a8c3..579e87c52a1 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.79 2007/02/17 23:59:03 marco Exp $ */ +/* $OpenBSD: acpi.c,v 1.80 2007/02/18 01:37:49 marco Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -253,248 +253,6 @@ acpi_gasio(struct acpi_softc *sc, int iodir, int iospace, uint64_t address, return (0); } -/* Map Power Management registers */ -void -acpi_map_pmregs(struct acpi_softc *sc) -{ - bus_addr_t addr; - bus_size_t size; - const char *name; - int reg; - - for (reg = 0; reg < ACPIREG_MAXREG; reg++) { - size = 0; - switch (reg) { - case ACPIREG_SMICMD: - name = "smi"; - size = 1; - addr = sc->sc_fadt->smi_cmd; - break; - case ACPIREG_PM1A_STS: - case ACPIREG_PM1A_EN: - name = "pm1a_sts"; - size = sc->sc_fadt->pm1_evt_len >> 1; - addr = sc->sc_fadt->pm1a_evt_blk; - if (reg == ACPIREG_PM1A_EN && addr) { - addr += size; - name = "pm1a_en"; - } - break; - case ACPIREG_PM1A_CNT: - name = "pm1a_cnt"; - size = sc->sc_fadt->pm1_cnt_len; - addr = sc->sc_fadt->pm1a_cnt_blk; - break; - case ACPIREG_PM1B_STS: - case ACPIREG_PM1B_EN: - name = "pm1b_sts"; - size = sc->sc_fadt->pm1_evt_len >> 1; - addr = sc->sc_fadt->pm1b_evt_blk; - if (reg == ACPIREG_PM1B_EN && addr) { - addr += size; - name = "pm1b_en"; - } - break; - case ACPIREG_PM1B_CNT: - name = "pm1b_cnt"; - size = sc->sc_fadt->pm1_cnt_len; - addr = sc->sc_fadt->pm1b_cnt_blk; - break; - case ACPIREG_PM2_CNT: - name = "pm2_cnt"; - size = sc->sc_fadt->pm2_cnt_len; - addr = sc->sc_fadt->pm2_cnt_blk; - break; -#if 0 - case ACPIREG_PM_TMR: - /* Allocated in acpitimer */ - name = "pm_tmr"; - size = sc->sc_fadt->pm_tmr_len; - addr = sc->sc_fadt->pm_tmr_blk; - break; -#endif - case ACPIREG_GPE0_STS: - case ACPIREG_GPE0_EN: - name = "gpe0_sts"; - size = sc->sc_fadt->gpe0_blk_len >> 1; - addr = sc->sc_fadt->gpe0_blk; - - dnprintf(20, "gpe0 block len : %x\n", - sc->sc_fadt->gpe0_blk_len >> 1); - dnprintf(20, "gpe0 block addr: %x\n", - sc->sc_fadt->gpe0_blk); - if (reg == ACPIREG_GPE0_EN && addr) { - addr += size; - name = "gpe0_en"; - } - break; - case ACPIREG_GPE1_STS: - case ACPIREG_GPE1_EN: - name = "gpe1_sts"; - size = sc->sc_fadt->gpe1_blk_len >> 1; - addr = sc->sc_fadt->gpe1_blk; - - dnprintf(20, "gpe1 block len : %x\n", - sc->sc_fadt->gpe1_blk_len >> 1); - dnprintf(20, "gpe1 block addr: %x\n", - sc->sc_fadt->gpe1_blk); - if (reg == ACPIREG_GPE1_EN && addr) { - addr += size; - name = "gpe1_en"; - } - break; - } - if (size && addr) { - dnprintf(50, "mapping: %.4x %.4x %s\n", - addr, size, name); - - /* Size and address exist; map register space */ - bus_space_map(sc->sc_iot, addr, size, 0, - &sc->sc_pmregs[reg].ioh); - - sc->sc_pmregs[reg].name = name; - sc->sc_pmregs[reg].size = size; - sc->sc_pmregs[reg].addr = addr; - } - } -} - -/* Read from power management register */ -int -acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) -{ - bus_space_handle_t ioh; - bus_size_t size, __size; - int regval; - - __size = 0; - /* Special cases: 1A/1B blocks can be OR'ed together */ - 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: - __size = 1; - dnprintf(50, "read GPE_STS offset: %.2x %.2x %.2x\n", offset, - sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1); - if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { - reg = ACPIREG_GPE0_STS; - } - break; - case ACPIREG_GPE_EN: - __size = 1; - dnprintf(50, "read GPE_EN offset: %.2x %.2x %.2x\n", - offset, sc->sc_fadt->gpe0_blk_len>>1, - sc->sc_fadt->gpe1_blk_len>>1); - if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { - reg = ACPIREG_GPE0_EN; - } - break; - } - - if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) - return (0); - - regval = 0; - ioh = sc->sc_pmregs[reg].ioh; - size = sc->sc_pmregs[reg].size; - if (__size) - size = __size; - if (size > 4) - size = 4; - - switch (size) { - case 1: - regval = bus_space_read_1(sc->sc_iot, ioh, offset); - break; - case 2: - regval = bus_space_read_2(sc->sc_iot, ioh, offset); - break; - case 4: - regval = bus_space_read_4(sc->sc_iot, ioh, offset); - break; - } - - dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", - sc->sc_pmregs[reg].name, - 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 offset, int regval) -{ - bus_space_handle_t ioh; - bus_size_t size, __size; - - __size = 0; - /* Special cases: 1A/1B blocks can be written with same value */ - 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; - case ACPIREG_GPE_STS: - __size = 1; - dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n", - offset, sc->sc_fadt->gpe0_blk_len>>1, - sc->sc_fadt->gpe1_blk_len>>1, regval); - if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { - reg = ACPIREG_GPE0_STS; - } - break; - case ACPIREG_GPE_EN: - __size = 1; - dnprintf(50, "write GPE_EN offset: %.2x %.2x %.2x %.2x\n", - offset, sc->sc_fadt->gpe0_blk_len>>1, - sc->sc_fadt->gpe1_blk_len>>1, regval); - if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { - reg = ACPIREG_GPE0_EN; - } - break; - } - - /* All special case return here */ - if (reg >= ACPIREG_MAXREG) - return; - - ioh = sc->sc_pmregs[reg].ioh; - size = sc->sc_pmregs[reg].size; - if (__size) - size = __size; - if (size > 4) - size = 4; - switch (size) { - case 1: - bus_space_write_1(sc->sc_iot, ioh, offset, regval); - break; - case 2: - bus_space_write_2(sc->sc_iot, ioh, offset, regval); - break; - case 4: - bus_space_write_4(sc->sc_iot, ioh, offset, regval); - break; - } - - dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", - sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval); -} - void acpi_inidev(struct aml_node *node, void *arg) { @@ -518,151 +276,6 @@ acpi_inidev(struct aml_node *node, void *arg) aml_freevalue(&res); } -#ifndef SMALL_KERNEL -void -acpi_foundtmp(struct aml_node *node, void *arg) -{ - struct acpi_softc *sc = (struct acpi_softc *)arg; - struct device *self = (struct device *)arg; - const char *dev; - struct acpi_attach_args aaa; - - dnprintf(10, "found thermal zone entry: %s\n", node->parent->name); - - memset(&aaa, 0, sizeof(aaa)); - aaa.aaa_iot = sc->sc_iot; - aaa.aaa_memt = sc->sc_memt; - aaa.aaa_node = node->parent; - aaa.aaa_dev = dev; - aaa.aaa_name = "acpitz"; - - config_found(self, &aaa, acpi_print); -} - -void -acpi_foundpss(struct aml_node *node, void *arg) -{ - struct acpi_softc *sc = (struct acpi_softc *)arg; - struct device *self = (struct device *)arg; - const char *dev; - struct acpi_attach_args aaa; - - dnprintf(10, "found pss entry: %s\n", node->parent->name); - - memset(&aaa, 0, sizeof(aaa)); - aaa.aaa_iot = sc->sc_iot; - aaa.aaa_memt = sc->sc_memt; - aaa.aaa_node = node->parent; - aaa.aaa_dev = dev; - aaa.aaa_name = "acpicpu"; - - config_found(self, &aaa, acpi_print); -} - -void -acpi_foundec(struct aml_node *node, void *arg) -{ - struct acpi_softc *sc = (struct acpi_softc *)arg; - struct device *self = (struct device *)arg; - const char *dev; - struct aml_value res; - struct acpi_attach_args aaa; - - if (aml_evalnode(sc, node, 0, NULL, &res) != 0) - return; - - switch (res.type) { - case AML_OBJTYPE_STRING: - dev = res.v_string; - break; - case AML_OBJTYPE_INTEGER: - dev = aml_eisaid(aml_val2int(&res)); - break; - default: - dev = "unknown"; - break; - } - - if (strcmp(dev, ACPI_DEV_ECD)) - return; - - memset(&aaa, 0, sizeof(aaa)); - aaa.aaa_iot = sc->sc_iot; - aaa.aaa_memt = sc->sc_memt; - aaa.aaa_node = node->parent; - aaa.aaa_dev = dev; - aaa.aaa_name = "acpiec"; - config_found(self, &aaa, acpi_print); - aml_freevalue(&res); -} - -void -acpi_foundhid(struct aml_node *node, void *arg) -{ - struct acpi_softc *sc = (struct acpi_softc *)arg; - struct device *self = (struct device *)arg; - const char *dev; - struct aml_value res; - struct acpi_attach_args aaa; - - dnprintf(10, "found hid device: %s ", node->parent->name); - if (aml_evalnode(sc, node, 0, NULL, &res) != 0) - return; - - switch (res.type) { - case AML_OBJTYPE_STRING: - dev = res.v_string; - break; - case AML_OBJTYPE_INTEGER: - dev = aml_eisaid(aml_val2int(&res)); - break; - default: - dev = "unknown"; - break; - } - dnprintf(10, " device: %s\n", dev); - - memset(&aaa, 0, sizeof(aaa)); - aaa.aaa_iot = sc->sc_iot; - aaa.aaa_memt = sc->sc_memt; - aaa.aaa_node = node->parent; - aaa.aaa_dev = dev; - - if (!strcmp(dev, ACPI_DEV_AC)) - aaa.aaa_name = "acpiac"; - else if (!strcmp(dev, ACPI_DEV_CMB)) - aaa.aaa_name = "acpibat"; - else if (!strcmp(dev, ACPI_DEV_LD) || - !strcmp(dev, ACPI_DEV_PBD) || - !strcmp(dev, ACPI_DEV_SBD)) - aaa.aaa_name = "acpibtn"; - - if (aaa.aaa_name) - config_found(self, &aaa, acpi_print); - aml_freevalue(&res); -} - -void -acpi_founddock(struct aml_node *node, void *arg) -{ - struct acpi_softc *sc = (struct acpi_softc *)arg; - struct device *self = (struct device *)arg; - const char *dev; - struct acpi_attach_args aaa; - - dnprintf(10, "found dock entry: %s\n", node->parent->name); - - memset(&aaa, 0, sizeof(aaa)); - aaa.aaa_iot = sc->sc_iot; - aaa.aaa_memt = sc->sc_memt; - aaa.aaa_node = node->parent; - aaa.aaa_dev = dev; - aaa.aaa_name = "acpidock"; - - config_found(self, &aaa, acpi_print); -} -#endif /* SMALL_KERNEL */ - void acpi_init_pic(struct acpi_softc *sc) { @@ -860,8 +473,7 @@ acpi_attach(struct device *parent, struct device *self, void *aux) /* some devices require periodic polling */ timeout_set(&sc->sc_dev_timeout, acpi_poll, sc); - -#endif +#endif /* SMALL_KERNEL */ /* * Take over ACPI control. Note that once we do this, we @@ -1141,6 +753,172 @@ acpi_load_dsdt(paddr_t pa, struct acpi_q **dsdt) } } +int +acpiopen(dev_t dev, int flag, int mode, struct proc *p) +{ + struct acpi_softc *sc; + int error = 0; + + if (!acpi_cd.cd_ndevs || minor(dev) != 0 || + !(sc = acpi_cd.cd_devs[minor(dev)])) + return (ENXIO); + + return (error); +} + +int +acpiclose(dev_t dev, int flag, int mode, struct proc *p) +{ + struct acpi_softc *sc; + + if (!acpi_cd.cd_ndevs || minor(dev) != 0 || + !(sc = acpi_cd.cd_devs[minor(dev)])) + return (ENXIO); + + return (0); +} + +int +acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + int error = 0; +#ifndef SMALL_KERNEL + struct acpi_softc *sc; + struct acpi_ac *ac; + struct acpi_bat *bat; + struct apm_power_info *pi = (struct apm_power_info *)data; + int bats; + unsigned int remaining, rem, minutes, rate; + + if (!acpi_cd.cd_ndevs || minor(dev) != 0 || + !(sc = acpi_cd.cd_devs[minor(dev)])) + return (ENXIO); + + ACPI_LOCK(sc); + /* fake APM */ + switch (cmd) { + case APM_IOC_GETPOWER: + /* A/C */ + pi->ac_state = APM_AC_UNKNOWN; + SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { + if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) + pi->ac_state = APM_AC_ON; + else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) + if (pi->ac_state == APM_AC_UNKNOWN) + pi->ac_state = APM_AC_OFF; + } + + /* battery */ + pi->battery_state = APM_BATT_UNKNOWN; + pi->battery_life = 0; + pi->minutes_left = 0; + bats = 0; + remaining = rem = 0; + minutes = 0; + rate = 0; + SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { + if (bat->aba_softc->sc_bat_present == 0) + continue; + + if (bat->aba_softc->sc_bif.bif_last_capacity == 0) + continue; + + bats++; + rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / + bat->aba_softc->sc_bif.bif_last_capacity; + if (rem > 100) + rem = 100; + remaining += rem; + + if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) + continue; + else if (bat->aba_softc->sc_bst.bst_rate > 1) + rate = bat->aba_softc->sc_bst.bst_rate; + + minutes += bat->aba_softc->sc_bst.bst_capacity; + } + + if (bats == 0) { + pi->battery_state = APM_BATTERY_ABSENT; + pi->battery_life = 0; + pi->minutes_left = (unsigned int)-1; + break; + } + + if (pi->ac_state == APM_AC_ON || rate == 0) + pi->minutes_left = (unsigned int)-1; + else + pi->minutes_left = minutes / rate * 100; + + /* running on battery */ + pi->battery_life = remaining / bats; + if (pi->battery_life > 50) + pi->battery_state = APM_BATT_HIGH; + else if (pi->battery_life > 25) + pi->battery_state = APM_BATT_LOW; + else + pi->battery_state = APM_BATT_CRITICAL; + + break; + + default: + error = ENOTTY; + } + + ACPI_UNLOCK(sc); +#else + error = ENXIO; +#endif /* SMALL_KERNEL */ + return (error); +} + +void +acpi_filtdetach(struct knote *kn) +{ + struct acpi_softc *sc = kn->kn_hook; + + ACPI_LOCK(sc); + SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext); + ACPI_UNLOCK(sc); +} + +int +acpi_filtread(struct knote *kn, long hint) +{ + /* XXX weird kqueue_scan() semantics */ + if (hint & !kn->kn_data) + kn->kn_data = hint; + + return (1); +} + +int +acpikqfilter(dev_t dev, struct knote *kn) +{ + struct acpi_softc *sc; + + if (!acpi_cd.cd_ndevs || minor(dev) != 0 || + !(sc = acpi_cd.cd_devs[minor(dev)])) + return (ENXIO); + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &acpiread_filtops; + break; + default: + return (1); + } + + kn->kn_hook = sc; + + ACPI_LOCK(sc); + SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext); + ACPI_UNLOCK(sc); + + return (0); +} + +/* move all stuff that doesn't go on the boot media in here */ #ifndef SMALL_KERNEL int acpi_interrupt(void *arg) @@ -1562,169 +1340,389 @@ acpi_create_thread(void *arg) return; } } -#endif /* SMALL_KERNEL */ -int -acpiopen(dev_t dev, int flag, int mode, struct proc *p) +/* Map Power Management registers */ +void +acpi_map_pmregs(struct acpi_softc *sc) { - struct acpi_softc *sc; - int error = 0; + bus_addr_t addr; + bus_size_t size; + const char *name; + int reg; - if (!acpi_cd.cd_ndevs || minor(dev) != 0 || - !(sc = acpi_cd.cd_devs[minor(dev)])) - return (ENXIO); + for (reg = 0; reg < ACPIREG_MAXREG; reg++) { + size = 0; + switch (reg) { + case ACPIREG_SMICMD: + name = "smi"; + size = 1; + addr = sc->sc_fadt->smi_cmd; + break; + case ACPIREG_PM1A_STS: + case ACPIREG_PM1A_EN: + name = "pm1a_sts"; + size = sc->sc_fadt->pm1_evt_len >> 1; + addr = sc->sc_fadt->pm1a_evt_blk; + if (reg == ACPIREG_PM1A_EN && addr) { + addr += size; + name = "pm1a_en"; + } + break; + case ACPIREG_PM1A_CNT: + name = "pm1a_cnt"; + size = sc->sc_fadt->pm1_cnt_len; + addr = sc->sc_fadt->pm1a_cnt_blk; + break; + case ACPIREG_PM1B_STS: + case ACPIREG_PM1B_EN: + name = "pm1b_sts"; + size = sc->sc_fadt->pm1_evt_len >> 1; + addr = sc->sc_fadt->pm1b_evt_blk; + if (reg == ACPIREG_PM1B_EN && addr) { + addr += size; + name = "pm1b_en"; + } + break; + case ACPIREG_PM1B_CNT: + name = "pm1b_cnt"; + size = sc->sc_fadt->pm1_cnt_len; + addr = sc->sc_fadt->pm1b_cnt_blk; + break; + case ACPIREG_PM2_CNT: + name = "pm2_cnt"; + size = sc->sc_fadt->pm2_cnt_len; + addr = sc->sc_fadt->pm2_cnt_blk; + break; +#if 0 + case ACPIREG_PM_TMR: + /* Allocated in acpitimer */ + name = "pm_tmr"; + size = sc->sc_fadt->pm_tmr_len; + addr = sc->sc_fadt->pm_tmr_blk; + break; +#endif + case ACPIREG_GPE0_STS: + case ACPIREG_GPE0_EN: + name = "gpe0_sts"; + size = sc->sc_fadt->gpe0_blk_len >> 1; + addr = sc->sc_fadt->gpe0_blk; - return (error); -} + dnprintf(20, "gpe0 block len : %x\n", + sc->sc_fadt->gpe0_blk_len >> 1); + dnprintf(20, "gpe0 block addr: %x\n", + sc->sc_fadt->gpe0_blk); + if (reg == ACPIREG_GPE0_EN && addr) { + addr += size; + name = "gpe0_en"; + } + break; + case ACPIREG_GPE1_STS: + case ACPIREG_GPE1_EN: + name = "gpe1_sts"; + size = sc->sc_fadt->gpe1_blk_len >> 1; + addr = sc->sc_fadt->gpe1_blk; -int -acpiclose(dev_t dev, int flag, int mode, struct proc *p) -{ - struct acpi_softc *sc; + dnprintf(20, "gpe1 block len : %x\n", + sc->sc_fadt->gpe1_blk_len >> 1); + dnprintf(20, "gpe1 block addr: %x\n", + sc->sc_fadt->gpe1_blk); + if (reg == ACPIREG_GPE1_EN && addr) { + addr += size; + name = "gpe1_en"; + } + break; + } + if (size && addr) { + dnprintf(50, "mapping: %.4x %.4x %s\n", + addr, size, name); - if (!acpi_cd.cd_ndevs || minor(dev) != 0 || - !(sc = acpi_cd.cd_devs[minor(dev)])) - return (ENXIO); + /* Size and address exist; map register space */ + bus_space_map(sc->sc_iot, addr, size, 0, + &sc->sc_pmregs[reg].ioh); - return (0); + sc->sc_pmregs[reg].name = name; + sc->sc_pmregs[reg].size = size; + sc->sc_pmregs[reg].addr = addr; + } + } } +/* Read from power management register */ int -acpiioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +acpi_read_pmreg(struct acpi_softc *sc, int reg, int offset) { - int error = 0; -#ifndef SMALL_KERNEL - struct acpi_softc *sc; - struct acpi_ac *ac; - struct acpi_bat *bat; - struct apm_power_info *pi = (struct apm_power_info *)data; - int bats; - unsigned int remaining, rem, minutes, rate; - - if (!acpi_cd.cd_ndevs || minor(dev) != 0 || - !(sc = acpi_cd.cd_devs[minor(dev)])) - return (ENXIO); + bus_space_handle_t ioh; + bus_size_t size, __size; + int regval; - ACPI_LOCK(sc); - /* fake APM */ - switch (cmd) { - case APM_IOC_GETPOWER: - /* A/C */ - pi->ac_state = APM_AC_UNKNOWN; - SLIST_FOREACH(ac, &sc->sc_ac, aac_link) { - if (ac->aac_softc->sc_ac_stat == PSR_ONLINE) - pi->ac_state = APM_AC_ON; - else if (ac->aac_softc->sc_ac_stat == PSR_OFFLINE) - if (pi->ac_state == APM_AC_UNKNOWN) - pi->ac_state = APM_AC_OFF; + __size = 0; + /* Special cases: 1A/1B blocks can be OR'ed together */ + 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: + __size = 1; + dnprintf(50, "read GPE_STS offset: %.2x %.2x %.2x\n", offset, + sc->sc_fadt->gpe0_blk_len>>1, sc->sc_fadt->gpe1_blk_len>>1); + if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { + reg = ACPIREG_GPE0_STS; + } + break; + case ACPIREG_GPE_EN: + __size = 1; + dnprintf(50, "read GPE_EN offset: %.2x %.2x %.2x\n", + offset, sc->sc_fadt->gpe0_blk_len>>1, + sc->sc_fadt->gpe1_blk_len>>1); + if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { + reg = ACPIREG_GPE0_EN; } + break; + } - /* battery */ - pi->battery_state = APM_BATT_UNKNOWN; - pi->battery_life = 0; - pi->minutes_left = 0; - bats = 0; - remaining = rem = 0; - minutes = 0; - rate = 0; - SLIST_FOREACH(bat, &sc->sc_bat, aba_link) { - if (bat->aba_softc->sc_bat_present == 0) - continue; + if (reg >= ACPIREG_MAXREG || sc->sc_pmregs[reg].size == 0) + return (0); - if (bat->aba_softc->sc_bif.bif_last_capacity == 0) - continue; + regval = 0; + ioh = sc->sc_pmregs[reg].ioh; + size = sc->sc_pmregs[reg].size; + if (__size) + size = __size; + if (size > 4) + size = 4; - bats++; - rem = (bat->aba_softc->sc_bst.bst_capacity * 100) / - bat->aba_softc->sc_bif.bif_last_capacity; - if (rem > 100) - rem = 100; - remaining += rem; + switch (size) { + case 1: + regval = bus_space_read_1(sc->sc_iot, ioh, offset); + break; + case 2: + regval = bus_space_read_2(sc->sc_iot, ioh, offset); + break; + case 4: + regval = bus_space_read_4(sc->sc_iot, ioh, offset); + break; + } - if (bat->aba_softc->sc_bst.bst_rate == BST_UNKNOWN) - continue; - else if (bat->aba_softc->sc_bst.bst_rate > 1) - rate = bat->aba_softc->sc_bst.bst_rate; + dnprintf(30, "acpi_readpm: %s = %.4x:%.4x %x\n", + sc->sc_pmregs[reg].name, + sc->sc_pmregs[reg].addr, offset, regval); + return (regval); +} - minutes += bat->aba_softc->sc_bst.bst_capacity; - } +/* Write to power management register */ +void +acpi_write_pmreg(struct acpi_softc *sc, int reg, int offset, int regval) +{ + bus_space_handle_t ioh; + bus_size_t size, __size; - if (bats == 0) { - pi->battery_state = APM_BATTERY_ABSENT; - pi->battery_life = 0; - pi->minutes_left = (unsigned int)-1; - break; + __size = 0; + /* Special cases: 1A/1B blocks can be written with same value */ + 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; + case ACPIREG_GPE_STS: + __size = 1; + dnprintf(50, "write GPE_STS offset: %.2x %.2x %.2x %.2x\n", + offset, sc->sc_fadt->gpe0_blk_len>>1, + sc->sc_fadt->gpe1_blk_len>>1, regval); + if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { + reg = ACPIREG_GPE0_STS; } + break; + case ACPIREG_GPE_EN: + __size = 1; + dnprintf(50, "write GPE_EN offset: %.2x %.2x %.2x %.2x\n", + offset, sc->sc_fadt->gpe0_blk_len>>1, + sc->sc_fadt->gpe1_blk_len>>1, regval); + if (offset < (sc->sc_fadt->gpe0_blk_len >> 1)) { + reg = ACPIREG_GPE0_EN; + } + break; + } - if (pi->ac_state == APM_AC_ON || rate == 0) - pi->minutes_left = (unsigned int)-1; - else - pi->minutes_left = minutes / rate * 100; - - /* running on battery */ - pi->battery_life = remaining / bats; - if (pi->battery_life > 50) - pi->battery_state = APM_BATT_HIGH; - else if (pi->battery_life > 25) - pi->battery_state = APM_BATT_LOW; - else - pi->battery_state = APM_BATT_CRITICAL; + /* All special case return here */ + if (reg >= ACPIREG_MAXREG) + return; + ioh = sc->sc_pmregs[reg].ioh; + size = sc->sc_pmregs[reg].size; + if (__size) + size = __size; + if (size > 4) + size = 4; + switch (size) { + case 1: + bus_space_write_1(sc->sc_iot, ioh, offset, regval); + break; + case 2: + bus_space_write_2(sc->sc_iot, ioh, offset, regval); + break; + case 4: + bus_space_write_4(sc->sc_iot, ioh, offset, regval); break; - - default: - error = ENOTTY; } - ACPI_UNLOCK(sc); -#else - error = ENXIO; -#endif /* SMALL_KERNEL */ - return (error); + dnprintf(30, "acpi_writepm: %s = %.4x:%.4x %x\n", + sc->sc_pmregs[reg].name, sc->sc_pmregs[reg].addr, offset, regval); } void -acpi_filtdetach(struct knote *kn) +acpi_foundtmp(struct aml_node *node, void *arg) { - struct acpi_softc *sc = kn->kn_hook; + struct acpi_softc *sc = (struct acpi_softc *)arg; + struct device *self = (struct device *)arg; + const char *dev; + struct acpi_attach_args aaa; - ACPI_LOCK(sc); - SLIST_REMOVE(sc->sc_note, kn, knote, kn_selnext); - ACPI_UNLOCK(sc); + dnprintf(10, "found thermal zone entry: %s\n", node->parent->name); + + memset(&aaa, 0, sizeof(aaa)); + aaa.aaa_iot = sc->sc_iot; + aaa.aaa_memt = sc->sc_memt; + aaa.aaa_node = node->parent; + aaa.aaa_dev = dev; + aaa.aaa_name = "acpitz"; + + config_found(self, &aaa, acpi_print); } -int -acpi_filtread(struct knote *kn, long hint) +void +acpi_foundpss(struct aml_node *node, void *arg) { - /* XXX weird kqueue_scan() semantics */ - if (hint & !kn->kn_data) - kn->kn_data = hint; + struct acpi_softc *sc = (struct acpi_softc *)arg; + struct device *self = (struct device *)arg; + const char *dev; + struct acpi_attach_args aaa; - return (1); + dnprintf(10, "found pss entry: %s\n", node->parent->name); + + memset(&aaa, 0, sizeof(aaa)); + aaa.aaa_iot = sc->sc_iot; + aaa.aaa_memt = sc->sc_memt; + aaa.aaa_node = node->parent; + aaa.aaa_dev = dev; + aaa.aaa_name = "acpicpu"; + + config_found(self, &aaa, acpi_print); } -int -acpikqfilter(dev_t dev, struct knote *kn) +void +acpi_foundec(struct aml_node *node, void *arg) { - struct acpi_softc *sc; + struct acpi_softc *sc = (struct acpi_softc *)arg; + struct device *self = (struct device *)arg; + const char *dev; + struct aml_value res; + struct acpi_attach_args aaa; - if (!acpi_cd.cd_ndevs || minor(dev) != 0 || - !(sc = acpi_cd.cd_devs[minor(dev)])) - return (ENXIO); + if (aml_evalnode(sc, node, 0, NULL, &res) != 0) + return; - switch (kn->kn_filter) { - case EVFILT_READ: - kn->kn_fop = &acpiread_filtops; + switch (res.type) { + case AML_OBJTYPE_STRING: + dev = res.v_string; + break; + case AML_OBJTYPE_INTEGER: + dev = aml_eisaid(aml_val2int(&res)); break; default: - return (1); + dev = "unknown"; + break; } - kn->kn_hook = sc; + if (strcmp(dev, ACPI_DEV_ECD)) + return; - ACPI_LOCK(sc); - SLIST_INSERT_HEAD(sc->sc_note, kn, kn_selnext); - ACPI_UNLOCK(sc); + memset(&aaa, 0, sizeof(aaa)); + aaa.aaa_iot = sc->sc_iot; + aaa.aaa_memt = sc->sc_memt; + aaa.aaa_node = node->parent; + aaa.aaa_dev = dev; + aaa.aaa_name = "acpiec"; + config_found(self, &aaa, acpi_print); + aml_freevalue(&res); +} - return (0); +void +acpi_foundhid(struct aml_node *node, void *arg) +{ + struct acpi_softc *sc = (struct acpi_softc *)arg; + struct device *self = (struct device *)arg; + const char *dev; + struct aml_value res; + struct acpi_attach_args aaa; + + dnprintf(10, "found hid device: %s ", node->parent->name); + if (aml_evalnode(sc, node, 0, NULL, &res) != 0) + return; + + switch (res.type) { + case AML_OBJTYPE_STRING: + dev = res.v_string; + break; + case AML_OBJTYPE_INTEGER: + dev = aml_eisaid(aml_val2int(&res)); + break; + default: + dev = "unknown"; + break; + } + dnprintf(10, " device: %s\n", dev); + + memset(&aaa, 0, sizeof(aaa)); + aaa.aaa_iot = sc->sc_iot; + aaa.aaa_memt = sc->sc_memt; + aaa.aaa_node = node->parent; + aaa.aaa_dev = dev; + + if (!strcmp(dev, ACPI_DEV_AC)) + aaa.aaa_name = "acpiac"; + else if (!strcmp(dev, ACPI_DEV_CMB)) + aaa.aaa_name = "acpibat"; + else if (!strcmp(dev, ACPI_DEV_LD) || + !strcmp(dev, ACPI_DEV_PBD) || + !strcmp(dev, ACPI_DEV_SBD)) + aaa.aaa_name = "acpibtn"; + + if (aaa.aaa_name) + config_found(self, &aaa, acpi_print); + aml_freevalue(&res); } + +void +acpi_founddock(struct aml_node *node, void *arg) +{ + struct acpi_softc *sc = (struct acpi_softc *)arg; + struct device *self = (struct device *)arg; + const char *dev; + struct acpi_attach_args aaa; + + dnprintf(10, "found dock entry: %s\n", node->parent->name); + + memset(&aaa, 0, sizeof(aaa)); + aaa.aaa_iot = sc->sc_iot; + aaa.aaa_memt = sc->sc_memt; + aaa.aaa_node = node->parent; + aaa.aaa_dev = dev; + aaa.aaa_name = "acpidock"; + + config_found(self, &aaa, acpi_print); +} +#endif /* SMALL_KERNEL */ |