aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorAaron Lu <aaron.lu@intel.com>2014-05-21 04:33:27 -0400
committerZhang Rui <rui.zhang@intel.com>2014-06-29 22:17:27 -0400
commite8db5d6736a712a3e2280c0e31f4b301d85172d8 (patch)
tree046ef84dcb4d9395070b0491da0f6bc0f9914a2f /drivers/thermal
parentf14d1c24c64bec45c01b0bc7b0dde2e54a797662 (diff)
thermal: hwmon: Make the check for critical temp valid consistent
On 05/21/2014 04:22 PM, Aaron Lu wrote: > On 05/21/2014 01:57 PM, Kui Zhang wrote: >> Hello, >> >> I get following error when rmmod thermal. >> >> rmmod thermal >> Killed While dealing with this problem, I found another problem that also results in a kernel crash on thermal module removal: From: Aaron Lu <aaron.lu@intel.com> Date: Wed, 21 May 2014 16:05:38 +0800 Subject: [PATCH] thermal: hwmon: Make the check for critical temp valid consistent We used the tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, temp) to decide if we need to create the temp_crit attribute file but we just check if tz->ops->get_crit_temp exists to decide if we need to remove that attribute file. Some ACPI thermal zone doesn't have a valid critical trip point and that would result in removing a non-existent device file on thermal module unload. Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Aaron Lu <aaron.lu@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/thermal_hwmon.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index fdb07199d9c2..1967bee4f076 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -140,6 +140,12 @@ thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
140 return NULL; 140 return NULL;
141} 141}
142 142
143static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz)
144{
145 unsigned long temp;
146 return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp);
147}
148
143int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) 149int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
144{ 150{
145 struct thermal_hwmon_device *hwmon; 151 struct thermal_hwmon_device *hwmon;
@@ -189,21 +195,18 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
189 if (result) 195 if (result)
190 goto free_temp_mem; 196 goto free_temp_mem;
191 197
192 if (tz->ops->get_crit_temp) { 198 if (thermal_zone_crit_temp_valid(tz)) {
193 unsigned long temperature; 199 snprintf(temp->temp_crit.name,
194 if (!tz->ops->get_crit_temp(tz, &temperature)) { 200 sizeof(temp->temp_crit.name),
195 snprintf(temp->temp_crit.name,
196 sizeof(temp->temp_crit.name),
197 "temp%d_crit", hwmon->count); 201 "temp%d_crit", hwmon->count);
198 temp->temp_crit.attr.attr.name = temp->temp_crit.name; 202 temp->temp_crit.attr.attr.name = temp->temp_crit.name;
199 temp->temp_crit.attr.attr.mode = 0444; 203 temp->temp_crit.attr.attr.mode = 0444;
200 temp->temp_crit.attr.show = temp_crit_show; 204 temp->temp_crit.attr.show = temp_crit_show;
201 sysfs_attr_init(&temp->temp_crit.attr.attr); 205 sysfs_attr_init(&temp->temp_crit.attr.attr);
202 result = device_create_file(hwmon->device, 206 result = device_create_file(hwmon->device,
203 &temp->temp_crit.attr); 207 &temp->temp_crit.attr);
204 if (result) 208 if (result)
205 goto unregister_input; 209 goto unregister_input;
206 }
207 } 210 }
208 211
209 mutex_lock(&thermal_hwmon_list_lock); 212 mutex_lock(&thermal_hwmon_list_lock);
@@ -250,7 +253,7 @@ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
250 } 253 }
251 254
252 device_remove_file(hwmon->device, &temp->temp_input.attr); 255 device_remove_file(hwmon->device, &temp->temp_input.attr);
253 if (tz->ops->get_crit_temp) 256 if (thermal_zone_crit_temp_valid(tz))
254 device_remove_file(hwmon->device, &temp->temp_crit.attr); 257 device_remove_file(hwmon->device, &temp->temp_crit.attr);
255 258
256 mutex_lock(&thermal_hwmon_list_lock); 259 mutex_lock(&thermal_hwmon_list_lock);