diff options
author | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> | 2014-05-30 15:10:32 -0400 |
---|---|---|
committer | Zhang Rui <rui.zhang@intel.com> | 2014-06-29 22:13:22 -0400 |
commit | 5fcdeb20df2085580819c665ae50f7dae964c27d (patch) | |
tree | ab96e86edc689001968de5999811ef7571d7ca3f /drivers/thermal | |
parent | a497c3ba1d97fc69c1e78e7b96435ba8c2cb42ee (diff) |
Thermal: int3403: Add CRT and PSV trip
The ACPI object definition can contain passive and critical
trip temperature. Export them via thermal sysfs.
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/int3403_thermal.c | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/drivers/thermal/int3403_thermal.c b/drivers/thermal/int3403_thermal.c index e93f0253f6ed..17554eeb3953 100644 --- a/drivers/thermal/int3403_thermal.c +++ b/drivers/thermal/int3403_thermal.c | |||
@@ -33,6 +33,10 @@ | |||
33 | struct int3403_sensor { | 33 | struct int3403_sensor { |
34 | struct thermal_zone_device *tzone; | 34 | struct thermal_zone_device *tzone; |
35 | unsigned long *thresholds; | 35 | unsigned long *thresholds; |
36 | unsigned long crit_temp; | ||
37 | int crit_trip_id; | ||
38 | unsigned long psv_temp; | ||
39 | int psv_trip_id; | ||
36 | }; | 40 | }; |
37 | 41 | ||
38 | static int sys_get_curr_temp(struct thermal_zone_device *tzone, | 42 | static int sys_get_curr_temp(struct thermal_zone_device *tzone, |
@@ -79,12 +83,18 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzone, | |||
79 | struct acpi_device *device = tzone->devdata; | 83 | struct acpi_device *device = tzone->devdata; |
80 | struct int3403_sensor *obj = acpi_driver_data(device); | 84 | struct int3403_sensor *obj = acpi_driver_data(device); |
81 | 85 | ||
82 | /* | 86 | if (trip == obj->crit_trip_id) |
83 | * get_trip_temp is a mandatory callback but | 87 | *temp = obj->crit_temp; |
84 | * PATx method doesn't return any value, so return | 88 | else if (trip == obj->psv_trip_id) |
85 | * cached value, which was last set from user space. | 89 | *temp = obj->psv_temp; |
86 | */ | 90 | else { |
87 | *temp = obj->thresholds[trip]; | 91 | /* |
92 | * get_trip_temp is a mandatory callback but | ||
93 | * PATx method doesn't return any value, so return | ||
94 | * cached value, which was last set from user space. | ||
95 | */ | ||
96 | *temp = obj->thresholds[trip]; | ||
97 | } | ||
88 | 98 | ||
89 | return 0; | 99 | return 0; |
90 | } | 100 | } |
@@ -92,8 +102,14 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzone, | |||
92 | static int sys_get_trip_type(struct thermal_zone_device *thermal, | 102 | static int sys_get_trip_type(struct thermal_zone_device *thermal, |
93 | int trip, enum thermal_trip_type *type) | 103 | int trip, enum thermal_trip_type *type) |
94 | { | 104 | { |
105 | struct acpi_device *device = thermal->devdata; | ||
106 | struct int3403_sensor *obj = acpi_driver_data(device); | ||
107 | |||
95 | /* Mandatory callback, may not mean much here */ | 108 | /* Mandatory callback, may not mean much here */ |
96 | *type = THERMAL_TRIP_PASSIVE; | 109 | if (trip == obj->crit_trip_id) |
110 | *type = THERMAL_TRIP_CRITICAL; | ||
111 | else | ||
112 | *type = THERMAL_TRIP_PASSIVE; | ||
97 | 113 | ||
98 | return 0; | 114 | return 0; |
99 | } | 115 | } |
@@ -155,6 +171,34 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) | |||
155 | } | 171 | } |
156 | } | 172 | } |
157 | 173 | ||
174 | static int sys_get_trip_crt(struct acpi_device *device, unsigned long *temp) | ||
175 | { | ||
176 | unsigned long long crt; | ||
177 | acpi_status status; | ||
178 | |||
179 | status = acpi_evaluate_integer(device->handle, "_CRT", NULL, &crt); | ||
180 | if (ACPI_FAILURE(status)) | ||
181 | return -EIO; | ||
182 | |||
183 | *temp = DECI_KELVIN_TO_MILLI_CELSIUS(crt, KELVIN_OFFSET); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int sys_get_trip_psv(struct acpi_device *device, unsigned long *temp) | ||
189 | { | ||
190 | unsigned long long psv; | ||
191 | acpi_status status; | ||
192 | |||
193 | status = acpi_evaluate_integer(device->handle, "_PSV", NULL, &psv); | ||
194 | if (ACPI_FAILURE(status)) | ||
195 | return -EIO; | ||
196 | |||
197 | *temp = DECI_KELVIN_TO_MILLI_CELSIUS(psv, KELVIN_OFFSET); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
158 | static int acpi_int3403_add(struct acpi_device *device) | 202 | static int acpi_int3403_add(struct acpi_device *device) |
159 | { | 203 | { |
160 | int result = 0; | 204 | int result = 0; |
@@ -194,6 +238,15 @@ static int acpi_int3403_add(struct acpi_device *device) | |||
194 | return -ENOMEM; | 238 | return -ENOMEM; |
195 | trip_mask = BIT(trip_cnt) - 1; | 239 | trip_mask = BIT(trip_cnt) - 1; |
196 | } | 240 | } |
241 | |||
242 | obj->psv_trip_id = -1; | ||
243 | if (!sys_get_trip_psv(device, &obj->psv_temp)) | ||
244 | obj->psv_trip_id = trip_cnt++; | ||
245 | |||
246 | obj->crit_trip_id = -1; | ||
247 | if (!sys_get_trip_crt(device, &obj->crit_temp)) | ||
248 | obj->crit_trip_id = trip_cnt++; | ||
249 | |||
197 | obj->tzone = thermal_zone_device_register(acpi_device_bid(device), | 250 | obj->tzone = thermal_zone_device_register(acpi_device_bid(device), |
198 | trip_cnt, trip_mask, device, &tzone_ops, | 251 | trip_cnt, trip_mask, device, &tzone_ops, |
199 | NULL, 0, 0); | 252 | NULL, 0, 0); |