Blame view

drivers/hwmon/coretemp.c 20.2 KB
935912c53   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
bebe46782   Rudolf Marek   hwmon: New corete...
2
3
4
5
6
7
  /*
   * coretemp.c - Linux kernel module for hardware monitoring
   *
   * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
   *
   * Inspired from many hwmon drivers
bebe46782   Rudolf Marek   hwmon: New corete...
8
   */
f8bb89256   Joe Perches   hwmon: (coretemp)...
9
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
bebe46782   Rudolf Marek   hwmon: New corete...
10
  #include <linux/module.h>
bebe46782   Rudolf Marek   hwmon: New corete...
11
12
13
14
15
16
17
18
19
20
21
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/jiffies.h>
  #include <linux/hwmon.h>
  #include <linux/sysfs.h>
  #include <linux/hwmon-sysfs.h>
  #include <linux/err.h>
  #include <linux/mutex.h>
  #include <linux/list.h>
  #include <linux/platform_device.h>
  #include <linux/cpu.h>
4cc452758   Guenter Roeck   hwmon: (coretemp)...
22
  #include <linux/smp.h>
a45a8c857   Jean Delvare   hwmon: (coretemp)...
23
  #include <linux/moduleparam.h>
14513ee69   Guenter Roeck   hwmon: (coretemp)...
24
  #include <linux/pci.h>
bebe46782   Rudolf Marek   hwmon: New corete...
25
26
  #include <asm/msr.h>
  #include <asm/processor.h>
9b38096fd   Andi Kleen   HWMON: Convert co...
27
  #include <asm/cpu_device_id.h>
bebe46782   Rudolf Marek   hwmon: New corete...
28
29
  
  #define DRVNAME	"coretemp"
a45a8c857   Jean Delvare   hwmon: (coretemp)...
30
31
32
33
34
35
36
  /*
   * force_tjmax only matters when TjMax can't be read from the CPU itself.
   * When set, it replaces the driver's suboptimal heuristic.
   */
  static int force_tjmax;
  module_param_named(tjmax, force_tjmax, int, 0444);
  MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
723f57343   Thomas Gleixner   hwmon: (coretemp)...
37
  #define PKG_SYSFS_ATTR_NO	1	/* Sysfs attribute for package temp */
199e0de7f   Durgadoss R   hwmon: (coretemp)...
38
  #define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */
cc904f9cf   Lukasz Odzioba   hwmon: (coretemp)...
39
  #define NUM_REAL_CORES		128	/* Number of Real cores per cpu */
3f9aec761   Jean Delvare   hwmon: (coretemp)...
40
  #define CORETEMP_NAME_LENGTH	19	/* String Length of attrs */
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
41
  #define MAX_CORE_ATTRS		4	/* Maximum no of basic attrs */
f4af6fd6e   Guenter Roeck   hwmon: (coretemp)...
42
  #define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
43
  #define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
780affe0e   Guenter Roeck   hwmon: (coretemp)...
44
  #define TO_CORE_ID(cpu)		(cpu_data(cpu).cpu_core_id)
141168c36   Kevin Winchester   x86: Simplify cod...
45
46
47
  #define TO_ATTR_NO(cpu)		(TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
  
  #ifdef CONFIG_SMP
19a34eea4   Bartosz Golaszewski   coretemp: Replace...
48
49
  #define for_each_sibling(i, cpu) \
  	for_each_cpu(i, topology_sibling_cpumask(cpu))
199e0de7f   Durgadoss R   hwmon: (coretemp)...
50
  #else
bb74e8ca3   Guenter Roeck   hwmon: (coretemp)...
51
  #define for_each_sibling(i, cpu)	for (i = 0; false; )
199e0de7f   Durgadoss R   hwmon: (coretemp)...
52
  #endif
bebe46782   Rudolf Marek   hwmon: New corete...
53
54
  
  /*
199e0de7f   Durgadoss R   hwmon: (coretemp)...
55
56
57
58
59
60
61
   * Per-Core Temperature Data
   * @last_updated: The time when the current temperature value was updated
   *		earlier (in jiffies).
   * @cpu_core_id: The CPU Core from which temperature values should be read
   *		This value is passed as "id" field to rdmsr/wrmsr functions.
   * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS,
   *		from where the temperature values should be read.
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
62
   * @attr_size:  Total number of pre-core attrs displayed in the sysfs.
199e0de7f   Durgadoss R   hwmon: (coretemp)...
63
64
65
   * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data.
   *		Otherwise, temp_data holds coretemp data.
   * @valid: If this is 1, the current temperature is valid.
bebe46782   Rudolf Marek   hwmon: New corete...
66
   */
199e0de7f   Durgadoss R   hwmon: (coretemp)...
67
  struct temp_data {
bebe46782   Rudolf Marek   hwmon: New corete...
68
  	int temp;
6369a2887   Rudolf Marek   hwmon: (coretemp)...
69
  	int ttarget;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
70
71
72
73
74
  	int tjmax;
  	unsigned long last_updated;
  	unsigned int cpu;
  	u32 cpu_core_id;
  	u32 status_reg;
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
75
  	int attr_size;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
76
77
  	bool is_pkg_data;
  	bool valid;
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
78
79
  	struct sensor_device_attribute sd_attrs[TOTAL_ATTRS];
  	char attr_name[TOTAL_ATTRS][CORETEMP_NAME_LENGTH];
1075305de   Guenter Roeck   hwmon: (coretemp)...
80
81
  	struct attribute *attrs[TOTAL_ATTRS + 1];
  	struct attribute_group attr_group;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
82
  	struct mutex update_lock;
bebe46782   Rudolf Marek   hwmon: New corete...
83
  };
199e0de7f   Durgadoss R   hwmon: (coretemp)...
84
85
  /* Platform Data per Physical CPU */
  struct platform_data {
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
86
  	struct device		*hwmon_dev;
712668460   Thomas Gleixner   hwmon: (coretemp)...
87
  	u16			pkg_id;
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
88
89
  	struct cpumask		cpumask;
  	struct temp_data	*core_data[MAX_CORE_DATA];
199e0de7f   Durgadoss R   hwmon: (coretemp)...
90
91
  	struct device_attribute name_attr;
  };
