Linux 6.12-rc1
[linux-block.git] / drivers / hwmon / k10temp.c
CommitLineData
6e7c1094 1// SPDX-License-Identifier: GPL-2.0-or-later
3c57e89b 2/*
d547552a
GR
3 * k10temp.c - AMD Family 10h/11h/12h/14h/15h/16h/17h
4 * processor hardware monitoring
3c57e89b
CL
5 *
6 * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
d547552a 7 * Copyright (c) 2020 Guenter Roeck <linux@roeck-us.net>
c7579389
GR
8 *
9 * Implementation notes:
fd8bdb23 10 * - CCD register address information as well as the calculation to
c7579389
GR
11 * convert raw register values is from https://github.com/ocerman/zenpower.
12 * The information is not confirmed from chip datasheets, but experiments
13 * suggest that it provides reasonable temperature values.
3c57e89b
CL
14 */
15
a6d210da 16#include <linux/bitops.h>
3c57e89b
CL
17#include <linux/err.h>
18#include <linux/hwmon.h>
3c57e89b
CL
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/pci.h>
dedf7dce 22#include <linux/pci_ids.h>
3b031622 23#include <asm/amd_nb.h>
3c57e89b
CL
24#include <asm/processor.h>
25
9e581311 26MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
3c57e89b
CL
27MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
28MODULE_LICENSE("GPL");
29
30static bool force;
31module_param(force, bool, 0444);
32MODULE_PARM_DESC(force, "force loading on processors with erratum 319");
33
f89ce270
AG
34/* Provide lock for writing to NB_SMU_IND_ADDR */
35static DEFINE_MUTEX(nb_smu_ind_mutex);
36
ccaf63b4
GR
37#ifndef PCI_DEVICE_ID_AMD_15H_M70H_NB_F3
38#define PCI_DEVICE_ID_AMD_15H_M70H_NB_F3 0x15b3
39#endif
40
c5114a1c 41/* CPUID function 0x80000001, ebx */
a6d210da 42#define CPUID_PKGTYPE_MASK GENMASK(31, 28)
c5114a1c
CL
43#define CPUID_PKGTYPE_F 0x00000000
44#define CPUID_PKGTYPE_AM2R2_AM3 0x10000000
45
46/* DRAM controller (PCI function 2) */
47#define REG_DCT0_CONFIG_HIGH 0x094
a6d210da 48#define DDR3_MODE BIT(8)
c5114a1c
CL
49
50/* miscellaneous (PCI function 3) */
3c57e89b 51#define REG_HARDWARE_THERMAL_CONTROL 0x64
a6d210da 52#define HTC_ENABLE BIT(0)
3c57e89b
CL
53
54#define REG_REPORTED_TEMPERATURE 0xa4
55
56#define REG_NORTHBRIDGE_CAPABILITIES 0xe8
a6d210da 57#define NB_CAP_HTC BIT(10)
3c57e89b 58
f89ce270 59/*
40626a1b
GR
60 * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
61 * and REG_REPORTED_TEMPERATURE have been moved to
62 * D0F0xBC_xD820_0C64 [Hardware Temperature Control]
63 * D0F0xBC_xD820_0CA4 [Reported Temperature Control]
f89ce270 64 */
40626a1b 65#define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET 0xd8200c64
f89ce270 66#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
f89ce270 67
3cd9da41 68/* Common for Zen CPU families (Family 17h and 18h and 19h and 1Ah) */
0e3f52bb 69#define ZEN_REPORTED_TEMP_CTRL_BASE 0x00059800
fd8bdb23 70
0e3f52bb
ML
71#define ZEN_CCD_TEMP(offset, x) (ZEN_REPORTED_TEMP_CTRL_BASE + \
72 (offset) + ((x) * 4))
17822417
WH
73#define ZEN_CCD_TEMP_VALID BIT(11)
74#define ZEN_CCD_TEMP_MASK GENMASK(10, 0)
9af0a9ae 75
17822417
WH
76#define ZEN_CUR_TEMP_SHIFT 21
77#define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19)
0c072385 78#define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16)
b00647c4 79
e146503a
BK
80/*
81 * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius.
82 * Use the model name to identify 3255 CPUs and set a flag to display negative temperature.
83 * Do not round off to zero for negative Tctl or Tdie values if the flag is set
84 */
85#define AMD_I3255_STR "3255"
86
68546abf
GR
87struct k10temp_data {
88 struct pci_dev *pdev;
40626a1b 89 void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
68546abf 90 void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
1b50b776 91 int temp_offset;
1b597889 92 u32 temp_adjust_mask;
60465245 93 u32 show_temp;
60465245 94 bool is_zen;
0e3f52bb 95 u32 ccd_offset;
e146503a 96 bool disp_negative;
1b50b776
GR
97};
98
60465245
GR
99#define TCTL_BIT 0
100#define TDIE_BIT 1
101#define TCCD_BIT(x) ((x) + 2)
102
103#define HAVE_TEMP(d, channel) ((d)->show_temp & BIT(channel))
60465245 104
1b50b776
GR
105struct tctl_offset {
106 u8 model;
107 char const *id;
108 int offset;
109};
110
111static const struct tctl_offset tctl_offset_table[] = {
ab5ee246 112 { 0x17, "AMD Ryzen 5 1600X", 20000 },
1b50b776
GR
113 { 0x17, "AMD Ryzen 7 1700X", 20000 },
114 { 0x17, "AMD Ryzen 7 1800X", 20000 },
1b597889 115 { 0x17, "AMD Ryzen 7 2700X", 10000 },
cd6a2064
GR
116 { 0x17, "AMD Ryzen Threadripper 19", 27000 }, /* 19{00,20,50}X */
117 { 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */
68546abf
GR
118};
119
40626a1b
GR
120static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
121{
122 pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
123}
124
68546abf
GR
125static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
126{
127 pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
128}
129
130static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
131 unsigned int base, int offset, u32 *val)
f89ce270
AG
132{
133 mutex_lock(&nb_smu_ind_mutex);
134 pci_bus_write_config_dword(pdev->bus, devfn,
68546abf 135 base, offset);
f89ce270 136 pci_bus_read_config_dword(pdev->bus, devfn,
68546abf 137 base + 4, val);
f89ce270
AG
138 mutex_unlock(&nb_smu_ind_mutex);
139}
140
40626a1b
GR
141static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
142{
143 amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
144 F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
145}
146
68546abf
GR
147static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
148{
149 amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
150 F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
151}
152
17822417 153static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
9af0a9ae 154{
c2d79cc5
YG
155 if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
156 ZEN_REPORTED_TEMP_CTRL_BASE, regval))
157 *regval = 0;
9af0a9ae
GR
158}
159
cc66126f
YG
160static int read_ccd_temp_reg(struct k10temp_data *data, int ccd, u32 *regval)
161{
162 u16 node_id = amd_pci_dev_to_node_id(data->pdev);
163
164 return amd_smn_read(node_id, ZEN_CCD_TEMP(data->ccd_offset, ccd), regval);
165}
166
d547552a 167static long get_raw_temp(struct k10temp_data *data)
3c57e89b 168{
f934c059 169 u32 regval;
d547552a 170 long temp;
68546abf
GR
171
172 data->read_tempreg(data->pdev, &regval);
17822417 173 temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
0c072385
BM
174 if ((regval & data->temp_adjust_mask) ||
175 (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
1b597889 176 temp -= 49000;
f934c059
GR
177 return temp;
178}
179
0e786f32 180static const char *k10temp_temp_label[] = {
d547552a 181 "Tctl",
b02c6857 182 "Tdie",
c7579389
GR
183 "Tccd1",
184 "Tccd2",
fd8bdb23
GR
185 "Tccd3",
186 "Tccd4",
187 "Tccd5",
188 "Tccd6",
189 "Tccd7",
190 "Tccd8",
8bb050cd
BM
191 "Tccd9",
192 "Tccd10",
193 "Tccd11",
194 "Tccd12",
d547552a 195};
f934c059 196
d547552a
GR
197static int k10temp_read_labels(struct device *dev,
198 enum hwmon_sensor_types type,
199 u32 attr, int channel, const char **str)
3c57e89b 200{
b00647c4
GR
201 switch (type) {
202 case hwmon_temp:
203 *str = k10temp_temp_label[channel];
204 break;
b00647c4
GR
205 default:
206 return -EOPNOTSUPP;
207 }
208 return 0;
209}
210
211static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
212 long *val)
3c57e89b 213{
68546abf 214 struct k10temp_data *data = dev_get_drvdata(dev);
c2d79cc5 215 int ret = -EOPNOTSUPP;
3c57e89b 216 u32 regval;
3c57e89b 217
d547552a
GR
218 switch (attr) {
219 case hwmon_temp_input:
220 switch (channel) {
b02c6857
GR
221 case 0: /* Tctl */
222 *val = get_raw_temp(data);
e146503a 223 if (*val < 0 && !data->disp_negative)
d547552a
GR
224 *val = 0;
225 break;
b02c6857
GR
226 case 1: /* Tdie */
227 *val = get_raw_temp(data) - data->temp_offset;
e146503a 228 if (*val < 0 && !data->disp_negative)
d547552a
GR
229 *val = 0;
230 break;
8bb050cd 231 case 2 ... 13: /* Tccd{1-12} */
cc66126f 232 ret = read_ccd_temp_reg(data, channel - 2, &regval);
c2d79cc5
YG
233
234 if (ret)
235 return ret;
236
17822417 237 *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
c7579389 238 break;
d547552a 239 default:
c2d79cc5 240 return ret;
d547552a
GR
241 }
242 break;
243 case hwmon_temp_max:
244 *val = 70 * 1000;
245 break;
246 case hwmon_temp_crit:
247 data->read_htcreg(data->pdev, &regval);
248 *val = ((regval >> 16) & 0x7f) * 500 + 52000;
249 break;
250 case hwmon_temp_crit_hyst:
251 data->read_htcreg(data->pdev, &regval);
252 *val = (((regval >> 16) & 0x7f)
253 - ((regval >> 24) & 0xf)) * 500 + 52000;
254 break;
255 default:
c2d79cc5 256 return ret;
d547552a
GR
257 }
258 return 0;
3c57e89b
CL
259}
260
b00647c4
GR
261static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
262 u32 attr, int channel, long *val)
263{
264 switch (type) {
265 case hwmon_temp:
266 return k10temp_read_temp(dev, attr, channel, val);
b00647c4
GR
267 default:
268 return -EOPNOTSUPP;
269 }
270}
271
efdf761a 272static umode_t k10temp_is_visible(const void *drvdata,
d547552a
GR
273 enum hwmon_sensor_types type,
274 u32 attr, int channel)
3e3e1022 275{
efdf761a 276 const struct k10temp_data *data = drvdata;
68546abf 277 struct pci_dev *pdev = data->pdev;
f934c059 278 u32 reg;
3e3e1022 279
d547552a
GR
280 switch (type) {
281 case hwmon_temp:
282 switch (attr) {
283 case hwmon_temp_input:
60465245 284 if (!HAVE_TEMP(data, channel))
d547552a
GR
285 return 0;
286 break;
287 case hwmon_temp_max:
60465245 288 if (channel || data->is_zen)
d547552a
GR
289 return 0;
290 break;
291 case hwmon_temp_crit:
292 case hwmon_temp_crit_hyst:
293 if (channel || !data->read_htcreg)
294 return 0;
295
296 pci_read_config_dword(pdev,
297 REG_NORTHBRIDGE_CAPABILITIES,
298 &reg);
299 if (!(reg & NB_CAP_HTC))
300 return 0;
301
302 data->read_htcreg(data->pdev, &reg);
303 if (!(reg & HTC_ENABLE))
304 return 0;
305 break;
306 case hwmon_temp_label:
60465245
GR
307 /* Show temperature labels only on Zen CPUs */
308 if (!data->is_zen || !HAVE_TEMP(data, channel))
c7579389 309 return 0;
d547552a
GR
310 break;
311 default:
f934c059 312 return 0;
d547552a 313 }
f934c059 314 break;
d547552a
GR
315 default:
316 return 0;
3e3e1022 317 }
d547552a 318 return 0444;
3e3e1022
GR
319}
320
6c931ae1 321static bool has_erratum_319(struct pci_dev *pdev)
3c57e89b 322{
c5114a1c
CL
323 u32 pkg_type, reg_dram_cfg;
324
325 if (boot_cpu_data.x86 != 0x10)
326 return false;
327
3c57e89b 328 /*
c5114a1c
CL
329 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
330 * may be unreliable.
3c57e89b 331 */
c5114a1c
CL
332 pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
333 if (pkg_type == CPUID_PKGTYPE_F)
334 return true;
335 if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
336 return false;
337
eefc2d9e 338 /* DDR3 memory implies socket AM3, which is good */
c5114a1c
CL
339 pci_bus_read_config_dword(pdev->bus,
340 PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
341 REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
eefc2d9e
JD
342 if (reg_dram_cfg & DDR3_MODE)
343 return false;
344
345 /*
346 * Unfortunately it is possible to run a socket AM3 CPU with DDR2
347 * memory. We blacklist all the cores which do exist in socket AM2+
348 * format. It still isn't perfect, as RB-C2 cores exist in both AM2+
349 * and AM3 formats, but that's the best we can do.
350 */
351 return boot_cpu_data.x86_model < 4 ||
b399151c 352 (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
3c57e89b
CL
353}
354
4dd50f3c 355static const struct hwmon_channel_info * const k10temp_info[] = {
d547552a
GR
356 HWMON_CHANNEL_INFO(temp,
357 HWMON_T_INPUT | HWMON_T_MAX |
358 HWMON_T_CRIT | HWMON_T_CRIT_HYST |
359 HWMON_T_LABEL,
c7579389
GR
360 HWMON_T_INPUT | HWMON_T_LABEL,
361 HWMON_T_INPUT | HWMON_T_LABEL,
fd8bdb23
GR
362 HWMON_T_INPUT | HWMON_T_LABEL,
363 HWMON_T_INPUT | HWMON_T_LABEL,
364 HWMON_T_INPUT | HWMON_T_LABEL,
365 HWMON_T_INPUT | HWMON_T_LABEL,
366 HWMON_T_INPUT | HWMON_T_LABEL,
367 HWMON_T_INPUT | HWMON_T_LABEL,
8bb050cd
BM
368 HWMON_T_INPUT | HWMON_T_LABEL,
369 HWMON_T_INPUT | HWMON_T_LABEL,
370 HWMON_T_INPUT | HWMON_T_LABEL,
371 HWMON_T_INPUT | HWMON_T_LABEL,
d547552a
GR
372 HWMON_T_INPUT | HWMON_T_LABEL),
373 NULL
374};
375
376static const struct hwmon_ops k10temp_hwmon_ops = {
377 .is_visible = k10temp_is_visible,
378 .read = k10temp_read,
379 .read_string = k10temp_read_labels,
380};
381
382static const struct hwmon_chip_info k10temp_chip_info = {
383 .ops = &k10temp_hwmon_ops,
384 .info = k10temp_info,
385};
386
a8bc4165 387static void k10temp_get_ccd_support(struct k10temp_data *data, int limit)
fd8bdb23
GR
388{
389 u32 regval;
390 int i;
391
392 for (i = 0; i < limit; i++) {
c2d79cc5
YG
393 /*
394 * Ignore inaccessible CCDs.
395 *
396 * Some systems will return a register value of 0, and the TEMP_VALID
397 * bit check below will naturally fail.
398 *
399 * Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for
400 * the register value. And this will incorrectly pass the TEMP_VALID
401 * bit check.
402 */
cc66126f 403 if (read_ccd_temp_reg(data, i, &regval))
c2d79cc5
YG
404 continue;
405
17822417 406 if (regval & ZEN_CCD_TEMP_VALID)
60465245 407 data->show_temp |= BIT(TCCD_BIT(i));
fd8bdb23
GR
408 }
409}
410
d547552a 411static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3c57e89b 412{
c5114a1c 413 int unreliable = has_erratum_319(pdev);
3e3e1022 414 struct device *dev = &pdev->dev;
68546abf 415 struct k10temp_data *data;
3e3e1022 416 struct device *hwmon_dev;
1b50b776 417 int i;
3c57e89b 418
3e3e1022
GR
419 if (unreliable) {
420 if (!force) {
421 dev_err(dev,
422 "unreliable CPU thermal sensor; monitoring disabled\n");
423 return -ENODEV;
424 }
425 dev_warn(dev,
3c57e89b 426 "unreliable CPU thermal sensor; check erratum 319\n");
3e3e1022 427 }
3c57e89b 428
68546abf
GR
429 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
430 if (!data)
431 return -ENOMEM;
432
433 data->pdev = pdev;
60465245 434 data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */
68546abf 435
e146503a
BK
436 if (boot_cpu_data.x86 == 0x17 &&
437 strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) {
438 data->disp_negative = true;
439 }
440
45995100
ML
441 data->is_zen = cpu_feature_enabled(X86_FEATURE_ZEN);
442 if (data->is_zen) {
443 data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
444 data->read_tempreg = read_tempreg_nb_zen;
445 } else if (boot_cpu_data.x86 == 0x15 &&
53dfa008
GR
446 ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
447 (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
40626a1b 448 data->read_htcreg = read_htcreg_nb_f15;
68546abf 449 data->read_tempreg = read_tempreg_nb_f15;
45995100
ML
450 } else {
451 data->read_htcreg = read_htcreg_pci;
452 data->read_tempreg = read_tempreg_pci;
453 }
c7579389 454
45995100 455 if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
c7579389
GR
456 switch (boot_cpu_data.x86_model) {
457 case 0x1: /* Zen */
458 case 0x8: /* Zen+ */
459 case 0x11: /* Zen APU */
460 case 0x18: /* Zen+ APU */
0e3f52bb 461 data->ccd_offset = 0x154;
a8bc4165 462 k10temp_get_ccd_support(data, 4);
c7579389
GR
463 break;
464 case 0x31: /* Zen2 Threadripper */
128066c8
ML
465 case 0x60: /* Renoir */
466 case 0x68: /* Lucienne */
c7579389 467 case 0x71: /* Zen2 */
0e3f52bb 468 data->ccd_offset = 0x154;
a8bc4165 469 k10temp_get_ccd_support(data, 8);
c7579389 470 break;
d906fa73
ML
471 case 0xa0 ... 0xaf:
472 data->ccd_offset = 0x300;
a8bc4165 473 k10temp_get_ccd_support(data, 8);
d906fa73 474 break;
c7579389 475 }
55163a1c 476 } else if (boot_cpu_data.x86 == 0x19) {
55163a1c 477 switch (boot_cpu_data.x86_model) {
c8d0d3fa 478 case 0x0 ... 0x1: /* Zen3 SP3/TR */
06f34bcc 479 case 0x8: /* Zen3 TR Chagall */
c8d0d3fa 480 case 0x21: /* Zen3 Ryzen Desktop */
128066c8 481 case 0x50 ... 0x5f: /* Green Sardine */
0e3f52bb 482 data->ccd_offset = 0x154;
a8bc4165 483 k10temp_get_ccd_support(data, 8);
55163a1c 484 break;
25572c81
ML
485 case 0x40 ... 0x4f: /* Yellow Carp */
486 data->ccd_offset = 0x300;
a8bc4165 487 k10temp_get_ccd_support(data, 8);
25572c81 488 break;
d906fa73
ML
489 case 0x60 ... 0x6f:
490 case 0x70 ... 0x7f:
491 data->ccd_offset = 0x308;
a8bc4165 492 k10temp_get_ccd_support(data, 8);
d906fa73 493 break;
8bb050cd
BM
494 case 0x10 ... 0x1f:
495 case 0xa0 ... 0xaf:
496 data->ccd_offset = 0x300;
a8bc4165 497 k10temp_get_ccd_support(data, 12);
8bb050cd 498 break;
55163a1c 499 }
1b597889 500 }
68546abf 501
1b50b776
GR
502 for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
503 const struct tctl_offset *entry = &tctl_offset_table[i];
504
505 if (boot_cpu_data.x86 == entry->model &&
506 strstr(boot_cpu_data.x86_model_id, entry->id)) {
02a2484c 507 data->show_temp |= BIT(TDIE_BIT); /* show Tdie */
1b50b776
GR
508 data->temp_offset = entry->offset;
509 break;
510 }
511 }
512
d547552a
GR
513 hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
514 &k10temp_chip_info,
515 NULL);
8999eabf 516 return PTR_ERR_OR_ZERO(hwmon_dev);
3c57e89b
CL
517}
518
cd9bb056 519static const struct pci_device_id k10temp_id_table[] = {
3c57e89b
CL
520 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
521 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
aa4790a6 522 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
9e581311 523 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
24214449 524 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
d303b1b5 525 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
f89ce270 526 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
ccaf63b4 527 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M70H_NB_F3) },
30b146d1 528 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
ec015950 529 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
9af0a9ae 530 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3b031622 531 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
210ba120 532 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
279f0b3a 533 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
12163cfb 534 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
d906fa73 535 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
55163a1c 536 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
3cf90efa 537 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
25572c81 538 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
02c9dce4 539 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
d906fa73
ML
540 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
541 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
7d8accfa 542 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
3cd9da41
AN
543 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
544 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
59c34008 545 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
d93217d8 546 { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3c57e89b
CL
547 {}
548};
549MODULE_DEVICE_TABLE(pci, k10temp_id_table);
550
551static struct pci_driver k10temp_driver = {
552 .name = "k10temp",
553 .id_table = k10temp_id_table,
554 .probe = k10temp_probe,
3c57e89b
CL
555};
556
f71f5a55 557module_pci_driver(k10temp_driver);