aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2015-01-16 18:59:03 -0500
committerZhang Rui <rui.zhang@intel.com>2015-01-19 20:29:35 -0500
commit5fbf7f27fa3da2c7b538772cfe3340391ef8b3b9 (patch)
tree4258a014545ddf26bc29a86ef91dff9b37aa15a6
parentec6f34e5b552fb0a52e6aae1a5afbbb1605cc6cc (diff)
Thermal/int340x: Add common thermal zone handler
Most of the processing for each int340x driver to add a thermal zone is very similar and every driver has to duplicate code. Created a common module, which exports API to add and remove zones. In this way, we not only avoid duplicate code but also helps in bug fixes and enhancements. If for some driver default processing for thermal zone callback is not enough they can overide individual callback. The code for this driver is primarily copied from int3402_thermal.c. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
-rw-r--r--drivers/thermal/int340x_thermal/Makefile1
-rw-r--r--drivers/thermal/int340x_thermal/int340x_thermal_zone.c262
-rw-r--r--drivers/thermal/int340x_thermal/int340x_thermal_zone.h65
3 files changed, 328 insertions, 0 deletions
diff --git a/drivers/thermal/int340x_thermal/Makefile b/drivers/thermal/int340x_thermal/Makefile
index d4413698a85f..ba77a34f659f 100644
--- a/drivers/thermal/int340x_thermal/Makefile
+++ b/drivers/thermal/int340x_thermal/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o 1obj-$(CONFIG_INT340X_THERMAL) += int3400_thermal.o
2obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal_zone.o
2obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o 3obj-$(CONFIG_INT340X_THERMAL) += int3402_thermal.o
3obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o 4obj-$(CONFIG_INT340X_THERMAL) += int3403_thermal.o
4obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o 5obj-$(CONFIG_INT340X_THERMAL) += processor_thermal_device.o
diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c
new file mode 100644
index 000000000000..162e545cc93a
--- /dev/null
+++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c
@@ -0,0 +1,262 @@
1/*
2 * int340x_thermal_zone.c
3 * Copyright (c) 2015, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/acpi.h>
19#include <linux/thermal.h>
20#include "int340x_thermal_zone.h"
21
22static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
23 unsigned long *temp)
24{
25 struct int34x_thermal_zone *d = zone->devdata;
26 unsigned long long tmp;
27 acpi_status status;
28
29 if (d->override_ops && d->override_ops->get_temp)
30 return d->override_ops->get_temp(zone, temp);
31
32 status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp);
33 if (ACPI_FAILURE(status))
34 return -EIO;
35
36 /* _TMP returns the temperature in tenths of degrees Kelvin */
37 *temp = DECI_KELVIN_TO_MILLICELSIUS(tmp);
38
39 return 0;
40}
41
42static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone,
43 int trip, unsigned long *temp)
44{
45 struct int34x_thermal_zone *d = zone->devdata;
46 int i;
47
48 if (d->override_ops && d->override_ops->get_trip_temp)
49 return d->override_ops->get_trip_temp(zone, trip, temp);
50
51 if (trip < d->aux_trip_nr)
52 *temp = d->aux_trips[trip];
53 else if (trip == d->crt_trip_id)
54 *temp = d->crt_temp;
55 else if (trip == d->psv_trip_id)
56 *temp = d->psv_temp;
57 else if (trip == d->hot_trip_id)
58 *temp = d->hot_temp;
59 else {
60 for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) {
61 if (d->act_trips[i].valid &&
62 d->act_trips[i].id == trip) {
63 *temp = d->act_trips[i].temp;
64 break;
65 }
66 }
67 if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT)
68 return -EINVAL;
69 }
70
71 return 0;
72}
73
74static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone,
75 int trip,
76 enum thermal_trip_type *type)
77{
78 struct int34x_thermal_zone *d = zone->devdata;
79 int i;
80
81 if (d->override_ops && d->override_ops->get_trip_type)
82 return d->override_ops->get_trip_type(zone, trip, type);
83
84 if (trip < d->aux_trip_nr)
85 *type = THERMAL_TRIP_PASSIVE;
86 else if (trip == d->crt_trip_id)
87 *type = THERMAL_TRIP_CRITICAL;
88 else if (trip == d->hot_trip_id)
89 *type = THERMAL_TRIP_HOT;
90 else if (trip == d->psv_trip_id)
91 *type = THERMAL_TRIP_PASSIVE;
92 else {
93 for (i = 0; i < INT340X_THERMAL_MAX_ACT_TRIP_COUNT; i++) {
94 if (d->act_trips[i].valid &&
95 d->act_trips[i].id == trip) {
96 *type = THERMAL_TRIP_ACTIVE;
97 break;
98 }
99 }
100 if (i == INT340X_THERMAL_MAX_ACT_TRIP_COUNT)
101 return -EINVAL;
102 }
103
104 return 0;
105}
106
107static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone,
108 int trip, unsigned long temp)
109{
110 struct int34x_thermal_zone *d = zone->devdata;
111 acpi_status status;
112 char name[10];
113
114 if (d->override_ops && d->override_ops->set_trip_temp)
115 return d->override_ops->set_trip_temp(zone, trip, temp);
116
117 snprintf(name, sizeof(name), "PAT%d", trip);
118 status = acpi_execute_simple_method(d->adev->handle, name,
119 MILLICELSIUS_TO_DECI_KELVIN(temp));
120 if (ACPI_FAILURE(status))
121 return -EIO;
122
123 d->aux_trips[trip] = temp;
124
125 return 0;
126}
127
128
129static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone,
130 int trip, unsigned long *temp)
131{
132 struct int34x_thermal_zone *d = zone->devdata;
133 acpi_status status;
134 unsigned long long hyst;
135
136 if (d->override_ops && d->override_ops->get_trip_hyst)
137 return d->override_ops->get_trip_hyst(zone, trip, temp);
138
139 status = acpi_evaluate_integer(d->adev->handle, "GTSH", NULL, &hyst);
140 if (ACPI_FAILURE(status))
141 return -EIO;
142
143 *temp = hyst * 100;
144
145 return 0;
146}
147
148static struct thermal_zone_device_ops int340x_thermal_zone_ops = {
149 .get_temp = int340x_thermal_get_zone_temp,
150 .get_trip_temp = int340x_thermal_get_trip_temp,
151 .get_trip_type = int340x_thermal_get_trip_type,
152 .set_trip_temp = int340x_thermal_set_trip_temp,
153 .get_trip_hyst = int340x_thermal_get_trip_hyst,
154};
155
156static int int340x_thermal_get_trip_config(acpi_handle handle, char *name,
157 unsigned long *temp)
158{
159 unsigned long long r;
160 acpi_status status;
161
162 status = acpi_evaluate_integer(handle, name, NULL, &r);
163 if (ACPI_FAILURE(status))
164 return -EIO;
165
166 *temp = DECI_KELVIN_TO_MILLICELSIUS(r);
167
168 return 0;
169}
170
171static struct thermal_zone_params int340x_thermal_params = {
172 .governor_name = "user_space",
173 .no_hwmon = true,
174};
175
176struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev,
177 struct thermal_zone_device_ops *override_ops)
178{
179