bebe46782   Rudolf Marek   hwmon: New corete...
92

835896a59   Len Brown   hwmon/coretemp: C...
93
94
95
96
  /* Keep track of how many zone pointers we allocated in init() */
  static int max_zones __read_mostly;
  /* Array of zone pointers. Serialized by cpu hotplug lock */
  static struct platform_device **zone_devices;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
97

199e0de7f   Durgadoss R   hwmon: (coretemp)...
98
99
  static ssize_t show_label(struct device *dev,
  				struct device_attribute *devattr, char *buf)
bebe46782   Rudolf Marek   hwmon: New corete...
100
  {
bebe46782   Rudolf Marek   hwmon: New corete...
101
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
102
103
104
105
  	struct platform_data *pdata = dev_get_drvdata(dev);
  	struct temp_data *tdata = pdata->core_data[attr->index];
  
  	if (tdata->is_pkg_data)
712668460   Thomas Gleixner   hwmon: (coretemp)...
106
107
  		return sprintf(buf, "Package id %u
  ", pdata->pkg_id);
bebe46782   Rudolf Marek   hwmon: New corete...
108

199e0de7f   Durgadoss R   hwmon: (coretemp)...
109
110
  	return sprintf(buf, "Core %u
  ", tdata->cpu_core_id);
bebe46782   Rudolf Marek   hwmon: New corete...
111
  }
199e0de7f   Durgadoss R   hwmon: (coretemp)...
112
113
  static ssize_t show_crit_alarm(struct device *dev,
  				struct device_attribute *devattr, char *buf)
bebe46782   Rudolf Marek   hwmon: New corete...
114
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
115
116
117
118
  	u32 eax, edx;
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  	struct platform_data *pdata = dev_get_drvdata(dev);
  	struct temp_data *tdata = pdata->core_data[attr->index];
723f57343   Thomas Gleixner   hwmon: (coretemp)...
119
  	mutex_lock(&tdata->update_lock);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
120
  	rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
723f57343   Thomas Gleixner   hwmon: (coretemp)...
121
  	mutex_unlock(&tdata->update_lock);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
122
123
124
  
  	return sprintf(buf, "%d
  ", (eax >> 5) & 1);
bebe46782   Rudolf Marek   hwmon: New corete...
125
  }
199e0de7f   Durgadoss R   hwmon: (coretemp)...
126
127
  static ssize_t show_tjmax(struct device *dev,
  			struct device_attribute *devattr, char *buf)
bebe46782   Rudolf Marek   hwmon: New corete...
128
129
  {
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
130
  	struct platform_data *pdata = dev_get_drvdata(dev);
bebe46782   Rudolf Marek   hwmon: New corete...
131

199e0de7f   Durgadoss R   hwmon: (coretemp)...
132
133
  	return sprintf(buf, "%d
  ", pdata->core_data[attr->index]->tjmax);
bebe46782   Rudolf Marek   hwmon: New corete...
134
  }
199e0de7f   Durgadoss R   hwmon: (coretemp)...
135
136
137
138
139
  static ssize_t show_ttarget(struct device *dev,
  				struct device_attribute *devattr, char *buf)
  {
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  	struct platform_data *pdata = dev_get_drvdata(dev);
bebe46782   Rudolf Marek   hwmon: New corete...
140

199e0de7f   Durgadoss R   hwmon: (coretemp)...
141
142
143
  	return sprintf(buf, "%d
  ", pdata->core_data[attr->index]->ttarget);
  }
bebe46782   Rudolf Marek   hwmon: New corete...
144

199e0de7f   Durgadoss R   hwmon: (coretemp)...
145
146
  static ssize_t show_temp(struct device *dev,
  			struct device_attribute *devattr, char *buf)
bebe46782   Rudolf Marek   hwmon: New corete...
147
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
148
149
150
151
  	u32 eax, edx;
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
  	struct platform_data *pdata = dev_get_drvdata(dev);
  	struct temp_data *tdata = pdata->core_data[attr->index];
bebe46782   Rudolf Marek   hwmon: New corete...
152

199e0de7f   Durgadoss R   hwmon: (coretemp)...
153
  	mutex_lock(&tdata->update_lock);
bebe46782   Rudolf Marek   hwmon: New corete...
154

199e0de7f   Durgadoss R   hwmon: (coretemp)...
155
156
157
  	/* Check whether the time interval has elapsed */
  	if (!tdata->valid || time_after(jiffies, tdata->last_updated + HZ)) {
  		rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
bf6ea084e   Guenter Roeck   hwmon: (coretemp)...
158
159
160
161
162
163
164
165
  		/*
  		 * Ignore the valid bit. In all observed cases the register
  		 * value is either low or zero if the valid bit is 0.
  		 * Return it instead of reporting an error which doesn't
  		 * really help at all.
  		 */
  		tdata->temp = tdata->tjmax - ((eax >> 16) & 0x7f) * 1000;
  		tdata->valid = 1;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
166
  		tdata->last_updated = jiffies;
bebe46782   Rudolf Marek   hwmon: New corete...
167
  	}
199e0de7f   Durgadoss R   hwmon: (coretemp)...
168
  	mutex_unlock(&tdata->update_lock);
bf6ea084e   Guenter Roeck   hwmon: (coretemp)...
169
170
  	return sprintf(buf, "%d
  ", tdata->temp);
bebe46782   Rudolf Marek   hwmon: New corete...
171
  }
14513ee69   Guenter Roeck   hwmon: (coretemp)...
172
173
174
175
176
177
  struct tjmax_pci {
  	unsigned int device;
  	int tjmax;
  };
  
  static const struct tjmax_pci tjmax_pci_table[] = {
347c16cfd   Guenter Roeck   hwmon: (coretemp)...
178
  	{ 0x0708, 110000 },	/* CE41x0 (Sodaville ) */
14513ee69   Guenter Roeck   hwmon: (coretemp)...
179
180
181
182
  	{ 0x0c72, 102000 },	/* Atom S1240 (Centerton) */
  	{ 0x0c73, 95000 },	/* Atom S1220 (Centerton) */
  	{ 0x0c75, 95000 },	/* Atom S1260 (Centerton) */
  };
41e58a1f2   Guenter Roeck   hwmon: (coretemp)...
183
184
185
186
  struct tjmax {
  	char const *id;
  	int tjmax;
  };
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
187
  static const struct tjmax tjmax_table[] = {
1102dcab8   Guenter Roeck   hwmon: (coretemp)...
188
189
  	{ "CPU  230", 100000 },		/* Model 0x1c, stepping 2	*/
  	{ "CPU  330", 125000 },		/* Model 0x1c, stepping 2	*/
41e58a1f2   Guenter Roeck   hwmon: (coretemp)...
190
  };
2fa5222ef   Guenter Roeck   hwmon: (coretemp)...
191
192
193
194
195
196
197
  struct tjmax_model {
  	u8 model;
  	u8 mask;
  	int tjmax;
  };
  
  #define ANY 0xff
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
198
  static const struct tjmax_model tjmax_model_table[] = {
9e3970fba   Guenter Roeck   hwmon: (coretemp)...
199
  	{ 0x1c, 10, 100000 },	/* D4xx, K4xx, N4xx, D5xx, K5xx, N5xx */
2fa5222ef   Guenter Roeck   hwmon: (coretemp)...
200
201
202
203
204
205
206
207
208
  	{ 0x1c, ANY, 90000 },	/* Z5xx, N2xx, possibly others
  				 * Note: Also matches 230 and 330,
  				 * which are covered by tjmax_table
  				 */
  	{ 0x26, ANY, 90000 },	/* Atom Tunnel Creek (Exx), Lincroft (Z6xx)
  				 * Note: TjMax for E6xxT is 110C, but CPU type
  				 * is undetectable by software
  				 */
  	{ 0x27, ANY, 90000 },	/* Atom Medfield (Z2460) */
14513ee69   Guenter Roeck   hwmon: (coretemp)...
209
210
211
212
213
  	{ 0x35, ANY, 90000 },	/* Atom Clover Trail/Cloverview (Z27x0) */
  	{ 0x36, ANY, 100000 },	/* Atom Cedar Trail/Cedarview (N2xxx, D2xxx)
  				 * Also matches S12x0 (stepping 9), covered by
  				 * PCI table
  				 */
2fa5222ef   Guenter Roeck   hwmon: (coretemp)...
214
  };
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
215
  static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
118a88718   Rudolf Marek   hwmon: (coretemp)...
216
217
218
219
  {
  	/* The 100C is default for both mobile and non mobile CPUs */
  
  	int tjmax = 100000;
eccfed422   Rudolf Marek   hwmon: (coretemp)...
220
  	int tjmax_ee = 85000;
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
221
  	int usemsr_ee = 1;
118a88718   Rudolf Marek   hwmon: (coretemp)...
222
223
  	int err;
  	u32 eax, edx;
41e58a1f2   Guenter Roeck   hwmon: (coretemp)...
224
  	int i;
b9ccff233   Sinan Kaya   hwmon: (coretemp)...
225
226
  	u16 devfn = PCI_DEVFN(0, 0);
  	struct pci_dev *host_bridge = pci_get_domain_bus_and_slot(0, 0, devfn);
14513ee69   Guenter Roeck   hwmon: (coretemp)...
227
228
229
230
231
232
233
234
235
236
237
238
  
  	/*
  	 * Explicit tjmax table entries override heuristics.
  	 * First try PCI host bridge IDs, followed by model ID strings
  	 * and model/stepping information.
  	 */
  	if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) {
  		for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) {
  			if (host_bridge->device == tjmax_pci_table[i].device)
  				return tjmax_pci_table[i].tjmax;
  		}
  	}
41e58a1f2   Guenter Roeck   hwmon: (coretemp)...
239

41e58a1f2   Guenter Roeck   hwmon: (coretemp)...
240
241
242
243
  	for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) {
  		if (strstr(c->x86_model_id, tjmax_table[i].id))
  			return tjmax_table[i].tjmax;
  	}
118a88718   Rudolf Marek   hwmon: (coretemp)...
244

2fa5222ef   Guenter Roeck   hwmon: (coretemp)...
245
246
247
  	for (i = 0; i < ARRAY_SIZE(tjmax_model_table); i++) {
  		const struct tjmax_model *tm = &tjmax_model_table[i];
  		if (c->x86_model == tm->model &&
b399151cb   Jia Zhang   x86/cpu: Rename c...
248
  		    (tm->mask == ANY || c->x86_stepping == tm->mask))
2fa5222ef   Guenter Roeck   hwmon: (coretemp)...
249
  			return tm->tjmax;
72cbdddcc   Guenter Roeck   hwmon: (coretemp)...
250
  	}
1fe63ab47   Yong Wang   hwmon: (coretemp)...
251

72cbdddcc   Guenter Roeck   hwmon: (coretemp)...
252
  	/* Early chips have no MSR for TjMax */
1fe63ab47   Yong Wang   hwmon: (coretemp)...
253

b399151cb   Jia Zhang   x86/cpu: Rename c...
254
  	if (c->x86_model == 0xf && c->x86_stepping < 4)
5592906f8   Guenter Roeck   hwmon: (coretemp)...
255
  		usemsr_ee = 0;
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
256

4cc452758   Guenter Roeck   hwmon: (coretemp)...
257
  	if (c->x86_model > 0xe && usemsr_ee) {
eccfed422   Rudolf Marek   hwmon: (coretemp)...
258
  		u8 platform_id;
118a88718   Rudolf Marek   hwmon: (coretemp)...
259

4cc452758   Guenter Roeck   hwmon: (coretemp)...
260
261
262
263
264
  		/*
  		 * Now we can detect the mobile CPU using Intel provided table
  		 * http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
  		 * For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU
  		 */
118a88718   Rudolf Marek   hwmon: (coretemp)...
265
266
267
268
269
270
  		err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx);
  		if (err) {
  			dev_warn(dev,
  				 "Unable to access MSR 0x17, assuming desktop"
  				 " CPU
  ");
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
271
  			usemsr_ee = 0;
eccfed422   Rudolf Marek   hwmon: (coretemp)...
272
  		} else if (c->x86_model < 0x17 && !(eax & 0x10000000)) {
4cc452758   Guenter Roeck   hwmon: (coretemp)...
273
274
275
276
277
  			/*
  			 * Trust bit 28 up to Penryn, I could not find any
  			 * documentation on that; if you happen to know
  			 * someone at Intel please ask
  			 */
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
278
  			usemsr_ee = 0;
eccfed422   Rudolf Marek   hwmon: (coretemp)...
279
280
281
  		} else {
  			/* Platform ID bits 52:50 (EDX starts at bit 32) */
  			platform_id = (edx >> 18) & 0x7;
4cc452758   Guenter Roeck   hwmon: (coretemp)...
282
283
284
285
286
287
288
289
290
291
  			/*
  			 * Mobile Penryn CPU seems to be platform ID 7 or 5
  			 * (guesswork)
  			 */
  			if (c->x86_model == 0x17 &&
  			    (platform_id == 5 || platform_id == 7)) {
  				/*
  				 * If MSR EE bit is set, set it to 90 degrees C,
  				 * otherwise 105 degrees C
  				 */
eccfed422   Rudolf Marek   hwmon: (coretemp)...
292
293
294
  				tjmax_ee = 90000;
  				tjmax = 105000;
  			}
118a88718   Rudolf Marek   hwmon: (coretemp)...
295
296
  		}
  	}
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
297
  	if (usemsr_ee) {
118a88718   Rudolf Marek   hwmon: (coretemp)...
298
299
300
301
  		err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
  		if (err) {
  			dev_warn(dev,
  				 "Unable to access MSR 0xEE, for Tjmax, left"
4d7a5644e   Dean Nelson   hwmon: (coretemp)...
302
303
  				 " at default
  ");
118a88718   Rudolf Marek   hwmon: (coretemp)...
304
  		} else if (eax & 0x40000000) {
eccfed422   Rudolf Marek   hwmon: (coretemp)...
305
  			tjmax = tjmax_ee;
118a88718   Rudolf Marek   hwmon: (coretemp)...
306
  		}
708a62bcd   Rudolf Marek   hwmon: (coretemp)...
307
  	} else if (tjmax == 100000) {
4cc452758   Guenter Roeck   hwmon: (coretemp)...
308
309
310
311
  		/*
  		 * If we don't use msr EE it means we are desktop CPU
  		 * (with exeception of Atom)
  		 */
118a88718   Rudolf Marek   hwmon: (coretemp)...
312
313
314
315
316
317
  		dev_warn(dev, "Using relative temperature scale!
  ");
  	}
  
  	return tjmax;
  }
1c2faa224   Guenter Roeck   hwmon: (coretemp)...
318
319
320
321
322
323
324
325
326
327
328
  static bool cpu_has_tjmax(struct cpuinfo_x86 *c)
  {
  	u8 model = c->x86_model;
  
  	return model > 0xe &&
  	       model != 0x1c &&
  	       model != 0x26 &&
  	       model != 0x27 &&
  	       model != 0x35 &&
  	       model != 0x36;
  }
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
329
  static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
a321cedb1   Carsten Emde   drivers/hwmon/cor...
330
  {
a321cedb1   Carsten Emde   drivers/hwmon/cor...
331
332
333
  	int err;
  	u32 eax, edx;
  	u32 val;
4cc452758   Guenter Roeck   hwmon: (coretemp)...
334
335
336
337
  	/*
  	 * A new feature of current Intel(R) processors, the
  	 * IA32_TEMPERATURE_TARGET contains the TjMax value
  	 */
a321cedb1   Carsten Emde   drivers/hwmon/cor...
338
339
  	err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
  	if (err) {
1c2faa224   Guenter Roeck   hwmon: (coretemp)...
340
  		if (cpu_has_tjmax(c))
6bf9e9b09   Jean Delvare   hwmon: (coretemp)...
341
342
  			dev_warn(dev, "Unable to read TjMax from CPU %u
  ", id);
a321cedb1   Carsten Emde   drivers/hwmon/cor...
343
  	} else {
c0940e95f   Guenter Roeck   Revert "hwmon: (c...
344
  		val = (eax >> 16) & 0xff;
a321cedb1   Carsten Emde   drivers/hwmon/cor...
345
346
347
348
  		/*
  		 * If the TjMax is not plausible, an assumption
  		 * will be used
  		 */
c0940e95f   Guenter Roeck   Revert "hwmon: (c...
349
  		if (val) {
6bf9e9b09   Jean Delvare   hwmon: (coretemp)...
350
351
  			dev_dbg(dev, "TjMax is %d degrees C
  ", val);
a321cedb1   Carsten Emde   drivers/hwmon/cor...
352
353
354
  			return val * 1000;
  		}
  	}
a45a8c857   Jean Delvare   hwmon: (coretemp)...
355
356
357
358
359
360
  	if (force_tjmax) {
  		dev_notice(dev, "TjMax forced to %d degrees C by user
  ",
  			   force_tjmax);
  		return force_tjmax * 1000;
  	}
a321cedb1   Carsten Emde   drivers/hwmon/cor...
361
362
  	/*
  	 * An assumption is made for early CPUs and unreadable MSR.
4f5f71a7a   Guenter Roeck   hwmon: (coretemp)...
363
  	 * NOTE: the calculated value may not be correct.
a321cedb1   Carsten Emde   drivers/hwmon/cor...
364
  	 */
4f5f71a7a   Guenter Roeck   hwmon: (coretemp)...
365
  	return adjust_tjmax(c, id, dev);
a321cedb1   Carsten Emde   drivers/hwmon/cor...
366
  }
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
367
368
  static int create_core_attrs(struct temp_data *tdata, struct device *dev,
  			     int attr_no)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
369
  {
1075305de   Guenter Roeck   hwmon: (coretemp)...
370
  	int i;
e3204ed3a   Jan Beulich   hwmon: (coretemp)...
371
  	static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev,
199e0de7f   Durgadoss R   hwmon: (coretemp)...
372
  			struct device_attribute *devattr, char *buf) = {
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
373
  			show_label, show_crit_alarm, show_temp, show_tjmax,
f4af6fd6e   Guenter Roeck   hwmon: (coretemp)...
374
  			show_ttarget };
1055b5f90   Rasmus Villemoes   hwmon: (coretemp)...
375
376
377
  	static const char *const suffixes[TOTAL_ATTRS] = {
  		"label", "crit_alarm", "input", "crit", "max"
  	};
199e0de7f   Durgadoss R   hwmon: (coretemp)...
378

c814a4c7c   Durgadoss R   hwmon: (coretemp)...
379
  	for (i = 0; i < tdata->attr_size; i++) {
1055b5f90   Rasmus Villemoes   hwmon: (coretemp)...
380
381
  		snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH,
  			 "temp%d_%s", attr_no, suffixes[i]);
4258781ac   Sergey Senozhatsky   hwmon: (coretemp)...
382
  		sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
383
  		tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i];
0cd709d0d   Guenter Roeck   hwmon: (coretemp)...
384
  		tdata->sd_attrs[i].dev_attr.attr.mode = 0444;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
385
  		tdata->sd_attrs[i].dev_attr.show = rd_ptr[i];
199e0de7f   Durgadoss R   hwmon: (coretemp)...
386
  		tdata->sd_attrs[i].index = attr_no;
1075305de   Guenter Roeck   hwmon: (coretemp)...
387
  		tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr;
bebe46782   Rudolf Marek   hwmon: New corete...
388
  	}
1075305de   Guenter Roeck   hwmon: (coretemp)...
389
390
  	tdata->attr_group.attrs = tdata->attrs;
  	return sysfs_create_group(&dev->kobj, &tdata->attr_group);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
391
  }
199e0de7f   Durgadoss R   hwmon: (coretemp)...
392

d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
393
  static int chk_ucode_version(unsigned int cpu)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
394
  {
0eb9782ad   Jean Delvare   hwmon: (coretemp)...
395
  	struct cpuinfo_x86 *c = &cpu_data(cpu);
67f363b1f   Rudolf Marek   hwmon/coretemp: A...
396

199e0de7f   Durgadoss R   hwmon: (coretemp)...
397
398
399
400
401
  	/*
  	 * Check if we have problem with errata AE18 of Core processors:
  	 * Readings might stop update when processor visited too deep sleep,
  	 * fixed for stepping D0 (6EC).
  	 */
b399151cb   Jia Zhang   x86/cpu: Rename c...
402
  	if (c->x86_model == 0xe && c->x86_stepping < 0xc && c->microcode < 0x39) {
b55f37572   Guenter Roeck   hwmon: Fix checkp...
403
404
  		pr_err("Errata AE18 not fixed, update BIOS or microcode of the CPU!
  ");
ca8bc8dc0   Andi Kleen   coretemp: Get mic...
405
  		return -ENODEV;
67f363b1f   Rudolf Marek   hwmon/coretemp: A...
406
  	}
199e0de7f   Durgadoss R   hwmon: (coretemp)...
407
408
  	return 0;
  }
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
409
  static struct platform_device *coretemp_get_pdev(unsigned int cpu)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
410
  {
835896a59   Len Brown   hwmon/coretemp: C...
411
  	int id = topology_logical_die_id(cpu);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
412

835896a59   Len Brown   hwmon/coretemp: C...
413
414
  	if (id >= 0 && id < max_zones)
  		return zone_devices[id];
199e0de7f   Durgadoss R   hwmon: (coretemp)...
415
416
  	return NULL;
  }
d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
417
  static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
418
419
420
421
422
423
424
425
426
427
428
429
  {
  	struct temp_data *tdata;
  
  	tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL);
  	if (!tdata)
  		return NULL;
  
  	tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS :
  							MSR_IA32_THERM_STATUS;
  	tdata->is_pkg_data = pkg_flag;
  	tdata->cpu = cpu;
  	tdata->cpu_core_id = TO_CORE_ID(cpu);
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
430
  	tdata->attr_size = MAX_CORE_ATTRS;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
431
432
433
  	mutex_init(&tdata->update_lock);
  	return tdata;
  }
67f363b1f   Rudolf Marek   hwmon/coretemp: A...
434

d23e2ae1a   Paul Gortmaker   hwmon: delete __c...
435
436
  static int create_core_data(struct platform_device *pdev, unsigned int cpu,
  			    int pkg_flag)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
437
438
  {
  	struct temp_data *tdata;
2f1c3db0a   Jan Beulich   hwmon: (coretemp)...
439
  	struct platform_data *pdata = platform_get_drvdata(pdev);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
440
441
442
  	struct cpuinfo_x86 *c = &cpu_data(cpu);
  	u32 eax, edx;
  	int err, attr_no;
bebe46782   Rudolf Marek   hwmon: New corete...
443

a321cedb1   Carsten Emde   drivers/hwmon/cor...
444
  	/*
199e0de7f   Durgadoss R   hwmon: (coretemp)...
445
446
447
448
  	 * Find attr number for sysfs:
  	 * We map the attr number to core id of the CPU
  	 * The attr number is always core id + 2
  	 * The Pkgtemp will always show up as temp1_*, if available
a321cedb1   Carsten Emde   drivers/hwmon/cor...
449
  	 */
723f57343   Thomas Gleixner   hwmon: (coretemp)...
450
  	attr_no = pkg_flag ? PKG_SYSFS_ATTR_NO : TO_ATTR_NO(cpu);
6369a2887   Rudolf Marek   hwmon: (coretemp)...
451

199e0de7f   Durgadoss R   hwmon: (coretemp)...
452
453
  	if (attr_no > MAX_CORE_DATA - 1)
  		return -ERANGE;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
454
455
456
  	tdata = init_temp_data(cpu, pkg_flag);
  	if (!tdata)
  		return -ENOMEM;
bebe46782   Rudolf Marek   hwmon: New corete...
457

199e0de7f   Durgadoss R   hwmon: (coretemp)...
458
459
460
461
462
463
  	/* Test if we can access the status register */
  	err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
  	if (err)
  		goto exit_free;
  
  	/* We can access status register. Get Critical Temperature */
6bf9e9b09   Jean Delvare   hwmon: (coretemp)...
464
  	tdata->tjmax = get_tjmax(c, cpu, &pdev->dev);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
465

c814a4c7c   Durgadoss R   hwmon: (coretemp)...
466
  	/*
f4af6fd6e   Guenter Roeck   hwmon: (coretemp)...
467
468
469
  	 * Read the still undocumented bits 8:15 of IA32_TEMPERATURE_TARGET.
  	 * The target temperature is available on older CPUs but not in this
  	 * register. Atoms don't have the register at all.
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
470
  	 */
f4af6fd6e   Guenter Roeck   hwmon: (coretemp)...
471
472
473
474
475
476
477
478
  	if (c->x86_model > 0xe && c->x86_model != 0x1c) {
  		err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET,
  					&eax, &edx);
  		if (!err) {
  			tdata->ttarget
  			  = tdata->tjmax - ((eax >> 8) & 0xff) * 1000;
  			tdata->attr_size++;
  		}
c814a4c7c   Durgadoss R   hwmon: (coretemp)...
479
  	}
199e0de7f   Durgadoss R   hwmon: (coretemp)...
480
481
482
  	pdata->core_data[attr_no] = tdata;
  
  	/* Create sysfs interfaces */
d72d19c26   Guenter Roeck   hwmon: (coretemp)...
483
  	err = create_core_attrs(tdata, pdata->hwmon_dev, attr_no);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
484
485
  	if (err)
  		goto exit_free;
bebe46782   Rudolf Marek   hwmon: New corete...
486
487
  
  	return 0;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
488
  exit_free:
20ecb499f   Guenter Roeck   hwmon: (coretemp)...
489
  	pdata->core_data[attr_no] = NULL;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
490
491
492
  	kfree(tdata);
  	return err;
  }
4b138cf73   Thomas Gleixner   hwmon: (coretemp)...
493
494
  static void
  coretemp_add_core(struct platform_device *pdev, unsigned int cpu, int pkg_flag)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
495
  {
4b138cf73   Thomas Gleixner   hwmon: (coretemp)...
496
  	if (create_core_data(pdev, cpu, pkg_flag))
199e0de7f   Durgadoss R   hwmon: (coretemp)...
497
498
499
  		dev_err(&pdev->dev, "Adding Core %u failed
  ", cpu);
  }
4b138cf73   Thomas Gleixner   hwmon: (coretemp)...
500
  static void coretemp_remove_core(struct platform_data *pdata, int indx)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
501
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
502
503
504
  	struct temp_data *tdata = pdata->core_data[indx];
  
  	/* Remove the sysfs attributes */
d72d19c26   Guenter Roeck   hwmon: (coretemp)...
505
  	sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
506
507
508
509
  
  	kfree(pdata->core_data[indx]);
  	pdata->core_data[indx] = NULL;
  }
6c931ae1c   Bill Pemberton   hwmon: remove use...
510
  static int coretemp_probe(struct platform_device *pdev)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
511
  {
c503a811e   Guenter Roeck   hwmon: (coretemp)...
512
  	struct device *dev = &pdev->dev;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
513
  	struct platform_data *pdata;
bebe46782   Rudolf Marek   hwmon: New corete...
514

835896a59   Len Brown   hwmon/coretemp: C...
515
  	/* Initialize the per-zone data structures */
c503a811e   Guenter Roeck   hwmon: (coretemp)...
516
  	pdata = devm_kzalloc(dev, sizeof(struct platform_data), GFP_KERNEL);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
517
518
  	if (!pdata)
  		return -ENOMEM;
712668460   Thomas Gleixner   hwmon: (coretemp)...
519
  	pdata->pkg_id = pdev->id;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
520
  	platform_set_drvdata(pdev, pdata);
d72d19c26   Guenter Roeck   hwmon: (coretemp)...
521
522
523
  	pdata->hwmon_dev = devm_hwmon_device_register_with_groups(dev, DRVNAME,
  								  pdata, NULL);
  	return PTR_ERR_OR_ZERO(pdata->hwmon_dev);
bebe46782   Rudolf Marek   hwmon: New corete...
524
  }
281dfd0b6   Bill Pemberton   hwmon: remove use...
525
  static int coretemp_remove(struct platform_device *pdev)
bebe46782   Rudolf Marek   hwmon: New corete...
526
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
527
528
  	struct platform_data *pdata = platform_get_drvdata(pdev);
  	int i;
bebe46782   Rudolf Marek   hwmon: New corete...
529

199e0de7f   Durgadoss R   hwmon: (coretemp)...
530
531
  	for (i = MAX_CORE_DATA - 1; i >= 0; --i)
  		if (pdata->core_data[i])
d72d19c26   Guenter Roeck   hwmon: (coretemp)...
532
  			coretemp_remove_core(pdata, i);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
533

bebe46782   Rudolf Marek   hwmon: New corete...
534
535
536
537
538
  	return 0;
  }
  
  static struct platform_driver coretemp_driver = {
  	.driver = {
bebe46782   Rudolf Marek   hwmon: New corete...
539
540
541
  		.name = DRVNAME,
  	},
  	.probe = coretemp_probe,
9e5e9b7a9   Bill Pemberton   hwmon: remove use...
542
  	.remove = coretemp_remove,
bebe46782   Rudolf Marek   hwmon: New corete...
543
  };
