static int acpi_thermal_remove ( struct acpi_device *device, int type) { acpi_status status = AE_OK; struct acpi_thermal *tz = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_remove"); if (!device || !acpi_driver_data(device)) return_VALUE(-EINVAL); tz = (struct acpi_thermal *) acpi_driver_data(device); /* avoid timer adding new defer task */ tz->zombie = 1; /* wait for running timer (on other CPUs) finish */ delete_timer( tz->timer ); /* synchronize deferred task */ acpi_os_wait_events_complete(NULL); status = acpi_remove_notify_handler(tz->handle, ACPI_DEVICE_NOTIFY, acpi_thermal_notify); if (ACPI_FAILURE(status)) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n")); /* Terminate policy */ if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { tz->trips.passive.flags.enabled = 0; acpi_thermal_passive(tz); } if (tz->trips.active[0].flags.valid && tz->trips.active[0].flags.enabled) { tz->trips.active[0].flags.enabled = 0; acpi_thermal_active(tz); } kfree(tz); return_VALUE(0); }
static int acpi_thermal_remove ( struct acpi_device *device, int type) { acpi_status status = AE_OK; struct acpi_thermal *tz = NULL; ACPI_FUNCTION_TRACE("acpi_thermal_remove"); if (!device || !acpi_driver_data(device)) return_VALUE(-EINVAL); tz = (struct acpi_thermal *) acpi_driver_data(device); if (timer_pending(&(tz->timer))) del_timer(&(tz->timer)); status = acpi_remove_notify_handler(tz->handle, ACPI_DEVICE_NOTIFY, acpi_thermal_notify); if (ACPI_FAILURE(status)) ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Error removing notify handler\n")); /* Terminate policy */ if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { tz->trips.passive.flags.enabled = 0; acpi_thermal_passive(tz); } if (tz->trips.active[0].flags.valid && tz->trips.active[0].flags.enabled) { tz->trips.active[0].flags.enabled = 0; acpi_thermal_active(tz); } acpi_thermal_remove_fs(device); return_VALUE(0); }
static void acpi_thermal_check ( void *data) { int result = 0; struct acpi_thermal *tz = (struct acpi_thermal *) data; unsigned long sleep_time = 0; int i = 0; struct acpi_thermal_state state = tz->state; ACPI_FUNCTION_TRACE("acpi_thermal_check"); if (!tz) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); return_VOID; } result = acpi_thermal_get_temperature(tz); if (result) return_VOID; memset(&tz->state, 0, sizeof(tz->state)); /* * Check Trip Points * ----------------- * Compare the current temperature to the trip point values to see * if we've entered one of the thermal policy states. Note that * this function determines when a state is entered, but the * individual policy decides when it is exited (e.g. hysteresis). */ if (tz->trips.critical.flags.valid) state.critical |= (tz->temperature >= tz->trips.critical.temperature); if (tz->trips.hot.flags.valid) state.hot |= (tz->temperature >= tz->trips.hot.temperature); if (tz->trips.passive.flags.valid) state.passive |= (tz->temperature >= tz->trips.passive.temperature); for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) if (tz->trips.active[i].flags.valid) state.active |= (tz->temperature >= tz->trips.active[i].temperature); /* * Invoke Policy * ------------- * Separated from the above check to allow individual policy to * determine when to exit a given state. */ if (state.critical) acpi_thermal_critical(tz); if (state.hot) acpi_thermal_hot(tz); if (state.passive) acpi_thermal_passive(tz); if (state.active) acpi_thermal_active(tz); /* * Calculate State * --------------- * Again, separated from the above two to allow independent policy * decisions. */ if (tz->trips.critical.flags.enabled) tz->state.critical = 1; if (tz->trips.hot.flags.enabled) tz->state.hot = 1; if (tz->trips.passive.flags.enabled) tz->state.passive = 1; for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) if (tz->trips.active[i].flags.enabled) tz->state.active = 1; /* * Calculate Sleep Time * -------------------- * If we're in the passive state, use _TSP's value. Otherwise * use the default polling frequency (e.g. _TZP). If no polling * frequency is specified then we'll wait forever (at least until * a thermal event occurs). Note that _TSP and _TZD values are * given in 1/10th seconds (we must covert to milliseconds). */ if (tz->state.passive) sleep_time = tz->trips.passive.tsp * 100; else if (tz->polling_frequency > 0) sleep_time = tz->polling_frequency * 100; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", tz->name, tz->temperature, sleep_time)); /* * Schedule Next Poll * ------------------ */ if (!sleep_time) { if (timer_pending(&(tz->timer))) del_timer(&(tz->timer)); } else { if (timer_pending(&(tz->timer))) mod_timer(&(tz->timer), (HZ * sleep_time) / 1000); else { tz->timer.data = (unsigned long) tz; tz->timer.function = acpi_thermal_run; tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; add_timer(&(tz->timer)); } } return_VOID; }