diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-05-11 14:44:27 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-05-11 14:44:31 +0200 | 
| commit | 41fb454ebe6024f5c1e3b3cbc0abc0da762e7b51 (patch) | |
| tree | 51c50bcb67a5039448ddfa1869d7948cab1217e9 /drivers/acpi/thermal.c | |
| parent | 19c1a6f5764d787113fa323ffb18be7991208f82 (diff) | |
| parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) | |
Merge commit 'v2.6.30-rc5' into core/iommu
Merge reason: core/iommu was on an .30-rc1 base,
              update it to .30-rc5 to refresh.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/acpi/thermal.c')
| -rw-r--r-- | drivers/acpi/thermal.c | 70 | 
1 files changed, 39 insertions, 31 deletions
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index e8c143caf0f..564ea142428 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -98,6 +98,7 @@ MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");  static int acpi_thermal_add(struct acpi_device *device);  static int acpi_thermal_remove(struct acpi_device *device, int type);  static int acpi_thermal_resume(struct acpi_device *device); +static void acpi_thermal_notify(struct acpi_device *device, u32 event);  static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);  static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);  static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); @@ -123,6 +124,7 @@ static struct acpi_driver acpi_thermal_driver = {  		.add = acpi_thermal_add,  		.remove = acpi_thermal_remove,  		.resume = acpi_thermal_resume, +		.notify = acpi_thermal_notify,  		},  }; @@ -192,6 +194,7 @@ struct acpi_thermal {  	struct acpi_handle_list devices;  	struct thermal_zone_device *thermal_zone;  	int tz_enabled; +	int kelvin_offset;  	struct mutex lock;  }; @@ -581,7 +584,7 @@ static void acpi_thermal_check(void *data)  }  /* sys I/F for generic thermal sysfs support */ -#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) +#define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)  static int thermal_get_temp(struct thermal_zone_device *thermal,  			    unsigned long *temp) @@ -596,7 +599,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal,  	if (result)  		return result; -	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature); +	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);  	return 0;  } @@ -702,7 +705,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,  	if (tz->trips.critical.flags.valid) {  		if (!trip) {  			*temp = KELVIN_TO_MILLICELSIUS( -				tz->trips.critical.temperature); +				tz->trips.critical.temperature, +				tz->kelvin_offset);  			return 0;  		}  		trip--; @@ -711,7 +715,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,  	if (tz->trips.hot.flags.valid) {  		if (!trip) {  			*temp = KELVIN_TO_MILLICELSIUS( -				tz->trips.hot.temperature); +				tz->trips.hot.temperature, +				tz->kelvin_offset);  			return 0;  		}  		trip--; @@ -720,7 +725,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,  	if (tz->trips.passive.flags.valid) {  		if (!trip) {  			*temp = KELVIN_TO_MILLICELSIUS( -				tz->trips.passive.temperature); +				tz->trips.passive.temperature, +				tz->kelvin_offset);  			return 0;  		}  		trip--; @@ -730,7 +736,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,  		tz->trips.active[i].flags.valid; i++) {  		if (!trip) {  			*temp = KELVIN_TO_MILLICELSIUS( -				tz->trips.active[i].temperature); +				tz->trips.active[i].temperature, +				tz->kelvin_offset);  			return 0;  		}  		trip--; @@ -745,7 +752,8 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,  	if (tz->trips.critical.flags.valid) {  		*temperature = KELVIN_TO_MILLICELSIUS( -				tz->trips.critical.temperature); +				tz->trips.critical.temperature, +				tz->kelvin_offset);  		return 0;  	} else  		return -EINVAL; @@ -901,7 +909,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)  			thermal_zone_device_register("acpitz", trips, tz,  						     &acpi_thermal_zone_ops,  						     0, 0, 0, -						     tz->polling_frequency); +						     tz->polling_frequency*100);  	if (IS_ERR(tz->thermal_zone))  		return -ENODEV; @@ -1264,17 +1272,14 @@ static int acpi_thermal_remove_fs(struct acpi_device *device)                                   Driver Interface     -------------------------------------------------------------------------- */ -static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) +static void acpi_thermal_notify(struct acpi_device *device, u32 event)  { -	struct acpi_thermal *tz = data; -	struct acpi_device *device = NULL; +	struct acpi_thermal *tz = acpi_driver_data(device);  	if (!tz)  		return; -	device = tz->device; -  	switch (event) {  	case ACPI_THERMAL_NOTIFY_TEMPERATURE:  		acpi_thermal_check(tz); @@ -1298,8 +1303,6 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)  				  "Unsupported event [0x%x]\n", event));  		break;  	} - -	return;  }  static int acpi_thermal_get_info(struct acpi_thermal *tz) @@ -1334,10 +1337,28 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz)  	return 0;  } +/* + * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI + * handles temperature values with a single decimal place. As a consequence, + * some implementations use an offset of 273.1 and others use an offset of + * 273.2. Try to find out which one is being used, to present the most + * accurate and visually appealing number. + * + * The heuristic below should work for all ACPI thermal zones which have a + * critical trip point with a value being a multiple of 0.5 degree Celsius. + */ +static void acpi_thermal_guess_offset(struct acpi_thermal *tz) +{ +	if (tz->trips.critical.flags.valid && +	    (tz->trips.critical.temperature % 5) == 1) +		tz->kelvin_offset = 2731; +	else +		tz->kelvin_offset = 2732; +} +  static int acpi_thermal_add(struct acpi_device *device)  {  	int result = 0; -	acpi_status status = AE_OK;  	struct acpi_thermal *tz = NULL; @@ -1360,6 +1381,8 @@ static int acpi_thermal_add(struct acpi_device *device)  	if (result)  		goto free_memory; +	acpi_thermal_guess_offset(tz); +  	result = acpi_thermal_register_thermal_zone(tz);  	if (result)  		goto free_memory; @@ -1368,21 +1391,11 @@ static int acpi_thermal_add(struct acpi_device *device)  	if (result)  		goto unregister_thermal_zone; -	status = acpi_install_notify_handler(device->handle, -					     ACPI_DEVICE_NOTIFY, -					     acpi_thermal_notify, tz); -	if (ACPI_FAILURE(status)) { -		result = -ENODEV; -		goto remove_fs; -	} -  	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",  	       acpi_device_name(device), acpi_device_bid(device),  	       KELVIN_TO_CELSIUS(tz->temperature));  	goto end; -remove_fs: -	acpi_thermal_remove_fs(device);  unregister_thermal_zone:  	thermal_zone_device_unregister(tz->thermal_zone);  free_memory: @@ -1393,7 +1406,6 @@ end:  static int acpi_thermal_remove(struct acpi_device *device, int type)  { -	acpi_status status = AE_OK;  	struct acpi_thermal *tz = NULL;  	if (!device || !acpi_driver_data(device)) @@ -1401,10 +1413,6 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)  	tz = acpi_driver_data(device); -	status = acpi_remove_notify_handler(device->handle, -					    ACPI_DEVICE_NOTIFY, -					    acpi_thermal_notify); -  	acpi_thermal_remove_fs(device);  	acpi_thermal_unregister_thermal_zone(tz);  	mutex_destroy(&tz->lock);  | 