712668460   Thomas Gleixner   hwmon: (coretemp)...
544
  static struct platform_device *coretemp_device_add(unsigned int cpu)
bebe46782   Rudolf Marek   hwmon: New corete...
545
  {
835896a59   Len Brown   hwmon/coretemp: C...
546
  	int err, zoneid = topology_logical_die_id(cpu);
bebe46782   Rudolf Marek   hwmon: New corete...
547
  	struct platform_device *pdev;
d883b9f09   Jean Delvare   hwmon: (coretemp)...
548

835896a59   Len Brown   hwmon/coretemp: C...
549
  	if (zoneid < 0)
712668460   Thomas Gleixner   hwmon: (coretemp)...
550
  		return ERR_PTR(-ENOMEM);
d883b9f09   Jean Delvare   hwmon: (coretemp)...
551

835896a59   Len Brown   hwmon/coretemp: C...
552
  	pdev = platform_device_alloc(DRVNAME, zoneid);
712668460   Thomas Gleixner   hwmon: (coretemp)...
553
554
  	if (!pdev)
  		return ERR_PTR(-ENOMEM);
bebe46782   Rudolf Marek   hwmon: New corete...
555
556
557
  
  	err = platform_device_add(pdev);
  	if (err) {
712668460   Thomas Gleixner   hwmon: (coretemp)...
558
559
  		platform_device_put(pdev);
  		return ERR_PTR(err);
bebe46782   Rudolf Marek   hwmon: New corete...
560
  	}
835896a59   Len Brown   hwmon/coretemp: C...
561
  	zone_devices[zoneid] = pdev;
712668460   Thomas Gleixner   hwmon: (coretemp)...
562
  	return pdev;
bebe46782   Rudolf Marek   hwmon: New corete...
563
  }
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
564
  static int coretemp_cpu_online(unsigned int cpu)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
