Merge tag 'pci-v6.16-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
[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>
0a35c928 23#include <asm/amd/node.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
7dd57db4
ML
153static u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
154{
155 return PCI_SLOT(pdev->devfn) - AMD_NODE0_PCI_SLOT;
156}
157
17822417 158static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
9af0a9ae 159{
c2d79cc5
YG
160 if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
161 ZEN_REPORTED_TEMP_CTRL_BASE, regval))
162 *regval = 0;
9af0a9ae
GR
163}
164
cc66126f
YG
165static int read_ccd_temp_reg(struct k10temp_data *data, int ccd, u32 *regval)
166{
167 u16 node_id = amd_pci_dev_to_node_id(data->pdev);
168
169 return amd_smn_read(node_id, ZEN_CCD_TEMP(data->ccd_offset, ccd), regval);
170}
171
d547552a 172static long get_raw_temp(struct k10temp_data *data)
3c57e89b 173{
f934c059 174 u32 regval;
d547552a 175 long temp;
68546abf
GR
176
177 data->read_tempreg(data->pdev, &regval);
17822417 178 temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
0c072385
BM
179 if ((regval & data->temp_adjust_mask) ||
180 (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
1b597889 181 temp -= 49000;
f934c059
GR
182 return temp;
183}
184
0e786f32 185static const char *k10temp_temp_label[] = {
d547552a 186 "Tctl",
b02c6857 187 "Tdie",
c7579389
GR
188 "Tccd1",
189 "Tccd2",
fd8bdb23
GR
190 "Tccd3",
191 "Tccd4",
192 "Tccd5",
193 "Tccd6",
194 "Tccd7",
195 "Tccd8",
8bb050cd
BM
196 "Tccd9",
197 "Tccd10",
198 "Tccd11",
199 "Tccd12",
d547552a 200};
f934c059 201
d547552a
GR
202static int k10temp_read_labels(struct device *dev,
203 enum hwmon_sensor_types type,
204 u32 attr, int channel, const char **str)
3c57e89b 205{
b00647c4
GR
206 switch (type) {
207 case hwmon_temp:
208 *str = k10temp_temp_label[channel];
209 break;
b00647c4
GR
210 default:
211 return -EOPNOTSUPP;
212 }
213 return 0;
214}
215
216static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
217 long *val)
3c57e89b 218{
68546abf 219 struct k10temp_data *data = dev_get_drvdata(dev);
c2d79cc5 220 int ret = -EOPNOTSUPP;
3c57e89b 221 u32 regval;
3c57e89b 222
d547552a
GR
223 switch (attr) {
224 case hwmon_temp_input:
225 switch (channel) {
b02c6857
GR
226 case 0: /* Tctl */
227 *val = get_raw_temp(data);
e146503a 228 if (*val < 0 && !data->disp_negative)
d547552a
GR
229 *val = 0;
230 break;
b02c6857
GR
231 case 1: /* Tdie */
232 *val = get_raw_temp(data) - data->temp_offset;
e146503a 233 if (*val < 0 && !data->disp_negative)
d547552a
GR
234 *val = 0;
235 break;
8bb050cd 236 case 2 ... 13: /* Tccd{1-12} */
cc66126f 237 ret = read_ccd_temp_reg(data, channel - 2, &regval);
c2d79cc5
YG
238
239 if (ret)
240 return ret;
241
17822417 242 *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
c7579389 243 break;
d547552a 244 default:
c2d79cc5 245 return ret;
d547552a
GR
246 }
247 break;
248 case hwmon_temp_max:
249 *val = 70 * 1000;
250 break;
251 case hwmon_temp_crit:
252 data->read_htcreg(data->pdev, &regval);
253 *val = ((regval >> 16) & 0x7f) * 500 + 52000;
254 break;
255 case hwmon_temp_crit_hyst:
256 data->read_htcreg(data->pdev, &regval);
257 *val = (((regval >> 16) & 0x7f)
258 - ((regval >> 24) & 0xf)) * 500 + 52000;
259 break;
260 default:
c2d79cc5 261 return ret;
d547552a
GR
262 }
263 return 0;
3c57e89b
CL
264}
265
b00647c4
GR
266static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
267 u32 attr, int channel, long *val)
268{
269 switch (type) {
270 case hwmon_temp:
271 return k10temp_read_temp(dev, attr, channel, val);
b00647c4
GR
272 default:
273 return -EOPNOTSUPP;
274 }
275}
276
efdf761a 277static umode_t k10temp_is_visible(const void *drvdata,
d547552a
GR
278 enum hwmon_sensor_types type,
279 u32 attr, int channel)
3e3e1022 280{
efdf761a 281 const struct k10temp_data *data = drvdata;
68546abf 282 struct pci_dev *pdev = data->pdev;
f934c059 283 u32 reg;
3e3e1022 284
d547552a
GR
285 switch (type) {
286 case hwmon_temp:
287 switch (attr) {
288 case hwmon_temp_input:
60465245 289 if (!HAVE_TEMP(data, channel))
d547552a
GR
290 return 0;
291 break;
292 case hwmon_temp_max:
60465245 293 if (channel || data->is_zen)
d547552a
GR
294 return 0;
295 break;
296 case hwmon_temp_crit:
297 case hwmon_temp_crit_hyst:
298 if (channel || !data->read_htcreg)
299 return 0;
300
301 pci_read_config_dword(pdev,
302 REG_NORTHBRIDGE_CAPABILITIES,
303 &reg);
304 if (!(reg & NB_CAP_HTC))
305 return 0;
306
307 data->read_htcreg(data->pdev, &reg);
308 if (!(reg & HTC_ENABLE))
309 return 0;
310 break;
311 case hwmon_temp_label:
60465245
GR
312 /* Show temperature labels only on Zen CPUs */
313 if (!data->is_zen || !HAVE_TEMP(data, channel))
c7579389 314 return 0;
d547552a
GR
315 break;
316 default:
f934c059 317 return 0;
d547552a 318 }
f934c059 319 break;
d547552a
GR
320 default:
321 return 0;
3e3e1022 322 }
d547552a 323 return 0444;
3e3e1022
GR
324}
325
6c931ae1 326static bool has_erratum_319(struct pci_dev *pdev)
3c57e89b 327{
c5114a1c
CL
328 u32 pkg_type, reg_dram_cfg;
329
330 if (boot_cpu_data.x86 != 0x10)
331 return false;
332
3c57e89b 333 /*
c5114a1c
CL
334 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
335 * may be unreliable.
3c57e89b 336 */
c5114a1c
CL
337 pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
338 if (pkg_type == CPUID_PKGTYPE_F)
339 return true;
340 if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
341 return false;
342
eefc2d9e 343 /* DDR3 memory implies socket AM3, which is good */
c5114a1c
CL
344 pci_bus_read_config_dword(pdev->bus,
345 PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
346 REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
eefc2d9e
JD
347 if (reg_dram_cfg & DDR3_MODE)
348 return false;
349
350 /*
351 * Unfortunately it is possible to run a socket AM3 CPU with DDR2
352 * memory. We blacklist all the cores which do exist in socket AM2+
353 * format. It still isn't perfect, as RB-C2 cores exist in both AM2+
354 * and AM3 formats, but that's the best we can do.
355 */
356 return boot_cpu_data.x86_model < 4 ||
b399151c 357 (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
3c57e89b
CL
358}
359
4dd50f3c 360static const struct hwmon_channel_info * const k10temp_info[] = {
d547552a
GR
361 HWMON_CHANNEL_INFO(temp,
362 HWMON_T_INPUT | HWMON_T_MAX |
363 HWMON_T_CRIT | HWMON_T_CRIT_HYST |
364 HWMON_T_LABEL,
c7579389
GR
365 HWMON_T_INPUT | HWMON_T_LABEL,
366 HWMON_T_INPUT | HWMON_T_LABEL,
fd8bdb23
GR
367 HWMON_T_INPUT | HWMON_T_LABEL,
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,
372 HWMON_T_INPUT | HWMON_T_LABEL,
8bb050cd
BM
373 HWMON_T_INPUT | HWMON_T_LABEL,
374 HWMON_T_INPUT | HWMON_T_LABEL,
375 HWMON_T_INPUT | HWMON_T_LABEL,
376 HWMON_T_INPUT | HWMON_T_LABEL,
d547552a
GR
377 HWMON_T_INPUT | HWMON_T_LABEL),
378 NULL
379};
380
381static const struct hwmon_ops k10temp_hwmon_ops = {
382 .is_visible = k10temp_is_visible,
383 .read = k10temp_read,
384 .read_string = k10temp_read_labels,
385};
386
387static const struct hwmon_chip_info k10temp_chip_info = {
388 .ops = &k10temp_hwmon_ops,
389 .info = k10temp_info,
390};
391
a8bc4165 392static void k10temp_get_ccd_support(struct k10temp_data *data, int limit)
fd8bdb23
GR
393{
394 u32 regval;
395 int i;
396
397 for (i = 0; i < limit; i++) {
c2d79cc5
YG
398 /*
399 * Ignore inaccessible CCDs.
400 *
401 * Some systems will return a register value of 0, and the TEMP_VALID
402 * bit check below will naturally fail.
403 *
404 * Other systems will return a PCI_ERROR_RESPONSE (0xFFFFFFFF) for
405 * the register value. And this will incorrectly pass the TEMP_VALID
406 * bit check.
407 */
cc66126f 408 if (read_ccd_temp_reg(data, i, &regval))
c2d79cc5
YG
409 continue;
410
17822417 411 if (regval & ZEN_CCD_TEMP_VALID)
60465245 412 data->show_temp |= BIT(TCCD_BIT(i));
fd8bdb23
GR
413 }
414}
415
d547552a 416static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3c57e89b 417{
c5114a1c 418 int unreliable = has_erratum_319(pdev);
3e3e1022 419 struct device *dev = &pdev->dev;
68546abf 420 struct k10temp_data *data;
3e3e1022 421 struct device *hwmon_dev;
1b50b776 422 int i;
3c57e89b 423
3e3e1022
GR
424 if (unreliable) {
425 if (!force) {
426 dev_err(dev,
427 "unreliable CPU thermal sensor; monitoring disabled\n");
428 return -ENODEV;
429 }
430 dev_warn(dev,
3c57e89b 431 "unreliable CPU thermal sensor; check erratum 319\n");
3e3e1022 432 }
3c57e89b 433
68546abf
GR
434 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
435 if (!data)
436 return -ENOMEM;
437
438 data->pdev = pdev;
60465245 439 data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */
68546abf 440
e146503a
BK
441 if (boot_cpu_data.x86 == 0x17 &&
442 strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) {
443 data->disp_negative = true;
444 }
445
45995100
ML
446 data->is_zen = cpu_feature_enabled(X86_FEATURE_ZEN);
447 if (data->is_zen) {
448 data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
449 data->read_tempreg = read_tempreg_nb_zen;
450 } else if (boot_cpu_data.x86 == 0x15 &&
53dfa008
GR
451 ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
452 (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
40626a1b 453 data->read_htcreg = read_htcreg_nb_f15;
68546abf 454 data->read_tempreg = read_tempreg_nb_f15;
45995100
ML
455 } else {
456 data->read_htcreg = read_htcreg_pci;
457 data->read_tempreg = read_tempreg_pci;
458 }
c7579389 459
45995100 460 if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
c7579389
GR
461 switch (boot_cpu_data.x86_model) {
462 case 0x1: /* Zen */
463 case 0x8: /* Zen+ */
464 case 0x11: /* Zen APU */
465 case 0x18: /* Zen+ APU */
0e3f52bb 466 data->ccd_offset = 0x154;
a8bc4165 467 k10temp_get_ccd_support(data, 4);
c7579389
GR
468 break;
469 case 0x31: /* Zen2 Threadripper */
fafac0eb 470 case 0x47: /* Cyan Skillfish */
128066c8
ML
471 case 0x60: /* Renoir */
472 case 0x68: /* Lucienne */
c7579389 473 case 0x71: /* Zen2 */
0e3f52bb 474 data->ccd_offset = 0x154;
a8bc4165 475 k10temp_get_ccd_support(data, 8);
c7579389 476 break;
d906fa73
ML
477 case 0xa0 ... 0xaf:
478 data->ccd_offset = 0x300;
a8bc4165 479 k10temp_get_ccd_support(data, 8);
d906fa73 480 break;
c7579389 481 }
55163a1c 482 } else if (boot_cpu_data.x86 == 0x19) {
55163a1c 483 switch (boot_cpu_data.x86_model) {
c8d0d3fa 484 case 0x0 ... 0x1: /* Zen3 SP3/TR */
06f34bcc 485 case 0x8: /* Zen3 TR Chagall */
c8d0d3fa 486 case 0x21: /* Zen3 Ryzen Desktop */
128066c8 487 case 0x50 ... 0x5f: /* Green Sardine */
0e3f52bb 488 data->ccd_offset = 0x154;
a8bc4165 489 k10temp_get_ccd_support(data, 8);
55163a1c 490 break;
25572c81
ML
491 case 0x40 ... 0x4f: /* Yellow Carp */
492 data->ccd_offset = 0x300;
a8bc4165 493 k10temp_get_ccd_support(data, 8);
25572c81 494 break;
d906fa73
ML
495 case 0x60 ... 0x6f:
496 case 0x70 ... 0x7f:
497 data->ccd_offset = 0x308;
a8bc4165 498 k10temp_get_ccd_support(data, 8);
d906fa73 499 break;
8bb050cd
BM
500 case 0x10 ... 0x1f:
501 case 0xa0 ... 0xaf:
502 data->ccd_offset = 0x300;
a8bc4165 503 k10temp_get_ccd_support(data, 12);
8bb050cd 504 break;
55163a1c 505 }
2c183963
DH
506 } else if (boot_cpu_data.x86 == 0x1a) {
507 switch (boot_cpu_data.x86_model) {
508 case 0x40 ... 0x4f: /* Zen5 Ryzen Desktop */
509 data->ccd_offset = 0x308;
510 k10temp_get_ccd_support(data, 8);
511 break;
512 }
1b597889 513 }
68546abf 514
1b50b776
GR
515 for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
516 const struct tctl_offset *entry = &tctl_offset_table[i];
517
518 if (boot_cpu_data.x86 == entry->model &&
519 strstr(boot_cpu_data.x86_model_id, entry->id)) {
02a2484c 520 data->show_temp |= BIT(TDIE_BIT); /* show Tdie */
1b50b776
GR
521 data->temp_offset = entry->offset;
522 break;
523 }
524 }
525
d547552a
GR
526 hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
527 &k10temp_chip_info,
528 NULL);
8999eabf 529 return PTR_ERR_OR_ZERO(hwmon_dev);
3c57e89b
CL
530}
531
cd9bb056 532static const struct pci_device_id k10temp_id_table[] = {
3c57e89b
CL
533 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
534 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
aa4790a6 535 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
9e581311 536 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
24214449 537 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
d303b1b5 538 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
f89ce270 539 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
ccaf63b4 540 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M70H_NB_F3) },
30b146d1 541 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
ec015950 542 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
9af0a9ae 543 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3b031622 544 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
210ba120 545 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
fafac0eb 546 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M40H_DF_F3) },
279f0b3a 547 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
12163cfb 548 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
d906fa73 549 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
55163a1c 550 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
3cf90efa 551 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
25572c81 552 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
02c9dce4 553 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
d906fa73
ML
554 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
555 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
7d8accfa 556 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
3cd9da41
AN
557 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
558 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
59c34008 559 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
d93217d8 560 { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3c57e89b
CL
561 {}
562};
563MODULE_DEVICE_TABLE(pci, k10temp_id_table);
564
565static struct pci_driver k10temp_driver = {
566 .name = "k10temp",
567 .id_table = k10temp_id_table,
568 .probe = k10temp_probe,
3c57e89b
CL
569};
570
f71f5a55 571module_pci_driver(k10temp_driver);