summaryrefslogtreecommitdiff
path: root/sys/dev/acpi/acpi.c
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2007-02-18 01:37:50 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2007-02-18 01:37:50 +0000
commit7cd8f62f5a19e0768f3df0e0619f64ba9b3a1c1c (patch)
tree1abc369db8305dc0eca0ae1d0845e290814c2151 /sys/dev/acpi/acpi.c
parent63811bcaca08f79dca5938ec3c8ff4a1925c76c5 (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.c1018
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 */