565
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
566
  	struct platform_device *pdev = coretemp_get_pdev(cpu);
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
567
568
  	struct cpuinfo_x86 *c = &cpu_data(cpu);
  	struct platform_data *pdata;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
569
570
  
  	/*
90b4f30b6   Thomas Gleixner   hwmon: (coretemp)...
571
572
573
574
575
576
577
  	 * Don't execute this on resume as the offline callback did
  	 * not get executed on suspend.
  	 */
  	if (cpuhp_tasks_frozen)
  		return 0;
  
  	/*
199e0de7f   Durgadoss R   hwmon: (coretemp)...
578
579
580
581
  	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
  	 * sensors. We check this bit only, all the early CPUs
  	 * without thermal sensors will be filtered out.
  	 */
4ad334113   H. Peter Anvin   x86, cpufeature: ...
582
  	if (!cpu_has(c, X86_FEATURE_DTHERM))
2195c31b1   Thomas Gleixner   hwmon: (coretemp)...
583
  		return -ENODEV;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
584
585
  
  	if (!pdev) {
0eb9782ad   Jean Delvare   hwmon: (coretemp)...
586
587
  		/* Check the microcode version of the CPU */
  		if (chk_ucode_version(cpu))
2195c31b1   Thomas Gleixner   hwmon: (coretemp)...
588
  			return -EINVAL;
0eb9782ad   Jean Delvare   hwmon: (coretemp)...
589

199e0de7f   Durgadoss R   hwmon: (coretemp)...
590
591
592
593
594
595
  		/*
  		 * Alright, we have DTS support.
  		 * We are bringing the _first_ core in this pkg
  		 * online. So, initialize per-pkg data structures and
  		 * then bring this core online.
  		 */
712668460   Thomas Gleixner   hwmon: (coretemp)...
596
597
598
  		pdev = coretemp_device_add(cpu);
  		if (IS_ERR(pdev))
  			return PTR_ERR(pdev);
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
599

199e0de7f   Durgadoss R   hwmon: (coretemp)...
600
601
602
603
604
  		/*
  		 * Check whether pkgtemp support is available.
  		 * If so, add interfaces for pkgtemp.
  		 */
  		if (cpu_has(c, X86_FEATURE_PTS))
4b138cf73   Thomas Gleixner   hwmon: (coretemp)...
605
  			coretemp_add_core(pdev, cpu, 1);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
606
  	}
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
607
608
  
  	pdata = platform_get_drvdata(pdev);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
