Ejemplo n.º 1
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);

	/* 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);
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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;
}