/*
 * acpitz_attach: autoconf(9) attach routine
 */
static void
acpitz_attach(device_t parent, device_t self, void *aux)
{
    struct acpitz_softc *sc = device_private(self);
    struct acpi_attach_args *aa = aux;
    ACPI_INTEGER val;
    ACPI_STATUS rv;

    sc->sc_first = true;
    sc->sc_have_fan = false;
    sc->sc_node = aa->aa_node;
    sc->sc_zone.tzp = ATZ_TZP_RATE;

    aprint_naive("\n");
    acpitz_print_processor_list(self);
    aprint_normal("\n");

    /*
     * The _TZP (ACPI 4.0, p. 430) defines the recommended
     * polling interval (in tenths of seconds). A value zero
     * means that polling "should not be necessary".
     */
    rv = acpi_eval_integer(sc->sc_node->ad_handle, "_TZP", &val);

    if (ACPI_SUCCESS(rv) && val != 0)
        sc->sc_zone.tzp = val;

    aprint_debug_dev(self, "polling interval %d.%d seconds\n",
                     sc->sc_zone.tzp / 10, sc->sc_zone.tzp % 10);

    sc->sc_zone_expire = ATZ_ZONE_EXPIRE / sc->sc_zone.tzp;

    /*
     * XXX: The fan controls seen here are available on
     *	some HP laptops. Arguably these should not
     *	appear in a generic device driver like this.
     */
    if (acpitz_get_fanspeed(self, &sc->sc_zone.fanmin,
                            &sc->sc_zone.fanmax, &sc->sc_zone.fancurrent) == 0)
        sc->sc_have_fan = true;

    acpitz_get_zone(self, 1);
    acpitz_get_status(self);

    (void)pmf_device_register(self, NULL, NULL);
    (void)acpi_power_register(sc->sc_node->ad_handle);
    (void)acpi_register_notify(sc->sc_node, acpitz_notify_handler);

    callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
    callout_setfunc(&sc->sc_callout, acpitz_tick, self);

    acpitz_init_envsys(self);

    callout_schedule(&sc->sc_callout, sc->sc_zone.tzp * hz / 10);
}
Example #2
0
/*
 * 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);
}