609
  	/*
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
610
611
  	 * Check whether a thread sibling is already online. If not add the
  	 * interface for this CPU core.
199e0de7f   Durgadoss R   hwmon: (coretemp)...
612
  	 */
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
613
  	if (!cpumask_intersects(&pdata->cpumask, topology_sibling_cpumask(cpu)))
4b138cf73   Thomas Gleixner   hwmon: (coretemp)...
614
  		coretemp_add_core(pdev, cpu, 0);
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
615
616
  
  	cpumask_set_cpu(cpu, &pdata->cpumask);
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
617
  	return 0;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
618
  }
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
619
  static int coretemp_cpu_offline(unsigned int cpu)
199e0de7f   Durgadoss R   hwmon: (coretemp)...
620
  {
199e0de7f   Durgadoss R   hwmon: (coretemp)...
621
  	struct platform_device *pdev = coretemp_get_pdev(cpu);
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
622
  	struct platform_data *pd;
723f57343   Thomas Gleixner   hwmon: (coretemp)...
623
  	struct temp_data *tdata;
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
624
  	int indx, target;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
625

90b4f30b6   Thomas Gleixner   hwmon: (coretemp)...
626
627
628
629
630
631
  	/*
  	 * Don't execute this on suspend as the device remove locks
  	 * up the machine.
  	 */
  	if (cpuhp_tasks_frozen)
  		return 0;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
632
633
  	/* If the physical CPU device does not exist, just return */
  	if (!pdev)
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
634
  		return 0;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
635

b70487112   Kirill A. Shutemov   hwmon: (coretemp)...
636
  	/* The core id is too big, just return */
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
637
  	indx = TO_ATTR_NO(cpu);
b70487112   Kirill A. Shutemov   hwmon: (coretemp)...
638
  	if (indx > MAX_CORE_DATA - 1)
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
639
  		return 0;
b70487112   Kirill A. Shutemov   hwmon: (coretemp)...
640

e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
641
642
643
644
  	pd = platform_get_drvdata(pdev);
  	tdata = pd->core_data[indx];
  
  	cpumask_clear_cpu(cpu, &pd->cpumask);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
645

f4e0bcf06   Guenter Roeck   hwmon: (coretemp)...
646
  	/*
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
647
648
649
  	 * If this is the last thread sibling, remove the CPU core
  	 * interface, If there is still a sibling online, transfer the
  	 * target cpu of that core interface to it.
f4e0bcf06   Guenter Roeck   hwmon: (coretemp)...
650
  	 */
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
651
652
653
654
655
656
657
  	target = cpumask_any_and(&pd->cpumask, topology_sibling_cpumask(cpu));
  	if (target >= nr_cpu_ids) {
  		coretemp_remove_core(pd, indx);
  	} else if (tdata && tdata->cpu == cpu) {
  		mutex_lock(&tdata->update_lock);
  		tdata->cpu = target;
  		mutex_unlock(&tdata->update_lock);
199e0de7f   Durgadoss R   hwmon: (coretemp)...
658
  	}
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
659

199e0de7f   Durgadoss R   hwmon: (coretemp)...
660
  	/*
712668460   Thomas Gleixner   hwmon: (coretemp)...
661
662
663
  	 * If all cores in this pkg are offline, remove the device. This
  	 * will invoke the platform driver remove function, which cleans up
  	 * the rest.
199e0de7f   Durgadoss R   hwmon: (coretemp)...
664
  	 */
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
665
  	if (cpumask_empty(&pd->cpumask)) {
835896a59   Len Brown   hwmon/coretemp: C...
666
  		zone_devices[topology_logical_die_id(cpu)] = NULL;
712668460   Thomas Gleixner   hwmon: (coretemp)...
667
  		platform_device_unregister(pdev);
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
668
  		return 0;
723f57343   Thomas Gleixner   hwmon: (coretemp)...
669
  	}
712668460   Thomas Gleixner   hwmon: (coretemp)...
670

723f57343   Thomas Gleixner   hwmon: (coretemp)...
671
672
673
674
  	/*
  	 * Check whether this core is the target for the package
  	 * interface. We need to assign it to some other cpu.
  	 */
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
675
  	tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
723f57343   Thomas Gleixner   hwmon: (coretemp)...
676
  	if (tdata && tdata->cpu == cpu) {
e1b370b64   Thomas Gleixner   hwmon: (coretemp)...
677
  		target = cpumask_first(&pd->cpumask);
723f57343   Thomas Gleixner   hwmon: (coretemp)...
678
679
680
681
  		mutex_lock(&tdata->update_lock);
  		tdata->cpu = target;
  		mutex_unlock(&tdata->update_lock);
  	}
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
682
  	return 0;
199e0de7f   Durgadoss R   hwmon: (coretemp)...
683
  }
