static void asus_attach(device_t parent, device_t self, void *opaque) { asus_softc_t *sc = device_private(self); struct acpi_attach_args *aa = opaque; ACPI_STATUS rv; sc->sc_node = aa->aa_node; sc->sc_dev = self; aprint_naive("\n"); aprint_normal("\n"); asus_init(self); sc->sc_smpsw_valid = true; sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE; sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE].smpsw_type = PSWITCH_TYPE_HOTKEY; if (sysmon_pswitch_register(&sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE])) { aprint_error_dev(self, "couldn't register with sysmon\n"); sc->sc_smpsw_valid = false; } rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_ALL_NOTIFY, asus_notify_handler, sc); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler: %s\n", AcpiFormatException(rv)); if (!pmf_device_register(self, asus_suspend, asus_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
static int acpi_cmbat_attach(device_t dev) { int error; ACPI_HANDLE handle; struct acpi_cmbat_softc *sc; sc = device_get_softc(dev); handle = acpi_get_handle(dev); sc->dev = dev; timespecclear(&sc->bst_lastupdated); error = acpi_battery_register(dev); if (error != 0) { device_printf(dev, "registering battery failed\n"); return (error); } /* * Install a system notify handler in addition to the device notify. * Toshiba notebook uses this alternate notify for its battery. */ AcpiInstallNotifyHandler(handle, ACPI_ALL_NOTIFY, acpi_cmbat_notify_handler, dev); AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_cmbat_init_battery, dev); return (0); }
static ACPI_STATUS InstallHandlers (void) { ACPI_STATUS Status; /* Install global notify handler */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, NotifyHandler, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler")); return (Status); } Status = AcpiInstallAddressSpaceHandler (ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, RegionHandler, RegionInit, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While installing an OpRegion handler")); return (Status); } return (AE_OK); }
status_t install_notify_handler(acpi_handle device, uint32 handlerType, acpi_notify_handler handler, void *context) { return AcpiInstallNotifyHandler(device, handlerType, (ACPI_NOTIFY_HANDLER)handler, context) == AE_OK ? B_OK : B_ERROR; }
static int acpi_lid_attach(device_t dev) { struct acpi_prw_data prw; struct acpi_lid_softc *sc; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->lid_dev = dev; sc->lid_handle = acpi_get_handle(dev); /* * If a system does not get lid events, it may make sense to change * the type to ACPI_ALL_NOTIFY. Some systems generate both a wake and * runtime notify in that case though. */ AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY, acpi_lid_notify_handler, sc); /* Enable the GPE for wake/runtime. */ acpi_wake_set_enable(dev, 1); if (acpi_parse_prw(sc->lid_handle, &prw) == 0) AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit); return (0); }
static int acpi_panasonic_attach(device_t dev) { struct acpi_panasonic_softc *sc; struct acpi_softc *acpi_sc; ACPI_STATUS status; int i; sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); acpi_sc = acpi_device_get_parent_softc(dev); /* Build sysctl tree */ sysctl_ctx_init(&sc->sysctl_ctx); sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "panasonic", CTLFLAG_RD, 0, ""); for (i = 0; sysctl_table[i].name != NULL; i++) { SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, sysctl_table[i].name, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY, sc, i, acpi_panasonic_sysctl, "I", ""); } #if 0 /* Activate hotkeys */ status = AcpiEvaluateObject(sc->handle, "", NULL, NULL); if (ACPI_FAILURE(status)) { device_printf(dev, "enable FN keys failed\n"); sysctl_ctx_free(&sc->sysctl_ctx); return (ENXIO); } #endif /* Handle notifies */ status = AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, acpi_panasonic_notify, sc); if (ACPI_FAILURE(status)) { device_printf(dev, "couldn't install notify handler - %s\n", AcpiFormatException(status)); sysctl_ctx_free(&sc->sysctl_ctx); return (ENXIO); } /* Install power profile event handler */ sc->power_evh = EVENTHANDLER_REGISTER(power_profile_change, acpi_panasonic_power_profile, sc->handle, 0); return (0); }
/* * Install event handler for the hot plug events on the bus node as well * as device function (dev=0,func=0). */ static ACPI_STATUS pciehpc_acpi_install_event_handler(pcie_hp_ctrl_t *ctrl_p) { pcie_hp_slot_t *slot_p = ctrl_p->hc_slots[0]; int status = AE_OK; pciehpc_acpi_t *acpi_p; PCIE_DBG("install event handler for slot %d\n", slot_p->hs_phy_slot_num); acpi_p = ctrl_p->hc_misc_data; if (acpi_p->slot_dev_obj == NULL) return (AE_NOT_FOUND); /* * Install event hanlder for events on the bus object. * (Note: Insert event (hot-insert) is delivered on this object) */ status = AcpiInstallNotifyHandler(acpi_p->slot_dev_obj, ACPI_SYSTEM_NOTIFY, pciehpc_acpi_notify_handler, (void *)ctrl_p); if (status != AE_OK) goto cleanup; /* * Install event hanlder for events on the device function object. * (Note: Eject device event (hot-remove) is delivered on this object) * * NOTE: Here the assumption is that Notify events are delivered * on all of the 8 possible device functions so, subscribing to * one of them is sufficient. */ status = AcpiInstallNotifyHandler(acpi_p->bus_obj, ACPI_SYSTEM_NOTIFY, pciehpc_acpi_notify_handler, (void *)ctrl_p); return (status); cleanup: (void) AcpiRemoveNotifyHandler(acpi_p->slot_dev_obj, ACPI_SYSTEM_NOTIFY, pciehpc_acpi_notify_handler); return (status); }
static int acpi_dock_attach(device_t dev) { struct acpi_dock_softc *sc; ACPI_HANDLE h; sc = device_get_softc(dev); h = acpi_get_handle(dev); if (sc == NULL || h == NULL) return (ENXIO); sc->status = ACPI_DOCK_STATUS_UNKNOWN; AcpiEvaluateObject(h, "_INI", NULL, NULL); ACPI_SERIAL_BEGIN(dock); acpi_dock_device_check(dev); /* Get the sysctl tree */ sc->sysctl_ctx = device_get_sysctl_ctx(dev); sc->sysctl_tree = device_get_sysctl_tree(dev); SYSCTL_ADD_INT(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "_sta", CTLFLAG_RD, &sc->_sta, 0, "Dock _STA"); SYSCTL_ADD_INT(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "_bdn", CTLFLAG_RD, &sc->_bdn, 0, "Dock _BDN"); SYSCTL_ADD_INT(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "_uid", CTLFLAG_RD, &sc->_uid, 0, "Dock _UID"); SYSCTL_ADD_PROC(sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, "status", CTLTYPE_INT|CTLFLAG_RW, dev, 0, acpi_dock_status_sysctl, "I", "Dock/Undock operation"); ACPI_SERIAL_END(dock); AcpiInstallNotifyHandler(h, ACPI_ALL_NOTIFY, acpi_dock_notify_handler, dev); return (0); }
static int acpi_button_attach(device_t dev) { struct acpi_prw_data prw; struct acpi_button_softc *sc; ACPI_STATUS status; int event; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->button_dev = dev; sc->button_handle = acpi_get_handle(dev); event = (sc->button_type == ACPI_SLEEP_BUTTON) ? ACPI_EVENT_SLEEP_BUTTON : ACPI_EVENT_POWER_BUTTON; /* * Install the new handler. We could remove any fixed handlers added * from the FADT once we have a duplicate from the AML but some systems * only return events on one or the other so we have to keep both. */ if (sc->fixed) { AcpiClearEvent(event); status = AcpiInstallFixedEventHandler(event, acpi_button_fixed_handler, sc); } else { /* * If a system does not get lid events, it may make sense to change * the type to ACPI_ALL_NOTIFY. Some systems generate both a wake * and runtime notify in that case though. */ status = AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc); } if (ACPI_FAILURE(status)) { device_printf(sc->button_dev, "couldn't install notify handler - %s\n", AcpiFormatException(status)); return_VALUE (ENXIO); } /* Enable the GPE for wake/runtime */ acpi_wake_set_enable(dev, 1); if (acpi_parse_prw(sc->button_handle, &prw) == 0) AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit); return_VALUE (0); }
static ACPI_STATUS InstallHandlers (void) { ACPI_STATUS Status; /* Install global notify handler */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, NotifyHandler, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "While installing Notify handler")); return (Status); } return (AE_OK); }
/* * acpitz_attach: autoconf(9) attach routine */ void acpitz_attach(struct device *parent, struct device *self, void *aux) { struct acpitz_softc *sc = (struct acpitz_softc *)self; struct acpi_attach_args *aa = aux; ACPI_STATUS rv; ACPI_INTEGER v; #if 0 sc->sc_flags = ATZ_F_VERBOSE; #endif sc->sc_devnode = aa->aa_node; printf(": ACPI Thermal Zone\n"); rv = acpi_eval_integer(sc->sc_devnode->ad_handle, "_TZP", &v); if (ACPI_FAILURE(rv)) { printf("%s: unable to get polling interval; using default of", sc->sc_dev.dv_xname); sc->sc_zone.tzp = ATZ_TZP_RATE; } else { sc->sc_zone.tzp = v; printf("%s: polling interval is", sc->sc_dev.dv_xname); } printf(" %d.%ds\n", sc->sc_zone.tzp / 10, sc->sc_zone.tsp % 10); /* XXX a value of 0 means "polling is not necessary" */ if (sc->sc_zone.tzp == 0) sc->sc_zone.tzp = ATZ_TZP_RATE; acpitz_get_status(sc); rv = AcpiInstallNotifyHandler(sc->sc_devnode->ad_handle, ACPI_SYSTEM_NOTIFY, acpitz_notify_handler, sc); if (ACPI_FAILURE(rv)) { printf("%s: unable to install SYSTEM NOTIFY handler: %s\n", sc->sc_dev.dv_xname, AcpiFormatException(rv)); return; } callout_init(&sc->sc_callout); callout_reset(&sc->sc_callout, (sc->sc_zone.tzp / 10) * hz, acpitz_tick, sc); acpitz_init_envsys(sc); }
static int acpi_cmbat_attach(device_t dev) { int error; ACPI_HANDLE handle; struct acpi_cmbat_softc *sc; if ((sc = device_get_softc(dev)) == NULL) { return (ENXIO); } handle = acpi_get_handle(dev); AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, acpi_cmbat_notify_handler, dev); sc->bif_updating = sc->bst_updating = 0; sc->dev = dev; timespecclear(&sc->bif_lastupdated); timespecclear(&sc->bst_lastupdated); if (acpi_cmbat_units == 0) { if ((error = acpi_register_ioctl(ACPIIO_CMBAT_GET_BIF, acpi_cmbat_ioctl, NULL)) != 0) { return (error); } if ((error = acpi_register_ioctl(ACPIIO_CMBAT_GET_BST, acpi_cmbat_ioctl, NULL)) != 0) { return (error); } } if ((error = acpi_battery_register(ACPI_BATT_TYPE_CMBAT, acpi_cmbat_units)) != 0) { return (error); } acpi_cmbat_units++; timespecclear(&acpi_cmbat_info_lastupdated); sc->initializing = 0; AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_cmbat_init_battery, dev); return (0); }
static int acpi_lid_attach(device_t dev) { struct acpi_lid_softc *sc; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->lid_dev = dev; sc->lid_handle = acpi_get_handle(dev); /* * Install notification handler */ AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY, acpi_lid_notify_handler, sc); acpi_device_enable_wake_capability(sc->lid_handle, 1); return_VALUE(0); }
static int acpi_button_attach(device_t dev) { struct acpi_button_softc *sc; ACPI_STATUS status; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->button_dev = dev; sc->button_handle = acpi_get_handle(dev); if (ACPI_FAILURE(status = AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc))) { device_printf(sc->button_dev, "couldn't install Notify handler - %s\n", AcpiFormatException(status)); return_VALUE(ENXIO); } acpi_device_enable_wake_capability(sc->button_handle, 1); return_VALUE(0); }
/* * acpilid_attach: * * Autoconfiguration `attach' routine. */ void acpilid_attach(struct device *parent, struct device *self, void *aux) { struct acpilid_softc *sc = (void *) self; struct acpi_attach_args *aa = aux; ACPI_STATUS rv; printf(": ACPI Lid Switch\n"); sc->sc_node = aa->aa_node; rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, acpilid_notify_handler, sc); if (rv != AE_OK) { printf("%s: unable to register device notify handler: %d\n", sc->sc_dev.dv_xname, rv); return; } /* Display the current state when it changes. */ sc->sc_flags = ACPILID_F_VERBOSE; }
/* * Install event handler for ACPI system events. * Acpinex driver handles ACPI system events for its children, * device specific events will be handled by device drivers. * Return DDI_SUCCESS on success, and DDI_FAILURE on failure. */ static int acpinex_event_install_handler(ACPI_HANDLE hdl, void *arg, ACPI_DEVICE_INFO *infop, acpidev_data_handle_t dhdl) { int rc = DDI_SUCCESS; ASSERT(hdl != NULL); ASSERT(dhdl != NULL); ASSERT(infop != NULL); /* * Check whether the event handler has already been installed on the * device object. With the introduction of ACPI Alias objects, which are * similar to symlinks in file systems, there may be multiple name * objects in the ACPI namespace pointing to the same underlying device * object. Those Alias objects need to be filtered out, otherwise * it will attempt to install the event handler multiple times on the * same device object which will fail. */ if (acpidev_data_get_flag(dhdl, ACPIDEV_DATA_HANDLER_READY)) { return (DDI_SUCCESS); } if (ACPI_SUCCESS(AcpiInstallNotifyHandler(hdl, ACPI_SYSTEM_NOTIFY, acpinex_event_system_handler, arg))) { acpidev_data_set_flag(dhdl, ACPIDEV_DATA_HANDLER_READY); } else { char *objname; objname = acpidev_get_object_name(hdl); cmn_err(CE_WARN, "!acpinex: failed to install system event handler for %s.", objname); acpidev_free_object_name(objname); rc = DDI_FAILURE; } return (rc); }
static int acpi_acad_attach(device_t dev) { struct acpi_acad_softc *sc; struct acpi_softc *acpi_sc; ACPI_HANDLE handle; int error; sc = device_get_softc(dev); handle = acpi_get_handle(dev); error = acpi_register_ioctl(ACPIIO_ACAD_GET_STATUS, acpi_acad_ioctl, dev); if (error != 0) return (error); ACPI_SERIAL_INIT(acad); if (device_get_unit(dev) == 0) { acpi_sc = acpi_device_get_parent_softc(dev); SYSCTL_ADD_PROC(&acpi_sc->acpi_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "acline", CTLTYPE_INT | CTLFLAG_RD, &sc->status, 0, acpi_acad_sysctl, "I", ""); } /* Get initial status after whole system is up. */ sc->status = -1; /* * Install both system and device notify handlers since the Casio * FIVA needs them. */ AcpiInstallNotifyHandler(handle, ACPI_ALL_NOTIFY, acpi_acad_notify_handler, dev); AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_acad_init_acline, dev); return (0); }
static int acpi_fujitsu_attach(device_t dev) { struct acpi_fujitsu_softc *sc; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->dev = dev; sc->handle = acpi_get_handle(dev); /* Install notification handler */ AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, acpi_fujitsu_notify_handler, sc); /* Snag our default values for the hotkeys / hotkey states. */ ACPI_SERIAL_BEGIN(fujitsu); if (!acpi_fujitsu_init(sc)) device_printf(dev, "Couldn't initialize hotkey states!\n"); ACPI_SERIAL_END(fujitsu); return (0); }
/* * Call this *after* all CPUs have been attached. */ static void acpi_cpu_startup(void *arg) { struct acpi_cpu_softc *sc; int i; /* Get set of CPU devices */ devclass_get_devices(acpi_cpu_devclass, &cpu_devices, &cpu_ndevices); /* * Setup any quirks that might necessary now that we have probed * all the CPUs */ acpi_cpu_quirks(); cpu_cx_count = 0; if (cpu_cx_generic) { /* * We are using generic Cx mode, probe for available Cx states * for all processors. */ for (i = 0; i < cpu_ndevices; i++) { sc = device_get_softc(cpu_devices[i]); acpi_cpu_generic_cx_probe(sc); if (sc->cpu_cx_count > cpu_cx_count) cpu_cx_count = sc->cpu_cx_count; } /* * Find the highest Cx state common to all CPUs * in the system, taking quirks into account. */ for (i = 0; i < cpu_ndevices; i++) { sc = device_get_softc(cpu_devices[i]); if (sc->cpu_cx_count < cpu_cx_count) cpu_cx_count = sc->cpu_cx_count; } } else { /* * We are using _CST mode, remove C3 state if necessary. * Update the largest Cx state supported in the global cpu_cx_count. * It will be used in the global Cx sysctl handler. * As we now know for sure that we will be using _CST mode * install our notify handler. */ for (i = 0; i < cpu_ndevices; i++) { sc = device_get_softc(cpu_devices[i]); if (cpu_quirks & CPU_QUIRK_NO_C3) { sc->cpu_cx_count = sc->cpu_non_c3 + 1; } if (sc->cpu_cx_count > cpu_cx_count) cpu_cx_count = sc->cpu_cx_count; AcpiInstallNotifyHandler(sc->cpu_handle, ACPI_DEVICE_NOTIFY, acpi_cpu_notify, sc); } } /* Perform Cx final initialization. */ for (i = 0; i < cpu_ndevices; i++) { sc = device_get_softc(cpu_devices[i]); acpi_cpu_startup_cx(sc); } /* Add a sysctl handler to handle global Cx lowest setting */ SYSCTL_ADD_PROC(&cpu_sysctl_ctx, SYSCTL_CHILDREN(cpu_sysctl_tree), OID_AUTO, "cx_lowest", CTLTYPE_STRING | CTLFLAG_RW, NULL, 0, acpi_cpu_global_cx_lowest_sysctl, "A", "Global lowest Cx sleep state to use"); /* Take over idling from cpu_idle_default(). */ cpu_cx_lowest = 0; cpu_disable_idle = FALSE; cpu_idle_hook = acpi_cpu_idle; }
static int acpi_tz_attach(device_t dev) { struct acpi_tz_softc *sc; struct acpi_softc *acpi_sc; int error; char oidname[8]; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->tz_dev = dev; sc->tz_handle = acpi_get_handle(dev); sc->tz_requested = TZ_ACTIVE_NONE; sc->tz_active = TZ_ACTIVE_UNKNOWN; sc->tz_thflags = TZ_THFLAG_NONE; sc->tz_cooling_proc = NULL; sc->tz_cooling_proc_running = FALSE; sc->tz_cooling_active = FALSE; sc->tz_cooling_updated = FALSE; sc->tz_cooling_enabled = FALSE; /* * Parse the current state of the thermal zone and build control * structures. We don't need to worry about interference with the * control thread since we haven't fully attached this device yet. */ if ((error = acpi_tz_establish(sc)) != 0) return (error); /* * Register for any Notify events sent to this zone. */ AcpiInstallNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY, acpi_tz_notify_handler, sc); /* * Create our sysctl nodes. * * XXX we need a mechanism for adding nodes under ACPI. */ if (device_get_unit(dev) == 0) { acpi_sc = acpi_device_get_parent_softc(dev); sysctl_ctx_init(&acpi_tz_sysctl_ctx); acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "thermal", CTLFLAG_RD, 0, ""); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "min_runtime", CTLFLAG_RW, &acpi_tz_min_runtime, 0, "minimum cooling run time in sec"); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "polling_rate", CTLFLAG_RW, &acpi_tz_polling_rate, 0, "monitor polling interval in seconds"); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "user_override", CTLFLAG_RW, &acpi_tz_override, 0, "allow override of thermal settings"); } sysctl_ctx_init(&sc->tz_sysctl_ctx); sprintf(oidname, "tz%d", device_get_unit(dev)); sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, oidname, CTLFLAG_RD, 0, ""); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, &sc->tz_temperature, 0, sysctl_handle_int, "IK", "current thermal zone temperature"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW, sc, 0, acpi_tz_active_sysctl, "I", "cooling is active"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "passive_cooling", CTLTYPE_INT | CTLFLAG_RW, sc, 0, acpi_tz_cooling_sysctl, "I", "enable passive (speed reduction) cooling"); SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "thermal_flags", CTLFLAG_RD, &sc->tz_thflags, 0, "thermal zone flags"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.psv), acpi_tz_temp_sysctl, "IK", "passive cooling temp setpoint"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK", "too hot temp setpoint (suspend now)"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_CRT", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.crt), acpi_tz_temp_sysctl, "IK", "critical temp setpoint (shutdown now)"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_ACx", CTLTYPE_INT | CTLFLAG_RD, &sc->tz_zone.ac, sizeof(sc->tz_zone.ac), sysctl_handle_opaque, "IK", ""); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TC1", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tc1), acpi_tz_passive_sysctl, "I", "thermal constant 1 for passive cooling"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TC2", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tc2), acpi_tz_passive_sysctl, "I", "thermal constant 2 for passive cooling"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TSP", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tsp), acpi_tz_passive_sysctl, "I", "thermal sampling period for passive cooling"); /* * Create thread to service all of the thermal zones. Register * our power profile event handler. */ sc->tz_event = EVENTHANDLER_REGISTER(power_profile_change, acpi_tz_power_profile, sc, 0); if (acpi_tz_proc == NULL) { error = kproc_create(acpi_tz_thread, NULL, &acpi_tz_proc, RFHIGHPID, 0, "acpi_thermal"); if (error != 0) { device_printf(sc->tz_dev, "could not create thread - %d", error); goto out; } } /* * Create a thread to handle passive cooling for 1st zone which * has _PSV, _TSP, _TC1 and _TC2. Users can enable it for other * zones manually for now. * * XXX We enable only one zone to avoid multiple zones conflict * with each other since cpufreq currently sets all CPUs to the * given frequency whereas it's possible for different thermal * zones to specify independent settings for multiple CPUs. */ if (acpi_tz_cooling_unit < 0 && acpi_tz_cooling_is_available(sc)) sc->tz_cooling_enabled = TRUE; if (sc->tz_cooling_enabled) { error = acpi_tz_cooling_thread_start(sc); if (error != 0) { sc->tz_cooling_enabled = FALSE; goto out; } acpi_tz_cooling_unit = device_get_unit(dev); } /* * Flag the event handler for a manual invocation by our timeout. * We defer it like this so that the rest of the subsystem has time * to come up. Don't bother evaluating/printing the temperature at * this point; on many systems it'll be bogus until the EC is running. */ sc->tz_flags |= TZ_FLAG_GETPROFILE; out: if (error != 0) { EVENTHANDLER_DEREGISTER(power_profile_change, sc->tz_event); AcpiRemoveNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY, acpi_tz_notify_handler); sysctl_ctx_free(&sc->tz_sysctl_ctx); } return_VALUE (error); }
static void sony_acpi_attach(device_t parent, device_t self, void *aux) { struct sony_acpi_softc *sc = device_private(self); struct acpi_attach_args *aa = aux; ACPI_STATUS rv; int i; aprint_naive(": Sony Miscellaneous Controller\n"); aprint_normal(": Sony Miscellaneous Controller\n"); sc->sc_node = aa->aa_node; sc->sc_dev = self; rv = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 100, sony_acpi_find_pic, sc, NULL); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't walk namespace: %s\n", AcpiFormatException(rv)); /* * If we don't find an SNY6001 device, assume that we need the * Fn key initialization sequence. */ if (sc->sc_has_pic == false) sc->sc_quirks |= SONY_ACPI_QUIRK_FNINIT; sony_acpi_quirk_setup(sc); /* Configure suspend button and hotkeys */ sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_name = device_xname(self); sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP; sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE; sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_type = PSWITCH_TYPE_HOTKEY; sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_name = PSWITCH_HK_ZOOM_BUTTON; sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_type = PSWITCH_TYPE_HOTKEY; sc->sc_smpsw_valid = 1; for (i = 0; i < SONY_PSW_LAST; i++) if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) { aprint_error_dev(self, "couldn't register %s with sysmon\n", sc->sc_smpsw[i].smpsw_name); sc->sc_smpsw_valid = 0; } /* Install notify handler */ rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, sony_acpi_notify_handler, self); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler (%d)\n", rv); /* Install sysctl handler */ rv = AcpiWalkNamespace(ACPI_TYPE_METHOD, sc->sc_node->ad_handle, 1, sony_walk_cb, sc, NULL); #ifdef DIAGNOSTIC if (ACPI_FAILURE(rv)) aprint_error_dev(self, "Cannot walk ACPI namespace (%d)\n", rv); #endif if (!pmf_device_register(self, sony_acpi_suspend, sony_acpi_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP, sony_acpi_brightness_up, true)) aprint_error_dev(self, "couldn't register BRIGHTNESS UP handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, sony_acpi_brightness_down, true)) aprint_error_dev(self, "couldn't register BRIGHTNESS DOWN handler\n"); }
static status_t acpi_std_ops(int32 op,...) { switch (op) { case B_MODULE_INIT: { ACPI_OBJECT arg; ACPI_OBJECT_LIST parameter; void *settings; bool acpiDisabled = false; AcpiGbl_CopyDsdtLocally = true; settings = load_driver_settings("kernel"); if (settings != NULL) { acpiDisabled = !get_driver_boolean_parameter(settings, "acpi", true, true); unload_driver_settings(settings); } if (!acpiDisabled) { // check if safemode settings disable ACPI settings = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS); if (settings != NULL) { acpiDisabled = get_driver_boolean_parameter(settings, B_SAFEMODE_DISABLE_ACPI, false, false); unload_driver_settings(settings); } } if (acpiDisabled) { ERROR("ACPI disabled\n"); return ENOSYS; } if (gDPC->new_dpc_queue(&gDPCHandle, "acpi_task", B_URGENT_DISPLAY_PRIORITY + 1) != B_OK) { ERROR("failed to create os execution queue\n"); return B_ERROR; } #ifdef ACPI_DEBUG_OUTPUT AcpiDbgLevel = ACPI_DEBUG_ALL | ACPI_LV_VERBOSE; AcpiDbgLayer = ACPI_ALL_COMPONENTS; #endif if (checkAndLogFailure(AcpiInitializeSubsystem(), "AcpiInitializeSubsystem failed")) goto err; if (checkAndLogFailure(AcpiInitializeTables(NULL, 0, TRUE), "AcpiInitializeTables failed")) goto err; if (checkAndLogFailure(AcpiLoadTables(), "AcpiLoadTables failed")) goto err; /* Install the default address space handlers. */ if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_MEMORY, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise SystemMemory handler:")) goto err; if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_SYSTEM_IO, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise SystemIO handler:")) goto err; if (checkAndLogFailure(AcpiInstallAddressSpaceHandler( ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL), "Could not initialise PciConfig handler:")) goto err; arg.Integer.Type = ACPI_TYPE_INTEGER; arg.Integer.Value = apic_available() ? APIC_MODE : PIC_MODE; parameter.Count = 1; parameter.Pointer = &arg; AcpiEvaluateObject(NULL, "\\_PIC", ¶meter, NULL); if (checkAndLogFailure(AcpiEnableSubsystem( ACPI_FULL_INITIALIZATION), "AcpiEnableSubsystem failed")) goto err; if (checkAndLogFailure(AcpiInitializeObjects( ACPI_FULL_INITIALIZATION), "AcpiInitializeObjects failed")) goto err; //TODO: Walk namespace init ALL _PRW's #ifdef ACPI_DEBUG_OUTPUT checkAndLogFailure( AcpiInstallGlobalEventHandler(globalGPEHandler, NULL), "Failed to install global GPE-handler."); checkAndLogFailure(AcpiInstallNotifyHandler(ACPI_ROOT_OBJECT, ACPI_ALL_NOTIFY, globalNotifyHandler, NULL), "Failed to install global Notify-handler."); #endif checkAndLogFailure(AcpiEnableAllRuntimeGpes(), "Failed to enable all runtime Gpes"); checkAndLogFailure(AcpiUpdateAllGpes(), "Failed to update all Gpes"); TRACE("ACPI initialized\n"); return B_OK; err: return B_ERROR; } case B_MODULE_UNINIT: { if (checkAndLogFailure(AcpiTerminate(), "Could not bring system out of ACPI mode. Oh well.")); gDPC->delete_dpc_queue(gDPCHandle); gDPCHandle = NULL; break; } default: return B_ERROR; } return B_OK; }
/* Probe and setup any valid performance states (Px). */ static int acpi_perf_evaluate(device_t dev) { struct acpi_perf_softc *sc; ACPI_BUFFER buf; ACPI_OBJECT *pkg, *res; ACPI_STATUS status; int count, error, i, j; static int once = 1; uint32_t *p; /* Get the control values and parameters for each state. */ error = ENXIO; sc = device_get_softc(dev); buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->handle, "_PSS", NULL, &buf); if (ACPI_FAILURE(status)) return (ENXIO); pkg = (ACPI_OBJECT *)buf.Pointer; if (!ACPI_PKG_VALID(pkg, 1)) { device_printf(dev, "invalid top level _PSS package\n"); goto out; } sc->px_count = pkg->Package.Count; sc->px_states = malloc(sc->px_count * sizeof(struct acpi_px), M_ACPIPERF, M_WAITOK | M_ZERO); if (sc->px_states == NULL) goto out; /* * Each state is a package of {CoreFreq, Power, TransitionLatency, * BusMasterLatency, ControlVal, StatusVal}, sorted from highest * performance to lowest. */ count = 0; for (i = 0; i < sc->px_count; i++) { res = &pkg->Package.Elements[i]; if (!ACPI_PKG_VALID(res, 6)) { if (once) { once = 0; device_printf(dev, "invalid _PSS package\n"); } continue; } /* Parse the rest of the package into the struct. */ p = &sc->px_states[count].core_freq; for (j = 0; j < 6; j++, p++) acpi_PkgInt32(res, j, p); /* * Check for some impossible frequencies that some systems * use to indicate they don't actually support this Px state. */ if (sc->px_states[count].core_freq == 0 || sc->px_states[count].core_freq == 9999 || sc->px_states[count].core_freq == 0x9999 || sc->px_states[count].core_freq >= 0xffff) continue; /* Check for duplicate entries */ if (count > 0 && sc->px_states[count - 1].core_freq == sc->px_states[count].core_freq) continue; count++; } sc->px_count = count; /* No valid Px state found so give up. */ if (count == 0) goto out; AcpiOsFree(buf.Pointer); /* Get the control and status registers (one of each). */ buf.Pointer = NULL; buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->handle, "_PCT", NULL, &buf); if (ACPI_FAILURE(status)) goto out; /* Check the package of two registers, each a Buffer in GAS format. */ pkg = (ACPI_OBJECT *)buf.Pointer; if (!ACPI_PKG_VALID(pkg, 2)) { device_printf(dev, "invalid perf register package\n"); goto out; } error = acpi_PkgGas(sc->dev, pkg, 0, &sc->perf_ctrl_type, &sc->px_rid, &sc->perf_ctrl, 0); if (error) { /* * If the register is of type FFixedHW, we can only return * info, we can't get or set new settings. */ if (error == EOPNOTSUPP) { sc->info_only = TRUE; error = 0; } else device_printf(dev, "failed in PERF_CTL attach\n"); goto out; } sc->px_rid++; error = acpi_PkgGas(sc->dev, pkg, 1, &sc->perf_sts_type, &sc->px_rid, &sc->perf_status, 0); if (error) { if (error == EOPNOTSUPP) { sc->info_only = TRUE; error = 0; } else device_printf(dev, "failed in PERF_STATUS attach\n"); goto out; } sc->px_rid++; /* Get our current limit and register for notifies. */ acpi_px_available(sc); AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, acpi_px_notify, sc); error = 0; out: if (error) { if (sc->px_states) { free(sc->px_states, M_ACPIPERF); sc->px_states = NULL; } if (sc->perf_ctrl) { bus_release_resource(sc->dev, sc->perf_ctrl_type, 0, sc->perf_ctrl); bus_delete_resource(sc->dev, sc->perf_ctrl_type, 0); sc->perf_ctrl = NULL; } if (sc->perf_status) { bus_release_resource(sc->dev, sc->perf_sts_type, 1, sc->perf_status); bus_delete_resource(sc->dev, sc->perf_sts_type, 1); sc->perf_status = NULL; } sc->px_rid = 0; sc->px_count = 0; } if (buf.Pointer) AcpiOsFree(buf.Pointer); return (error); }
static void thinkpad_attach(device_t parent, device_t self, void *opaque) { thinkpad_softc_t *sc = device_private(self); struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque; struct sysmon_pswitch *psw; device_t curdev; ACPI_STATUS rv; ACPI_INTEGER val; int i; sc->sc_node = aa->aa_node; sc->sc_dev = self; sc->sc_display_state = THINKPAD_DISPLAY_LCD; aprint_naive("\n"); aprint_normal("\n"); /* T61 uses \UCMS method for issuing CMOS commands */ rv = AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl); if (ACPI_FAILURE(rv)) sc->sc_cmoshdl_valid = false; else { aprint_verbose_dev(self, "using CMOS at \\UCMS\n"); sc->sc_cmoshdl_valid = true; } sc->sc_ecdev = NULL; TAILQ_FOREACH(curdev, &alldevs, dv_list) if (device_is_a(curdev, "acpiecdt") || device_is_a(curdev, "acpiec")) { sc->sc_ecdev = curdev; break; } if (sc->sc_ecdev) aprint_verbose_dev(self, "using EC at %s\n", device_xname(sc->sc_ecdev)); /* Get the supported event mask */ rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKA", &val); if (ACPI_FAILURE(rv)) { aprint_error_dev(self, "couldn't evaluate MHKA: %s\n", AcpiFormatException(rv)); goto fail; } /* Enable all supported events */ rv = thinkpad_mask_init(sc, val); if (ACPI_FAILURE(rv)) { aprint_error_dev(self, "couldn't set event mask: %s\n", AcpiFormatException(rv)); goto fail; } /* Install notify handler for events */ rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, thinkpad_notify_handler, sc); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler: %s\n", AcpiFormatException(rv)); /* Register power switches with sysmon */ psw = sc->sc_smpsw; sc->sc_smpsw_valid = true; psw[TP_PSW_SLEEP].smpsw_name = device_xname(self); psw[TP_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP; #if notyet psw[TP_PSW_HIBERNATE].smpsw_name = device_xname(self); mpsw[TP_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE; #endif for (i = TP_PSW_DISPLAY_CYCLE; i < TP_PSW_LAST; i++) sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY; psw[TP_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE; psw[TP_PSW_LOCK_SCREEN].smpsw_name = PSWITCH_HK_LOCK_SCREEN; psw[TP_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO; psw[TP_PSW_EJECT_BUTTON].smpsw_name = PSWITCH_HK_EJECT_BUTTON; psw[TP_PSW_ZOOM_BUTTON].smpsw_name = PSWITCH_HK_ZOOM_BUTTON; psw[TP_PSW_VENDOR_BUTTON].smpsw_name = PSWITCH_HK_VENDOR_BUTTON; for (i = 0; i < TP_PSW_LAST; i++) { /* not supported yet */ if (i == TP_PSW_HIBERNATE) continue; if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) { aprint_error_dev(self, "couldn't register with sysmon\n"); sc->sc_smpsw_valid = false; break; } } /* Register temperature and fan sensors with envsys */ thinkpad_sensors_init(sc); fail: if (!pmf_device_register(self, NULL, thinkpad_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP, thinkpad_brightness_up, true)) aprint_error_dev(self, "couldn't register event handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, thinkpad_brightness_down, true)) aprint_error_dev(self, "couldn't register event handler\n"); }
static int acpi_cpu_attach(device_t dev) { struct acpi_cpu_softc *sc = device_get_softc(dev); ACPI_HANDLE handle; device_t child; int cpu_id, cpu_features; struct acpi_softc *acpi_sc; sc->cpu_dev = dev; handle = acpi_get_handle(dev); cpu_id = acpi_get_magic(dev); acpi_sc = acpi_device_get_parent_softc(dev); if (cpu_id == 0) { sysctl_ctx_init(&sc->glob_sysctl_ctx); sc->glob_sysctl_tree = SYSCTL_ADD_NODE(&sc->glob_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "cpu", CTLFLAG_RD, 0, "node for CPU global settings"); if (sc->glob_sysctl_tree == NULL) return ENOMEM; } sysctl_ctx_init(&sc->pcpu_sysctl_ctx); sc->pcpu_sysctl_tree = SYSCTL_ADD_NODE(&sc->pcpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, "node for per-CPU settings"); if (sc->pcpu_sysctl_tree == NULL) { sysctl_ctx_free(&sc->glob_sysctl_ctx); return ENOMEM; } /* * Before calling any CPU methods, collect child driver feature hints * and notify ACPI of them. We support unified SMP power control * so advertise this ourselves. Note this is not the same as independent * SMP control where each CPU can have different settings. */ cpu_features = ACPI_PDC_MP_C1PXTX | ACPI_PDC_MP_C2C3; cpu_features |= acpi_cpu_md_features(); /* * CPU capabilities are specified as a buffer of 32-bit integers: * revision, count, and one or more capabilities. */ if (cpu_features) { uint32_t cap_set[3]; ACPI_STATUS status; cap_set[0] = 0; cap_set[1] = cpu_features; status = acpi_eval_osc(dev, handle, "4077A616-290C-47BE-9EBD-D87058713953", 1, cap_set, 2); if (ACPI_FAILURE(status)) { ACPI_OBJECT_LIST arglist; ACPI_OBJECT arg[4]; if (bootverbose) device_printf(dev, "_OSC failed, using _PDC\n"); arglist.Pointer = arg; arglist.Count = 1; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cap_set); arg[0].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 1; /* revision */ cap_set[1] = 1; /* # of capabilities integers */ cap_set[2] = cpu_features; AcpiEvaluateObject(handle, "_PDC", &arglist, NULL); } } ksnprintf(sc->cpu_sensdev.xname, sizeof(sc->cpu_sensdev.xname), "%s", device_get_nameunit(dev)); sensordev_install(&sc->cpu_sensdev); child = BUS_ADD_CHILD(dev, dev, 0, "cpu_cst", -1); if (child == NULL) return ENXIO; acpi_set_handle(child, handle); acpi_set_magic(child, cpu_id); sc->cpu_cst = child; child = BUS_ADD_CHILD(dev, dev, 0, "cpu_pst", -1); if (child == NULL) return ENXIO; acpi_set_handle(child, handle); acpi_set_magic(child, cpu_id); sc->cpu_pst = child; bus_generic_probe(dev); bus_generic_attach(dev); AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, acpi_cpu_notify, sc); return 0; }
ACPI_STATUS AeInstallHandlers (void) { ACPI_STATUS Status; UINT32 i; ACPI_HANDLE Handle; ACPI_FUNCTION_ENTRY (); Status = AcpiInstallTableHandler (AeTableHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install table handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallExceptionHandler (AeExceptionHandler); if (ACPI_FAILURE (Status)) { printf ("Could not install exception handler, %s\n", AcpiFormatException (Status)); } /* Install global notify handler */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY, AeDeviceNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiGetHandle (NULL, "\\_SB", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler); if (ACPI_FAILURE (Status)) { printf ("Could not remove a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler, NULL); Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler); Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); Status = AcpiDetachData (Handle, AeAttachedDataHandler); Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); } else { printf ("No _SB_ found, %s\n", AcpiFormatException (Status)); } /* Set a handler for all supported operation regions */ for (i = 0; i < AEXEC_NUM_REGIONS; i++) { Status = AcpiRemoveAddressSpaceHandler (AcpiGbl_RootNode, SpaceId[i], AeRegionHandler); /* Install handler at the root object. * TBD: all default handlers should be installed here! */ Status = AcpiInstallAddressSpaceHandler (AcpiGbl_RootNode, SpaceId[i], AeRegionHandler, AeRegionInit, NULL); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not install an OpRegion handler for %s space(%u)", AcpiUtGetRegionName((UINT8) SpaceId[i]), SpaceId[i])); return (Status); } } /* * Initialize the global Region Handler space * MCW 3/23/00 */ AeRegions.NumberOfRegions = 0; AeRegions.RegionList = NULL; return Status; }
static int acpi_cpu_attach(device_t dev) { struct acpi_cpux_softc *sc = device_get_softc(dev); ACPI_HANDLE handle; device_t child; int cpu_id, cpu_features; struct acpi_softc *acpi_sc; handle = acpi_get_handle(dev); cpu_id = acpi_get_magic(dev); acpi_sc = acpi_device_get_parent_softc(dev); if (cpu_id == 0) { sysctl_ctx_init(&sc->glob_sysctl_ctx); sc->glob_sysctl_tree = SYSCTL_ADD_NODE(&sc->glob_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "cpu", CTLFLAG_RD, 0, "node for CPU global settings"); if (sc->glob_sysctl_tree == NULL) return ENOMEM; } sysctl_ctx_init(&sc->pcpu_sysctl_ctx); sc->pcpu_sysctl_tree = SYSCTL_ADD_NODE(&sc->pcpu_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, device_get_nameunit(dev), CTLFLAG_RD, 0, "node for per-CPU settings"); if (sc->pcpu_sysctl_tree == NULL) { sysctl_ctx_free(&sc->glob_sysctl_ctx); return ENOMEM; } /* * Before calling any CPU methods, collect child driver feature hints * and notify ACPI of them. We support unified SMP power control * so advertise this ourselves. Note this is not the same as independent * SMP control where each CPU can have different settings. */ cpu_features = ACPI_PDC_MP_C1PXTX | ACPI_PDC_MP_C2C3; cpu_features |= acpi_cpu_md_features(); /* * CPU capabilities are specified as a buffer of 32-bit integers: * revision, count, and one or more capabilities. */ if (cpu_features) { ACPI_OBJECT_LIST arglist; uint32_t cap_set[3]; ACPI_OBJECT arg[4]; ACPI_STATUS status; /* UUID needed by _OSC evaluation */ static uint8_t cpu_oscuuid[16] = { 0x16, 0xA6, 0x77, 0x40, 0x0C, 0x29, 0xBE, 0x47, 0x9E, 0xBD, 0xD8, 0x70, 0x58, 0x71, 0x39, 0x53 }; arglist.Pointer = arg; arglist.Count = 4; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cpu_oscuuid); arg[0].Buffer.Pointer = cpu_oscuuid; /* UUID */ arg[1].Type = ACPI_TYPE_INTEGER; arg[1].Integer.Value = 1; /* revision */ arg[2].Type = ACPI_TYPE_INTEGER; arg[2].Integer.Value = 2; /* # of capabilities integers */ arg[3].Type = ACPI_TYPE_BUFFER; arg[3].Buffer.Length = sizeof(cap_set[0]) * 2; /* capabilities buffer */ arg[3].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 0; cap_set[1] = cpu_features; status = AcpiEvaluateObject(handle, "_OSC", &arglist, NULL); if (!ACPI_SUCCESS(status)) { if (bootverbose) device_printf(dev, "_OSC failed, use _PDC\n"); arglist.Pointer = arg; arglist.Count = 1; arg[0].Type = ACPI_TYPE_BUFFER; arg[0].Buffer.Length = sizeof(cap_set); arg[0].Buffer.Pointer = (uint8_t *)cap_set; cap_set[0] = 1; /* revision */ cap_set[1] = 1; /* # of capabilities integers */ cap_set[2] = cpu_features; AcpiEvaluateObject(handle, "_PDC", &arglist, NULL); } } child = BUS_ADD_CHILD(dev, dev, 0, "cpu_cst", -1); if (child == NULL) return ENXIO; acpi_set_handle(child, handle); acpi_set_magic(child, cpu_id); sc->cpux_cst = child; child = BUS_ADD_CHILD(dev, dev, 0, "cpu_pst", -1); if (child == NULL) return ENXIO; acpi_set_handle(child, handle); acpi_set_magic(child, cpu_id); bus_generic_attach(dev); AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, acpi_cpu_notify, sc); return 0; }
void acpi_secondary_init(void) { ACPI_STATUS Status; ACPI_STATUS DisplayOneDevice (ACPI_HANDLE, UINT32, void *, void **); /* Complete the ACPICA initialization sequence */ Status = AcpiInitializeSubsystem (); if (ACPI_FAILURE (Status)) { DLOG_COM1 ("Failed to initialize ACPI.\n"); } Status = AcpiReallocateRootTable (); if (ACPI_FAILURE (Status)) { DLOG_COM1 ("Failed: AcpiReallocateRootTable %d.\n", Status); } Status = AcpiLoadTables (); if (ACPI_FAILURE (Status)) { DLOG_COM1 ("Failed: AcpiLoadTables.\n"); } Status = AcpiEnableSubsystem (ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE (Status)) { DLOG_COM1 ("Failed: AcpiEnableSubsystem.\n"); } Status = AcpiInitializeObjects (ACPI_FULL_INITIALIZATION); if (ACPI_FAILURE (Status)) { DLOG_COM1 ("Failed: AcpiInitializeObjects.\n"); } /* Must enable IOAPIC before checking any PCI routing tables. */ acpi_enable_IOAPIC (); /* Install System Control Interrupt */ u8 vector = find_unused_vector (MINIMUM_VECTOR_PRIORITY); if (vector) { u64 flags = IOAPIC_DELIVERY_FIXED | IOAPIC_DESTINATION_LOGICAL; u8 gsi = acpi_sci_irq; /* SCI defaults to LEVEL/LOW in IO-APIC mode. */ if ((acpi_sci_flags & ACPI_MADT_POLARITY_MASK) == ACPI_MADT_POLARITY_ACTIVE_HIGH) flags |= IOAPIC_POLARITY_HIGH; else flags |= IOAPIC_POLARITY_LOW; if ((acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) == ACPI_MADT_TRIGGER_EDGE) flags |= IOAPIC_TRIGGER_EDGE; else flags |= IOAPIC_TRIGGER_LEVEL; if (IOAPIC_map_GSI (gsi, vector, 0x0100000000000000ULL | flags) != -1) { set_vector_handler (vector, acpi_irq_handler); DLOG ("ACPI: mapped GSI 0x%X to vector 0x%X (%s, %s)\n", gsi, vector, flags & IOAPIC_TRIGGER_LEVEL ? "level" : "edge", flags & IOAPIC_POLARITY_LOW ? "low" : "high"); } else DLOG ("ACPI: failed to map GSI\n"); } else DLOG ("ACPI: failed to find unused vector\n"); DLOG ("AcpiEnableEvent returned %d\n", AcpiEnableEvent (ACPI_EVENT_POWER_BUTTON, 0)); DLOG ("AcpiInstallFixedEventHandler returned %d\n", AcpiInstallFixedEventHandler (ACPI_EVENT_POWER_BUTTON, acpi_power_button, NULL)); DLOG ("AcpiInstallNotifyHandler returned %d\n", AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, acpi_notify_handler, NULL)); DLOG ("AcpiInstallNotifyHandler returned %d\n", AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY, acpi_notify_handler, NULL)); extern u8 AcpiGbl_OsiData; AcpiGbl_OsiData=0; /* Walk the System Bus "\_SB_" and output info about each object * found. */ #if 0 ACPI_HANDLE SysBusHandle; AcpiGetHandle (ACPI_ROOT_OBJECT, ACPI_NS_SYSTEM_BUS, &SysBusHandle); AcpiWalkNamespace (ACPI_TYPE_ANY, SysBusHandle, INT_MAX, DisplayOneDevice, NULL, NULL); #else AcpiGetDevices (NULL, DisplayOneDevice, NULL, NULL); #endif }
ACPI_STATUS AeInstallEarlyHandlers ( void) { ACPI_STATUS Status; UINT32 i; ACPI_HANDLE Handle; ACPI_FUNCTION_ENTRY (); Status = AcpiInstallInterfaceHandler (AeInterfaceHandler); if (ACPI_FAILURE (Status)) { printf ("Could not install interface handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallTableHandler (AeTableHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install table handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallExceptionHandler (AeExceptionHandler); if (ACPI_FAILURE (Status)) { printf ("Could not install exception handler, %s\n", AcpiFormatException (Status)); } /* Install global notify handlers */ Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, AeSystemNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global system notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (ACPI_ROOT_OBJECT, ACPI_DEVICE_NOTIFY, AeDeviceNotifyHandler, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a global notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiGetHandle (NULL, "\\_SB", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler1, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiRemoveNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler1); if (ACPI_FAILURE (Status)) { printf ("Could not remove a notify handler, %s\n", AcpiFormatException (Status)); } Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler1, NULL); AE_CHECK_OK (AcpiInstallNotifyHandler, Status); Status = AcpiRemoveNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler1); AE_CHECK_OK (AcpiRemoveNotifyHandler, Status); #if 0 Status = AcpiInstallNotifyHandler (Handle, ACPI_ALL_NOTIFY, AeNotifyHandler1, NULL); if (ACPI_FAILURE (Status)) { printf ("Could not install a notify handler, %s\n", AcpiFormatException (Status)); } #endif /* Install two handlers for _SB_ */ Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler1, ACPI_CAST_PTR (void, 0x01234567)); Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler2, ACPI_CAST_PTR (void, 0x89ABCDEF)); /* Attempt duplicate handler installation, should fail */ Status = AcpiInstallNotifyHandler (Handle, ACPI_SYSTEM_NOTIFY, AeNotifyHandler1, ACPI_CAST_PTR (void, 0x77777777)); Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); AE_CHECK_OK (AcpiAttachData, Status); Status = AcpiDetachData (Handle, AeAttachedDataHandler); AE_CHECK_OK (AcpiDetachData, Status); /* Test attach data at the root object */ Status = AcpiAttachData (ACPI_ROOT_OBJECT, AeAttachedDataHandler, AcpiGbl_RootNode); AE_CHECK_OK (AcpiAttachData, Status); Status = AcpiAttachData (ACPI_ROOT_OBJECT, AeAttachedDataHandler2, AcpiGbl_RootNode); AE_CHECK_OK (AcpiAttachData, Status); /* Test support for multiple attaches */ Status = AcpiAttachData (Handle, AeAttachedDataHandler, Handle); AE_CHECK_OK (AcpiAttachData, Status); Status = AcpiAttachData (Handle, AeAttachedDataHandler2, Handle); AE_CHECK_OK (AcpiAttachData, Status); } else {
static int acpi_tz_attach(device_t dev) { struct acpi_tz_softc *sc; struct acpi_softc *acpi_sc; int error; char oidname[8]; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); sc = device_get_softc(dev); sc->tz_dev = dev; sc->tz_handle = acpi_get_handle(dev); sc->tz_requested = TZ_ACTIVE_NONE; sc->tz_active = TZ_ACTIVE_UNKNOWN; sc->tz_thflags = TZ_THFLAG_NONE; sc->tz_cooling_proc = NULL; sc->tz_cooling_proc_running = FALSE; sc->tz_cooling_active = FALSE; sc->tz_cooling_updated = FALSE; sc->tz_cooling_enabled = FALSE; /* * Parse the current state of the thermal zone and build control * structures. We don't need to worry about interference with the * control thread since we haven't fully attached this device yet. */ if ((error = acpi_tz_establish(sc)) != 0) return (error); /* * Register for any Notify events sent to this zone. */ AcpiInstallNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY, acpi_tz_notify_handler, sc); /* * Create our sysctl nodes. * * XXX we need a mechanism for adding nodes under ACPI. */ if (device_get_unit(dev) == 0) { acpi_sc = acpi_device_get_parent_softc(dev); sysctl_ctx_init(&acpi_tz_sysctl_ctx); acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO, "thermal", CTLFLAG_RD, 0, ""); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "min_runtime", CTLFLAG_RW, &acpi_tz_min_runtime, 0, "minimum cooling run time in sec"); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "polling_rate", CTLFLAG_RW, &acpi_tz_polling_rate, 0, "monitor polling interval in seconds"); SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, "user_override", CTLFLAG_RW, &acpi_tz_override, 0, "allow override of thermal settings"); } sysctl_ctx_init(&sc->tz_sysctl_ctx); sprintf(oidname, "tz%d", device_get_unit(dev)); sc->tz_sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, oidname, CTLFLAG_RD, 0, "", "thermal_zone"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, &sc->tz_temperature, 0, sysctl_handle_int, "IK", "current thermal zone temperature"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW, sc, 0, acpi_tz_active_sysctl, "I", "cooling is active"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "passive_cooling", CTLTYPE_INT | CTLFLAG_RW, sc, 0, acpi_tz_cooling_sysctl, "I", "enable passive (speed reduction) cooling"); SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "thermal_flags", CTLFLAG_RD, &sc->tz_thflags, 0, "thermal zone flags"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.psv), acpi_tz_temp_sysctl, "IK", "passive cooling temp setpoint"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK", "too hot temp setpoint (suspend now)"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_CRT", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.crt), acpi_tz_temp_sysctl, "IK", "critical temp setpoint (shutdown now)"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_ACx", CTLTYPE_INT | CTLFLAG_RD, &sc->tz_zone.ac, sizeof(sc->tz_zone.ac), sysctl_handle_opaque, "IK", ""); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TC1", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tc1), acpi_tz_passive_sysctl, "I", "thermal constant 1 for passive cooling"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TC2", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tc2), acpi_tz_passive_sysctl, "I", "thermal constant 2 for passive cooling"); SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), OID_AUTO, "_TSP", CTLTYPE_INT | CTLFLAG_RW, sc, offsetof(struct acpi_tz_softc, tz_zone.tsp), acpi_tz_passive_sysctl, "I", "thermal sampling period for passive cooling"); /* * Register our power profile event handler. */ sc->tz_event = EVENTHANDLER_REGISTER(power_profile_change, acpi_tz_power_profile, sc, 0); /* * Flag the event handler for a manual invocation by our timeout. * We defer it like this so that the rest of the subsystem has time * to come up. Don't bother evaluating/printing the temperature at * this point; on many systems it'll be bogus until the EC is running. */ sc->tz_flags |= TZ_FLAG_GETPROFILE; return_VALUE (0); }