summaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-01-16 18:59:05 -0500
committerZhang Rui <rui.zhang@intel.com>2015-01-19 20:30:25 -0500
commit593df40475b719103e095aa1116653636662077e (patch)
tree92b44bfb545ede2b9bb48129daf083b846bce9db /drivers/thermal
parent820cdeba4086c74eb977088f1f9d31fd4c0aba9a (diff)
Thermal/int340x/int3403: Use int340x thermal API
Using APIs from int340x thermal zone module to add and remove thermal zones. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/int340x_thermal/int3403_thermal.c208
1 files changed, 10 insertions, 198 deletions
diff --git a/drivers/thermal/int340x_thermal/int3403_thermal.c b/drivers/thermal/int340x_thermal/int3403_thermal.c
index 0faf500d8a77..50a7a08e3a15 100644
--- a/drivers/thermal/int340x_thermal/int3403_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3403_thermal.c
@@ -19,6 +19,7 @@
19#include <linux/acpi.h> 19#include <linux/acpi.h>
20#include <linux/thermal.h> 20#include <linux/thermal.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include "int340x_thermal_zone.h"
22 23
23#define INT3403_TYPE_SENSOR 0x03 24#define INT3403_TYPE_SENSOR 0x03
24#define INT3403_TYPE_CHARGER 0x0B 25#define INT3403_TYPE_CHARGER 0x0B
@@ -26,18 +27,9 @@
26#define INT3403_PERF_CHANGED_EVENT 0x80 27#define INT3403_PERF_CHANGED_EVENT 0x80
27#define INT3403_THERMAL_EVENT 0x90 28#define INT3403_THERMAL_EVENT 0x90
28 29
29#define DECI_KELVIN_TO_MILLI_CELSIUS(t, off) (((t) - (off)) * 100) 30/* Preserved structure for future expandbility */
30#define KELVIN_OFFSET 2732
31#define MILLI_CELSIUS_TO_DECI_KELVIN(t, off) (((t) / 100) + (off))
32
33struct int3403_sensor { 31struct int3403_sensor {
34 struct thermal_zone_device *tzone; 32 struct int34x_thermal_zone *int340x_zone;
35 unsigned long *thresholds;
36 unsigned long crit_temp;
37 int crit_trip_id;
38 unsigned long psv_temp;
39 int psv_trip_id;
40
41}; 33};
42 34
43struct int3403_performance_state { 35struct int3403_performance_state {
@@ -63,126 +55,6 @@ struct int3403_priv {
63 void *priv; 55 void *priv;
64}; 56};
65 57
66static int sys_get_curr_temp(struct thermal_zone_device *tzone,
67 unsigned long *temp)
68{
69 struct int3403_priv *priv = tzone->devdata;
70 struct acpi_device *device = priv->adev;
71 unsigned long long tmp;
72 acpi_status status;
73
74 status = acpi_evaluate_integer(device->handle, "_TMP", NULL, &tmp);
75 if (ACPI_FAILURE(status))
76 return -EIO;
77
78 *temp = DECI_KELVIN_TO_MILLI_CELSIUS(tmp, KELVIN_OFFSET);
79
80 return 0;
81}
82
83static int sys_get_trip_hyst(struct thermal_zone_device *tzone,
84 int trip, unsigned long *temp)
85{
86 struct int3403_priv *priv = tzone->devdata;
87 struct acpi_device *device = priv->adev;
88 unsigned long long hyst;
89 acpi_status status;
90
91 status = acpi_evaluate_integer(device->handle, "GTSH", NULL, &hyst);
92 if (ACPI_FAILURE(status))
93 return -EIO;
94
95 /*
96 * Thermal hysteresis represents a temperature difference.
97 * Kelvin and Celsius have same degree size. So the
98 * conversion here between tenths of degree Kelvin unit
99 * and Milli-Celsius unit is just to multiply 100.
100 */
101 *temp = hyst * 100;
102
103 return 0;
104}
105
106static int sys_get_trip_temp(struct thermal_zone_device *tzone,
107 int trip, unsigned long *temp)
108{
109 struct int3403_priv *priv = tzone->devdata;
110 struct int3403_sensor *obj = priv->priv;
111
112 if (priv->type != INT3403_TYPE_SENSOR || !obj)
113 return -EINVAL;
114
115 if (trip == obj->crit_trip_id)
116 *temp = obj->crit_temp;
117 else if (trip == obj->psv_trip_id)
118 *temp = obj->psv_temp;
119 else {
120 /*
121 * get_trip_temp is a mandatory callback but
122 * PATx method doesn't return any value, so return
123 * cached value, which was last set from user space
124 */
125 *temp = obj->thresholds[trip];
126 }
127
128 return 0;
129}
130
131static int sys_get_trip_type(struct thermal_zone_device *thermal,
132 int trip, enum thermal_trip_type *type)
133{
134 struct int3403_priv *priv = thermal->devdata;
135 struct int3403_sensor *obj = priv->priv;
136
137 /* Mandatory callback, may not mean much here */
138 if (trip == obj->crit_trip_id)
139 *type = THERMAL_TRIP_CRITICAL;
140 else
141 *type = THERMAL_TRIP_PASSIVE;
142
143 return 0;
144}
145
146int sys_set_trip_temp(struct thermal_zone_device *tzone, int trip,
147 unsigned long temp)
148{
149 struct int3403_priv *priv = tzone->devdata;
150 struct acpi_device *device = priv->adev;
151 struct int3403_sensor *obj = priv->priv;
152 acpi_status status;
153 char name[10];
154 int ret = 0;
155
156 snprintf(name, sizeof(name), "PAT%d", trip);
157 if (acpi_has_method(device->handle, name)) {
158 status = acpi_execute_simple_method(device->handle, name,
159 MILLI_CELSIUS_TO_DECI_KELVIN(temp,
160 KELVIN_OFFSET));
161 if (ACPI_FAILURE(status))
162 ret = -EIO;
163 else
164 obj->thresholds[trip] = temp;
165 } else {
166 ret = -EIO;
167 dev_err(&device->dev, "sys_set_trip_temp: method not found\n");
168 }
169
170 return ret;
171}
172
173static struct thermal_zone_device_ops tzone_ops = {
174 .get_temp = sys_get_curr_temp,
175 .get_trip_temp = sys_get_trip_temp,
176 .get_trip_type = sys_get_trip_type,
177 .set_trip_temp = sys_set_trip_temp,
178 .get_trip_hyst = sys_get_trip_hyst,
179};
180
181static struct thermal_zone_params int3403_thermal_params = {
182 .governor_name = "user_space",
183 .no_hwmon = true,
184};
185
186static void int3403_notify(acpi_handle handle, 58static void int3403_notify(acpi_handle handle,
187 u32 event, void *data) 59 u32 event, void *data)
188{ 60{
@@ -200,7 +72,7 @@ static void int3403_notify(acpi_handle handle,
200 case INT3403_PERF_CHANGED_EVENT: 72 case INT3403_PERF_CHANGED_EVENT:
201 break; 73 break;
202 case INT3403_THERMAL_EVENT: 74 case INT3403_THERMAL_EVENT:
203 thermal_zone_device_update(obj->tzone); 75 int340x_thermal_zone_device_update(obj->int340x_zone);
204 break; 76 break;
205 default: 77 default:
206 dev_err(&priv->pdev->dev, "Unsupported event [0x%x]\n", event); 78 dev_err(&priv->pdev->dev, "Unsupported event [0x%x]\n", event);
@@ -208,41 +80,10 @@ static void int3403_notify(acpi_handle handle,
208 } 80 }
209} 81}
210 82
211static int sys_get_trip_crt(struct acpi_device *device, unsigned long *temp)
212{
213 unsigned long long crt;
214 acpi_status status;
215
216 status = acpi_evaluate_integer(device->handle, "_CRT", NULL, &crt);
217 if (ACPI_FAILURE(status))
218 return -EIO;
219
220 *temp = DECI_KELVIN_TO_MILLI_CELSIUS(crt, KELVIN_OFFSET);
221
222 return 0;
223}
224
225static int sys_get_trip_psv(struct acpi_device *device, unsigned long *temp)
226{
227 unsigned long long psv;
228 acpi_status status;
229
230 status = acpi_evaluate_integer(device->handle, "_PSV", NULL, &psv);
231 if (ACPI_FAILURE(status))
232 return -EIO;
233
234 *temp = DECI_KELVIN_TO_MILLI_CELSIUS(psv, KELVIN_OFFSET);
235
236 return 0;
237}
238
239static int int3403_sensor_add(struct int3403_priv *priv) 83static int int3403_sensor_add(struct int3403_priv *priv)
240{ 84{
241 int result = 0; 85 int result = 0;
242 acpi_status status;
243 struct int3403_sensor *obj; 86 struct int3403_sensor *obj;
244 unsigned long long trip_cnt;
245 int trip_mask = 0;
246 87
247 obj = devm_kzalloc(&priv->pdev->dev, sizeof(*obj), GFP_KERNEL); 88 obj = devm_kzalloc(&priv->pdev->dev, sizeof(*obj), GFP_KERNEL);
248 if (!obj) 89 if (!obj)
@@ -250,39 +91,9 @@ static int int3403_sensor_add(struct int3403_priv *priv)
250 91
251 priv->priv = obj; 92 priv->priv = obj;
252 93
253 status = acpi_evaluate_integer(priv->adev->handle, "PATC", NULL, 94 obj->int340x_zone = int340x_thermal_zone_add(priv->adev, NULL);
254 &trip_cnt); 95 if (IS_ERR(obj->int340x_zone))
255 if (ACPI_FAILURE(status)) 96 return PTR_ERR(obj->int340x_zone);
256 trip_cnt = 0;
257
258 if (trip_cnt) {
259 /* We have to cache, thresholds can't be readback */
260 obj->thresholds = devm_kzalloc(&priv->pdev->dev,
261 sizeof(*obj->thresholds) * trip_cnt,
262 GFP_KERNEL);
263 if (!obj->thresholds) {
264 result = -ENOMEM;
265 goto err_free_obj;
266 }
267 trip_mask = BIT(trip_cnt) - 1;
268 }
269
270 obj->psv_trip_id = -1;
271 if (!sys_get_trip_psv(priv->adev, &obj->psv_temp))
272 obj->psv_trip_id = trip_cnt++;
273
274 obj->crit_trip_id = -1;
275 if (!sys_get_trip_crt(priv->adev, &obj->crit_temp))
276 obj->crit_trip_id = trip_cnt++;
277
278 obj->tzone = thermal_zone_device_register(acpi_device_bid(priv->adev),
279 trip_cnt, trip_mask, priv, &tzone_ops,
280 &int3403_thermal_params, 0, 0);
281 if (IS_ERR(obj->tzone)) {
282 result = PTR_ERR(obj->tzone);
283 obj->tzone = NULL;
284 goto err_free_obj;
285 }
286 97
287 result = acpi_install_notify_handler(priv->adev->handle, 98 result = acpi_install_notify_handler(priv->adev->handle,
288 ACPI_DEVICE_NOTIFY, int3403_notify, 99 ACPI_DEVICE_NOTIFY, int3403_notify,
@@ -293,7 +104,7 @@ static int int3403_sensor_add(struct int3403_priv *priv)
293 return 0; 104 return 0;
294 105
295 err_free_obj: 106 err_free_obj:
296 thermal_zone_device_unregister(obj->tzone); 107 int340x_thermal_zone_remove(obj->int340x_zone);
297 return result; 108 return result;
298} 109}
299 110
@@ -303,7 +114,8 @@ static int int3403_sensor_remove(struct int3403_priv *priv)
303 114
304 acpi_remove_notify_handler(priv->adev->handle, 115 acpi_remove_notify_handler(priv->adev->handle,
305 ACPI_DEVICE_NOTIFY, int3403_notify); 116 ACPI_DEVICE_NOTIFY, int3403_notify);
306 thermal_zone_device_unregister(obj->tzone); 117 int340x_thermal_zone_remove(obj->int340x_zone);
118
307 return 0; 119 return 0;
308} 120}
309 121