e273bd98c   Jan Beulich   hwmon: struct x86...
684
  static const struct x86_cpu_id __initconst coretemp_ids[] = {
5cfc7ac7c   Thomas Gleixner   hwmon: Convert to...
685
  	X86_MATCH_VENDOR_FEATURE(INTEL, X86_FEATURE_DTHERM, NULL),
9b38096fd   Andi Kleen   HWMON: Convert co...
686
687
688
  	{}
  };
  MODULE_DEVICE_TABLE(x86cpu, coretemp_ids);
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
689
  static enum cpuhp_state coretemp_hp_online;
bebe46782   Rudolf Marek   hwmon: New corete...
690
691
  static int __init coretemp_init(void)
  {
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
692
  	int err;
bebe46782   Rudolf Marek   hwmon: New corete...
693

9b38096fd   Andi Kleen   HWMON: Convert co...
694
695
696
697
698
699
700
  	/*
  	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
  	 * sensors. We check this bit only, all the early CPUs
  	 * without thermal sensors will be filtered out.
  	 */
  	if (!x86_match_cpu(coretemp_ids))
  		return -ENODEV;
bebe46782   Rudolf Marek   hwmon: New corete...
701

835896a59   Len Brown   hwmon/coretemp: C...
702
703
  	max_zones = topology_max_packages() * topology_max_die_per_package();
  	zone_devices = kcalloc(max_zones, sizeof(struct platform_device *),
712668460   Thomas Gleixner   hwmon: (coretemp)...
704
  			      GFP_KERNEL);
835896a59   Len Brown   hwmon/coretemp: C...
705
  	if (!zone_devices)
712668460   Thomas Gleixner   hwmon: (coretemp)...
706
  		return -ENOMEM;
bebe46782   Rudolf Marek   hwmon: New corete...
707
708
  	err = platform_driver_register(&coretemp_driver);
  	if (err)
e027a2dea   Wenwen Wang   hwmon (coretemp) ...
709
  		goto outzone;
bebe46782   Rudolf Marek   hwmon: New corete...
710

e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
711
712
713
  	err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
  				coretemp_cpu_online, coretemp_cpu_offline);
  	if (err < 0)
2195c31b1   Thomas Gleixner   hwmon: (coretemp)...
714
  		goto outdrv;
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
715
  	coretemp_hp_online = err;
bebe46782   Rudolf Marek   hwmon: New corete...
716
  	return 0;
2195c31b1   Thomas Gleixner   hwmon: (coretemp)...
717
  outdrv:
bebe46782   Rudolf Marek   hwmon: New corete...
718
  	platform_driver_unregister(&coretemp_driver);
e027a2dea   Wenwen Wang   hwmon (coretemp) ...
719
  outzone:
835896a59   Len Brown   hwmon/coretemp: C...
720
  	kfree(zone_devices);
bebe46782   Rudolf Marek   hwmon: New corete...
721
722
  	return err;
  }
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
723
  module_init(coretemp_init)
bebe46782   Rudolf Marek   hwmon: New corete...
724
725
726
  
  static void __exit coretemp_exit(void)
  {
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
727
  	cpuhp_remove_state(coretemp_hp_online);
bebe46782   Rudolf Marek   hwmon: New corete...
728
  	platform_driver_unregister(&coretemp_driver);
835896a59   Len Brown   hwmon/coretemp: C...
729
  	kfree(zone_devices);
bebe46782   Rudolf Marek   hwmon: New corete...
730
  }
e00ca5df3   Thomas Gleixner   hwmon: (coretemp)...
731
  module_exit(coretemp_exit)
bebe46782   Rudolf Marek   hwmon: New corete...
732
733
734
735
  
  MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>");
  MODULE_DESCRIPTION("Intel Core temperature monitor");
  MODULE_LICENSE("GPL");