Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 262285
b: refs/heads/master
c: 31f5396
h: refs/heads/master
i:
  262283: 0885fd6
v: v3
  • Loading branch information
Jean Delvare authored and Len Brown committed Aug 2, 2011
1 parent ed959bd commit af2fc14
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0d97d7a494d43be77f57e688369be0aae33d1ade
refs/heads/master: 31f5396ad3bde23c8416e8d23ba425e27f413314
117 changes: 92 additions & 25 deletions trunk/drivers/thermal/thermal_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,29 @@ thermal_cooling_device_trip_point_show(struct device *dev,

/* hwmon sys I/F */
#include <linux/hwmon.h>

/* thermal zone devices with the same type share one hwmon device */
struct thermal_hwmon_device {
char type[THERMAL_NAME_LENGTH];
struct device *device;
int count;
struct list_head tz_list;
struct list_head node;
};

struct thermal_hwmon_attr {
struct device_attribute attr;
char name[16];
};

/* one temperature input for each thermal zone */
struct thermal_hwmon_temp {
struct list_head hwmon_node;
struct thermal_zone_device *tz;
struct thermal_hwmon_attr temp_input; /* hwmon sys attr */
struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */
};

static LIST_HEAD(thermal_hwmon_list);

static ssize_t
Expand All @@ -437,9 +460,10 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
int ret;
struct thermal_hwmon_attr *hwmon_attr
= container_of(attr, struct thermal_hwmon_attr, attr);
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
struct thermal_hwmon_temp *temp
= container_of(hwmon_attr, struct thermal_hwmon_temp,
temp_input);
struct thermal_zone_device *tz = temp->tz;

ret = tz->ops->get_temp(tz, &temperature);

Expand All @@ -455,9 +479,10 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
{
struct thermal_hwmon_attr *hwmon_attr
= container_of(attr, struct thermal_hwmon_attr, attr);
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
struct thermal_hwmon_temp *temp
= container_of(hwmon_attr, struct thermal_hwmon_temp,
temp_crit);
struct thermal_zone_device *tz = temp->tz;
long temperature;
int ret;

Expand Down Expand Up @@ -485,10 +510,29 @@ thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
return NULL;
}

/* Find the temperature input matching a given thermal zone */
static struct thermal_hwmon_temp *
thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon,
const struct thermal_zone_device *tz)
{
struct thermal_hwmon_temp *temp;

mutex_lock(&thermal_list_lock);
list_for_each_entry(temp, &hwmon->tz_list, hwmon_node)
if (temp->tz == tz) {
mutex_unlock(&thermal_list_lock);
return temp;
}
mutex_unlock(&thermal_list_lock);

return NULL;
}

static int
thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
{
struct thermal_hwmon_device *hwmon;
struct thermal_hwmon_temp *temp;
int new_hwmon_device = 1;
int result;

Expand All @@ -515,30 +559,36 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
goto free_mem;

register_sys_interface:
tz->hwmon = hwmon;
temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL);
if (!temp) {
result = -ENOMEM;
goto unregister_name;
}

temp->tz = tz;
hwmon->count++;

snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH,
snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH,
"temp%d_input", hwmon->count);
tz->temp_input.attr.attr.name = tz->temp_input.name;
tz->temp_input.attr.attr.mode = 0444;
tz->temp_input.attr.show = temp_input_show;
sysfs_attr_init(&tz->temp_input.attr.attr);
result = device_create_file(hwmon->device, &tz->temp_input.attr);
temp->temp_input.attr.attr.name = temp->temp_input.name;
temp->temp_input.attr.attr.mode = 0444;
temp->temp_input.attr.show = temp_input_show;
sysfs_attr_init(&temp->temp_input.attr.attr);
result = device_create_file(hwmon->device, &temp->temp_input.attr);
if (result)
goto unregister_name;
goto free_temp_mem;

if (tz->ops->get_crit_temp) {
unsigned long temperature;
if (!tz->ops->get_crit_temp(tz, &temperature)) {
snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH,
snprintf(temp->temp_crit.name, THERMAL_NAME_LENGTH,
"temp%d_crit", hwmon->count);
tz->temp_crit.attr.attr.name = tz->temp_crit.name;
tz->temp_crit.attr.attr.mode = 0444;
tz->temp_crit.attr.show = temp_crit_show;
sysfs_attr_init(&tz->temp_crit.attr.attr);
temp->temp_crit.attr.attr.name = temp->temp_crit.name;
temp->temp_crit.attr.attr.mode = 0444;
temp->temp_crit.attr.show = temp_crit_show;
sysfs_attr_init(&temp->temp_crit.attr.attr);
result = device_create_file(hwmon->device,
&tz->temp_crit.attr);
&temp->temp_crit.attr);
if (result)
goto unregister_input;
}
Expand All @@ -547,13 +597,15 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
mutex_lock(&thermal_list_lock);
if (new_hwmon_device)
list_add_tail(&hwmon->node, &thermal_hwmon_list);
list_add_tail(&tz->hwmon_node, &hwmon->tz_list);
list_add_tail(&temp->hwmon_node, &hwmon->tz_list);
mutex_unlock(&thermal_list_lock);

return 0;

unregister_input:
device_remove_file(hwmon->device, &tz->temp_input.attr);
device_remove_file(hwmon->device, &temp->temp_input.attr);
free_temp_mem:
kfree(temp);
unregister_name:
if (new_hwmon_device) {
device_remove_file(hwmon->device, &dev_attr_name);
Expand All @@ -569,15 +621,30 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
static void
thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
{
struct thermal_hwmon_device *hwmon = tz->hwmon;
struct thermal_hwmon_device *hwmon;
struct thermal_hwmon_temp *temp;

hwmon = thermal_hwmon_lookup_by_type(tz);
if (unlikely(!hwmon)) {
/* Should never happen... */
dev_dbg(&tz->device, "hwmon device lookup failed!\n");
return;
}

temp = thermal_hwmon_lookup_temp(hwmon, tz);
if (unlikely(!temp)) {
/* Should never happen... */
dev_dbg(&tz->device, "temperature input lookup failed!\n");
return;
}

tz->hwmon = NULL;
device_remove_file(hwmon->device, &tz->temp_input.attr);
device_remove_file(hwmon->device, &temp->temp_input.attr);
if (tz->ops->get_crit_temp)
device_remove_file(hwmon->device, &tz->temp_crit.attr);
device_remove_file(hwmon->device, &temp->temp_crit.attr);

mutex_lock(&thermal_list_lock);
list_del(&tz->hwmon_node);
list_del(&temp->hwmon_node);
kfree(temp);
if (!list_empty(&hwmon->tz_list)) {
mutex_unlock(&thermal_list_lock);
return;
Expand Down
22 changes: 0 additions & 22 deletions trunk/include/linux/thermal.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,6 @@ struct thermal_cooling_device {
((long)t-2732+5)/10 : ((long)t-2732-5)/10)
#define CELSIUS_TO_KELVIN(t) ((t)*10+2732)

#if defined(CONFIG_THERMAL_HWMON)
/* thermal zone devices with the same type share one hwmon device */
struct thermal_hwmon_device {
char type[THERMAL_NAME_LENGTH];
struct device *device;
int count;
struct list_head tz_list;
struct list_head node;
};

struct thermal_hwmon_attr {
struct device_attribute attr;
char name[16];
};
#endif

struct thermal_zone_device {
int id;
char type[THERMAL_NAME_LENGTH];
Expand All @@ -120,12 +104,6 @@ struct thermal_zone_device {
struct mutex lock; /* protect cooling devices list */
struct list_head node;
struct delayed_work poll_queue;
#if defined(CONFIG_THERMAL_HWMON)
struct list_head hwmon_node;
struct thermal_hwmon_device *hwmon;
struct thermal_hwmon_attr temp_input; /* hwmon sys attr */
struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */
#endif
};
/* Adding event notification support elements */
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
Expand Down

0 comments on commit af2fc14

Please sign in to comment.