aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/thermal/thermal_sys.c90
-rw-r--r--include/linux/thermal.h16
2 files changed, 106 insertions, 0 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index dca3bfc0e702..0afd84cb127d 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -49,7 +49,86 @@ static DEFINE_MUTEX(thermal_idr_lock);
49 49
50static LIST_HEAD(thermal_tz_list); 50static LIST_HEAD(thermal_tz_list);
51static LIST_HEAD(thermal_cdev_list); 51static LIST_HEAD(thermal_cdev_list);
52static LIST_HEAD(thermal_governor_list);
53
52static DEFINE_MUTEX(thermal_list_lock); 54static DEFINE_MUTEX(thermal_list_lock);
55static DEFINE_MUTEX(thermal_governor_lock);
56
57static struct thermal_governor *__find_governor(const char *name)
58{
59 struct thermal_governor *pos;
60
61 list_for_each_entry(pos, &thermal_governor_list, governor_list)
62 if (!strnicmp(name, pos->name, THERMAL_NAME_LENGTH))
63 return pos;
64
65 return NULL;
66}
67
68int thermal_register_governor(struct thermal_governor *governor)
69{
70 int err;
71 const char *name;
72 struct thermal_zone_device *pos;
73
74 if (!governor)
75 return -EINVAL;
76
77 mutex_lock(&thermal_governor_lock);
78
79 err = -EBUSY;
80 if (__find_governor(governor->name) == NULL) {
81 err = 0;
82 list_add(&governor->governor_list, &thermal_governor_list);
83 }
84
85 mutex_lock(&thermal_list_lock);
86
87 list_for_each_entry(pos, &thermal_tz_list, node) {
88 if (pos->governor)
89 continue;
90 if (pos->tzp)
91 name = pos->tzp->governor_name;
92 else
93 name = DEFAULT_THERMAL_GOVERNOR;
94 if (!strnicmp(name, governor->name, THERMAL_NAME_LENGTH))
95 pos->governor = governor;
96 }
97
98 mutex_unlock(&thermal_list_lock);
99 mutex_unlock(&thermal_governor_lock);
100
101 return err;
102}
103EXPORT_SYMBOL_GPL(thermal_register_governor);
104
105void thermal_unregister_governor(struct thermal_governor *governor)
106{
107 struct thermal_zone_device *pos;
108
109 if (!governor)
110 return;
111
112 mutex_lock(&thermal_governor_lock);
113
114 if (__find_governor(governor->name) == NULL)
115 goto exit;
116
117 mutex_lock(&thermal_list_lock);
118
119 list_for_each_entry(pos, &thermal_tz_list, node) {
120 if (!strnicmp(pos->governor->name, governor->name,
121 THERMAL_NAME_LENGTH))
122 pos->governor = NULL;
123 }
124
125 mutex_unlock(&thermal_list_lock);
126 list_del(&governor->governor_list);
127exit:
128 mutex_unlock(&thermal_governor_lock);
129 return;
130}
131EXPORT_SYMBOL_GPL(thermal_unregister_governor);
53 132
54static int get_idr(struct idr *idr, struct mutex *lock, int *id) 133static int get_idr(struct idr *idr, struct mutex *lock, int *id)
55{ 134{
@@ -1437,6 +1516,16 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
1437 if (result) 1516 if (result)
1438 goto unregister; 1517 goto unregister;
1439 1518
1519 /* Update 'this' zone's governor information */
1520 mutex_lock(&thermal_governor_lock);
1521
1522 if (tz->tzp)
1523 tz->governor = __find_governor(tz->tzp->governor_name);
1524 else
1525 tz->governor = __find_governor(DEFAULT_THERMAL_GOVERNOR);
1526
1527 mutex_unlock(&thermal_governor_lock);
1528
1440 result = thermal_add_hwmon_sysfs(tz); 1529 result = thermal_add_hwmon_sysfs(tz);
1441 if (result) 1530 if (result)
1442 goto unregister; 1531 goto unregister;
@@ -1500,6 +1589,7 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1500 if (tz->ops->get_mode) 1589 if (tz->ops->get_mode)
1501 device_remove_file(&tz->device, &dev_attr_mode); 1590 device_remove_file(&tz->device, &dev_attr_mode);
1502 remove_trip_attrs(tz); 1591 remove_trip_attrs(tz);
1592 tz->governor = NULL;
1503 1593
1504 thermal_remove_hwmon_sysfs(tz); 1594 thermal_remove_hwmon_sysfs(tz);
1505 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); 1595 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 58cb1c036a0e..6182bd5f7504 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -46,6 +46,9 @@
46#define THERMAL_GENL_VERSION 0x01 46#define THERMAL_GENL_VERSION 0x01
47#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group" 47#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_group"
48 48
49/* Default Thermal Governor: Does Linear Throttling */
50#define DEFAULT_THERMAL_GOVERNOR "step_wise"
51
49struct thermal_zone_device; 52struct thermal_zone_device;
50struct thermal_cooling_device; 53struct thermal_cooling_device;
51 54
@@ -158,6 +161,7 @@ struct thermal_zone_device {
158 unsigned int forced_passive; 161 unsigned int forced_passive;
159 const struct thermal_zone_device_ops *ops; 162 const struct thermal_zone_device_ops *ops;
160 const struct thermal_zone_params *tzp; 163 const struct thermal_zone_params *tzp;
164 struct thermal_governor *governor;
161 struct list_head thermal_instances; 165 struct list_head thermal_instances;
162 struct idr idr; 166 struct idr idr;
163 struct mutex lock; /* protect thermal_instances list */ 167 struct mutex lock; /* protect thermal_instances list */
@@ -165,6 +169,14 @@ struct thermal_zone_device {
165 struct delayed_work poll_queue; 169 struct delayed_work poll_queue;
166}; 170};
167 171
172/* Structure that holds thermal governor information */
173struct thermal_governor {
174 char name[THERMAL_NAME_LENGTH];
175 int (*throttle)(struct thermal_zone_device *tz, int trip);
176 struct list_head governor_list;
177 struct module *owner;
178};
179
168/* Structure that holds binding parameters for a zone */ 180/* Structure that holds binding parameters for a zone */
169struct thermal_bind_params { 181struct thermal_bind_params {
170 struct thermal_cooling_device *cdev; 182 struct thermal_cooling_device *cdev;
@@ -189,6 +201,7 @@ struct thermal_bind_params {
189 201
190/* Structure to define Thermal Zone parameters */ 202/* Structure to define Thermal Zone parameters */
191struct thermal_zone_params { 203struct thermal_zone_params {
204 char governor_name[THERMAL_NAME_LENGTH];
192 int num_tbps; /* Number of tbp entries */ 205 int num_tbps; /* Number of tbp entries */
193 struct thermal_bind_params *tbp; 206 struct thermal_bind_params *tbp;
194}; 207};
@@ -219,6 +232,9 @@ int get_tz_trend(struct thermal_zone_device *, int);
219struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, 232struct thermal_instance *get_thermal_instance(struct thermal_zone_device *,
220 struct thermal_cooling_device *, int); 233 struct thermal_cooling_device *, int);
221 234
235int thermal_register_governor(struct thermal_governor *);
236void thermal_unregister_governor(struct thermal_governor *);
237
222#ifdef CONFIG_NET 238#ifdef CONFIG_NET
223extern int thermal_generate_netlink_event(u32 orig, enum events event); 239extern int thermal_generate_netlink_event(u32 orig, enum events event);
224#else 240#else