⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thermal.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
}static intacpi_thermal_hot (	struct acpi_thermal	*tz){	int			result = 0;	struct acpi_device	*device = NULL;	ACPI_FUNCTION_TRACE("acpi_thermal_hot");	if (!tz || !tz->trips.hot.flags.valid)		return_VALUE(-EINVAL);	if (tz->temperature >= tz->trips.hot.temperature) {		ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n"));		tz->trips.hot.flags.enabled = 1;	}	else if (tz->trips.hot.flags.enabled)		tz->trips.hot.flags.enabled = 0;	result = acpi_bus_get_device(tz->handle, &device);	if (result)		return_VALUE(result);	acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled);	/* TBD: Call user-mode "sleep(S4)" function */	return_VALUE(0);}static intacpi_thermal_passive (	struct acpi_thermal	*tz){	int			result = 0;	struct acpi_thermal_passive *passive = NULL;	int			trend = 0;	int			i = 0;	ACPI_FUNCTION_TRACE("acpi_thermal_passive");	if (!tz || !tz->trips.passive.flags.valid)		return_VALUE(-EINVAL);	passive = &(tz->trips.passive);	/*	 * Above Trip?	 * -----------	 * Calculate the thermal trend (using the passive cooling equation)	 * and modify the performance limit for all passive cooling devices	 * accordingly.  Note that we assume symmetry.	 */	if (tz->temperature >= passive->temperature) {		trend = (passive->tc1 * (tz->temperature - tz->last_temperature)) + (passive->tc2 * (tz->temperature - passive->temperature));		ACPI_DEBUG_PRINT((ACPI_DB_INFO, 			"trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", 			trend, passive->tc1, tz->temperature, 			tz->last_temperature, passive->tc2, 			tz->temperature, passive->temperature));		tz->trips.passive.flags.enabled = 1;		/* Heating up? */		if (trend > 0)			for (i=0; i<passive->devices.count; i++)				acpi_processor_set_thermal_limit(					passive->devices.handles[i], 					ACPI_PROCESSOR_LIMIT_INCREMENT);		/* Cooling off? */		else if (trend < 0)			for (i=0; i<passive->devices.count; i++)				acpi_processor_set_thermal_limit(					passive->devices.handles[i], 					ACPI_PROCESSOR_LIMIT_DECREMENT);	}	/*	 * Below Trip?	 * -----------	 * Implement passive cooling hysteresis to slowly increase performance	 * and avoid thrashing around the passive trip point.  Note that we	 * assume symmetry.	 */	else if (tz->trips.passive.flags.enabled) {		for (i=0; i<passive->devices.count; i++)			result = acpi_processor_set_thermal_limit(				passive->devices.handles[i], 				ACPI_PROCESSOR_LIMIT_DECREMENT);		if (result == 1) {			tz->trips.passive.flags.enabled = 0;			ACPI_DEBUG_PRINT((ACPI_DB_INFO, 				"Disabling passive cooling (zone is cool)\n"));		}	}	return_VALUE(0);}static intacpi_thermal_active (	struct acpi_thermal	*tz){	int			result = 0;	struct acpi_thermal_active *active = NULL;	int                     i = 0;	int			j = 0;	unsigned long		maxtemp = 0;	ACPI_FUNCTION_TRACE("acpi_thermal_active");	if (!tz)		return_VALUE(-EINVAL);	for (i=0; i<ACPI_THERMAL_MAX_ACTIVE; i++) {		active = &(tz->trips.active[i]);		if (!active || !active->flags.valid)			break;		/*		 * Above Threshold?		 * ----------------		 * If not already enabled, turn ON all cooling devices		 * associated with this active threshold.		 */		if (tz->temperature >= active->temperature) {			if (active->temperature > maxtemp)				tz->state.active_index = i, maxtemp = active->temperature;			if (!active->flags.enabled) {				for (j = 0; j < active->devices.count; j++) {					result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D0);					if (result) {						ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'on'\n", active->devices.handles[j]));						continue;					}					active->flags.enabled = 1;					ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'on'\n", active->devices.handles[j]));				}			}		}		/*		 * Below Threshold?		 * ----------------		 * Turn OFF all cooling devices associated with this		 * threshold.		 */		else if (active->flags.enabled) {			for (j = 0; j < active->devices.count; j++) {				result = acpi_bus_set_power(active->devices.handles[j], ACPI_STATE_D3);				if (result) {					ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to turn cooling device [%p] 'off'\n", active->devices.handles[j]));					continue;				}				active->flags.enabled = 0;				ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling device [%p] now 'off'\n", active->devices.handles[j]));			}		}	}	return_VALUE(0);}static void acpi_thermal_check (void *context);static voidacpi_thermal_run (	unsigned long		data){	struct acpi_thermal *tz = (struct acpi_thermal *)data;	if (!tz->zombie)		acpi_os_queue_for_execution(OSD_PRIORITY_GPE,  			acpi_thermal_check, (void *) data);}static voidacpi_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;	ACPI_FUNCTION_TRACE("acpi_thermal_check");	if (!tz) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));		return_VOID;	}	state = tz->state;	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;}/* --------------------------------------------------------------------------                              FS Interface (/proc)   -------------------------------------------------------------------------- */struct proc_dir_entry		*acpi_thermal_dir;static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset){	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;	ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show");	if (!tz)		goto end;	seq_puts(seq, "state:                   ");	if (!tz->state.critical && !tz->state.hot && !tz->state.passive && !tz->state.active)		seq_puts(seq, "ok\n");	else {		if (tz->state.critical)			seq_puts(seq, "critical ");		if (tz->state.hot)			seq_puts(seq, "hot ");		if (tz->state.passive)			seq_puts(seq, "passive ");		if (tz->state.active)			seq_printf(seq, "active[%d]", tz->state.active_index);		seq_puts(seq, "\n");	}end:	return 0;}static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);}static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset){	int			result = 0;	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;	ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show");	if (!tz)		goto end;	result = acpi_thermal_get_temperature(tz);	if (result)		goto end;	seq_printf(seq, "temperature:             %ld C\n", 		KELVIN_TO_CELSIUS(tz->temperature));end:	return 0;}static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);}static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset){	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;	int			i = 0;	int			j = 0;	ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show");	if (!tz)		goto end;	if (tz->trips.critical.flags.valid)		seq_printf(seq, "critical (S5):           %ld C\n",			KELVIN_TO_CELSIUS(tz->trips.critical.temperature));	if (tz->trips.hot.flags.valid)		seq_printf(seq, "hot (S4):                %ld C\n",			KELVIN_TO_CELSIUS(tz->trips.hot.temperature));	if (tz->trips.passive.flags.valid) {		seq_printf(seq, "passive:                 %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",			KELVIN_TO_CELSIUS(tz->trips.passive.temperature),			tz->trips.passive.tc1,			tz->trips.passive.tc2, 			tz->trips.passive.tsp);		for (j=0; j<tz->trips.passive.devices.count; j++) {			seq_printf(seq, "0x%p ", tz->trips.passive.devices.handles[j]);		}		seq_puts(seq, "\n");	}	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {		if (!(tz->trips.active[i].flags.valid))			break;		seq_printf(seq, "active[%d]:               %ld C: devices=",			i, KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));		for (j = 0; j < tz->trips.active[i].devices.count; j++) 			seq_printf(seq, "0x%p ",				tz->trips.active[i].devices.handles[j]);		seq_puts(seq, "\n");	}end:	return 0;}static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file){	return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);}static ssize_tacpi_thermal_write_trip_points (        struct file		*file,        const char		__user *buffer,        size_t			count,        loff_t			*ppos){	struct seq_file		*m = (struct seq_file *)file->private_data;	struct acpi_thermal	*tz = (struct acpi_thermal *)m->private;	char			limit_string[65] = {'\0'};	int			num, critical, hot, passive;	int			active[ACPI_THERMAL_MAX_ACTIVE];	int			i = 0;	ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");	if (!tz || (count > sizeof(limit_string) - 1)) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));		return_VALUE(-EINVAL);	}		if (copy_from_user(limit_string, buffer, count)) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));		return_VALUE(-EFAULT);	}		limit_string[count] = '\0';	num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",				&critical, &hot, &passive,				&active[0], &active[1], &active[2], &active[3], &active[4],				&active[5], &active[6], &active[7], &active[8], &active[9]);	if(!(num >=5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {		ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));		return_VALUE(-EINVAL);	}	tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);	tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot);	tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive);	for (i = 0; i < num - 3; i++) {		if (!(tz->trips.active[i].flags.valid))			break;		tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);	}		return_VALUE(count);}static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset){	struct acpi_thermal	*tz = (struct acpi_thermal *)seq->private;	ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show");	if (!tz)		goto end;	if (!tz->flags.cooling_mode) {		seq_puts(seq, "<setting not supported>\n");	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -