Merge tag 'wireless-2023-06-14' of git://git.kernel.org/pub/scm/linux/kernel/git...
[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
0e3f52bb
ML
68/* Common for Zen CPU families (Family 17h and 18h and 19h) */
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
68546abf
GR
80struct k10temp_data {
81 struct pci_dev *pdev;
40626a1b 82 void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
68546abf 83 void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
1b50b776 84 int temp_offset;
1b597889 85 u32 temp_adjust_mask;
60465245 86 u32 show_temp;
60465245 87 bool is_zen;
0e3f52bb 88 u32 ccd_offset;
1b50b776
GR
89};
90
60465245
GR
91#define TCTL_BIT 0
92#define TDIE_BIT 1
93#define TCCD_BIT(x) ((x) + 2)
94
95#define HAVE_TEMP(d, channel) ((d)->show_temp & BIT(channel))
96#define HAVE_TDIE(d) HAVE_TEMP(d, TDIE_BIT)
97
1b50b776
GR
98struct tctl_offset {
99 u8 model;
100 char const *id;
101 int offset;
102};
103
104static const struct tctl_offset tctl_offset_table[] = {
ab5ee246 105 { 0x17, "AMD Ryzen 5 1600X", 20000 },
1b50b776
GR
106 { 0x17, "AMD Ryzen 7 1700X", 20000 },
107 { 0x17, "AMD Ryzen 7 1800X", 20000 },
1b597889 108 { 0x17, "AMD Ryzen 7 2700X", 10000 },
cd6a2064
GR
109 { 0x17, "AMD Ryzen Threadripper 19", 27000 }, /* 19{00,20,50}X */
110 { 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */
68546abf
GR
111};
112
40626a1b
GR
113static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
114{
115 pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
116}
117
68546abf
GR
118static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
119{
120 pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
121}
122
123static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
124 unsigned int base, int offset, u32 *val)
f89ce270
AG
125{
126 mutex_lock(&nb_smu_ind_mutex);
127 pci_bus_write_config_dword(pdev->bus, devfn,
68546abf 128 base, offset);
f89ce270 129 pci_bus_read_config_dword(pdev->bus, devfn,
68546abf 130 base + 4, val);
f89ce270
AG
131 mutex_unlock(&nb_smu_ind_mutex);
132}
133
40626a1b
GR
134static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
135{
136 amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
137 F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
138}
139
68546abf
GR
140static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
141{
142 amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
143 F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval);
144}
145
17822417 146static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
9af0a9ae 147{
3b031622 148 amd_smn_read(amd_pci_dev_to_node_id(pdev),
0e3f52bb 149 ZEN_REPORTED_TEMP_CTRL_BASE, regval);
9af0a9ae
GR
150}
151
d547552a 152static long get_raw_temp(struct k10temp_data *data)
3c57e89b 153{
f934c059 154 u32 regval;
d547552a 155 long temp;
68546abf
GR
156
157 data->read_tempreg(data->pdev, &regval);
17822417 158 temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
0c072385
BM
159 if ((regval & data->temp_adjust_mask) ||
160 (regval & ZEN_CUR_TEMP_TJ_SEL_MASK) == ZEN_CUR_TEMP_TJ_SEL_MASK)
1b597889 161 temp -= 49000;
f934c059
GR
162 return temp;
163}
164
0e786f32 165static const char *k10temp_temp_label[] = {
d547552a 166 "Tctl",
b02c6857 167 "Tdie",
c7579389
GR
168 "Tccd1",
169 "Tccd2",
fd8bdb23
GR
170 "Tccd3",
171 "Tccd4",
172 "Tccd5",
173 "Tccd6",
174 "Tccd7",
175 "Tccd8",
8bb050cd
BM
176 "Tccd9",
177 "Tccd10",
178 "Tccd11",
179 "Tccd12",
d547552a 180};
f934c059 181
d547552a
GR
182static int k10temp_read_labels(struct device *dev,
183 enum hwmon_sensor_types type,
184 u32 attr, int channel, const char **str)
3c57e89b 185{
b00647c4
GR
186 switch (type) {
187 case hwmon_temp:
188 *str = k10temp_temp_label[channel];
189 break;
b00647c4
GR
190 default:
191 return -EOPNOTSUPP;
192 }
193 return 0;
194}
195
196static int k10temp_read_temp(struct device *dev, u32 attr, int channel,
197 long *val)
3c57e89b 198{
68546abf 199 struct k10temp_data *data = dev_get_drvdata(dev);
3c57e89b 200 u32 regval;
3c57e89b 201
d547552a
GR
202 switch (attr) {
203 case hwmon_temp_input:
204 switch (channel) {
b02c6857
GR
205 case 0: /* Tctl */
206 *val = get_raw_temp(data);
d547552a
GR
207 if (*val < 0)
208 *val = 0;
209 break;
b02c6857
GR
210 case 1: /* Tdie */
211 *val = get_raw_temp(data) - data->temp_offset;
d547552a
GR
212 if (*val < 0)
213 *val = 0;
214 break;
8bb050cd 215 case 2 ... 13: /* Tccd{1-12} */
c7579389 216 amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
0e3f52bb
ML
217 ZEN_CCD_TEMP(data->ccd_offset, channel - 2),
218 &regval);
17822417 219 *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
c7579389 220 break;
d547552a
GR
221 default:
222 return -EOPNOTSUPP;
223 }
224 break;
225 case hwmon_temp_max:
226 *val = 70 * 1000;
227 break;
228 case hwmon_temp_crit:
229 data->read_htcreg(data->pdev, &regval);
230 *val = ((regval >> 16) & 0x7f) * 500 + 52000;
231 break;
232 case hwmon_temp_crit_hyst:
233 data->read_htcreg(data->pdev, &regval);
234 *val = (((regval >> 16) & 0x7f)
235 - ((regval >> 24) & 0xf)) * 500 + 52000;
236 break;
237 default:
238 return -EOPNOTSUPP;
239 }
240 return 0;
3c57e89b
CL
241}
242
b00647c4
GR
243static int k10temp_read(struct device *dev, enum hwmon_sensor_types type,
244 u32 attr, int channel, long *val)
245{
246 switch (type) {
247 case hwmon_temp:
248 return k10temp_read_temp(dev, attr, channel, val);
b00647c4
GR
249 default:
250 return -EOPNOTSUPP;
251 }
252}
253
d547552a
GR
254static umode_t k10temp_is_visible(const void *_data,
255 enum hwmon_sensor_types type,
256 u32 attr, int channel)
3e3e1022 257{
d547552a 258 const struct k10temp_data *data = _data;
68546abf 259 struct pci_dev *pdev = data->pdev;
f934c059 260 u32 reg;
3e3e1022 261
d547552a
GR
262 switch (type) {
263 case hwmon_temp:
264 switch (attr) {
265 case hwmon_temp_input:
60465245 266 if (!HAVE_TEMP(data, channel))
d547552a
GR
267 return 0;
268 break;
269 case hwmon_temp_max:
60465245 270 if (channel || data->is_zen)
d547552a
GR
271 return 0;
272 break;
273 case hwmon_temp_crit:
274 case hwmon_temp_crit_hyst:
275 if (channel || !data->read_htcreg)
276 return 0;
277
278 pci_read_config_dword(pdev,
279 REG_NORTHBRIDGE_CAPABILITIES,
280 &reg);
281 if (!(reg & NB_CAP_HTC))
282 return 0;
283
284 data->read_htcreg(data->pdev, &reg);
285 if (!(reg & HTC_ENABLE))
286 return 0;
287 break;
288 case hwmon_temp_label:
60465245
GR
289 /* Show temperature labels only on Zen CPUs */
290 if (!data->is_zen || !HAVE_TEMP(data, channel))
c7579389 291 return 0;
d547552a
GR
292 break;
293 default:
f934c059 294 return 0;
d547552a 295 }
f934c059 296 break;
d547552a
GR
297 default:
298 return 0;
3e3e1022 299 }
d547552a 300 return 0444;
3e3e1022
GR
301}
302
6c931ae1 303static bool has_erratum_319(struct pci_dev *pdev)
3c57e89b 304{
c5114a1c
CL
305 u32 pkg_type, reg_dram_cfg;
306
307 if (boot_cpu_data.x86 != 0x10)
308 return false;
309
3c57e89b 310 /*
c5114a1c
CL
311 * Erratum 319: The thermal sensor of Socket F/AM2+ processors
312 * may be unreliable.
3c57e89b 313 */
c5114a1c
CL
314 pkg_type = cpuid_ebx(0x80000001) & CPUID_PKGTYPE_MASK;
315 if (pkg_type == CPUID_PKGTYPE_F)
316 return true;
317 if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3)
318 return false;
319
eefc2d9e 320 /* DDR3 memory implies socket AM3, which is good */
c5114a1c
CL
321 pci_bus_read_config_dword(pdev->bus,
322 PCI_DEVFN(PCI_SLOT(pdev->devfn), 2),
323 REG_DCT0_CONFIG_HIGH, &reg_dram_cfg);
eefc2d9e
JD
324 if (reg_dram_cfg & DDR3_MODE)
325 return false;
326
327 /*
328 * Unfortunately it is possible to run a socket AM3 CPU with DDR2
329 * memory. We blacklist all the cores which do exist in socket AM2+
330 * format. It still isn't perfect, as RB-C2 cores exist in both AM2+
331 * and AM3 formats, but that's the best we can do.
332 */
333 return boot_cpu_data.x86_model < 4 ||
b399151c 334 (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
3c57e89b
CL
335}
336
4dd50f3c 337static const struct hwmon_channel_info * const k10temp_info[] = {
d547552a
GR
338 HWMON_CHANNEL_INFO(temp,
339 HWMON_T_INPUT | HWMON_T_MAX |
340 HWMON_T_CRIT | HWMON_T_CRIT_HYST |
341 HWMON_T_LABEL,
c7579389
GR
342 HWMON_T_INPUT | HWMON_T_LABEL,
343 HWMON_T_INPUT | HWMON_T_LABEL,
fd8bdb23
GR
344 HWMON_T_INPUT | HWMON_T_LABEL,
345 HWMON_T_INPUT | HWMON_T_LABEL,
346 HWMON_T_INPUT | HWMON_T_LABEL,
347 HWMON_T_INPUT | HWMON_T_LABEL,
348 HWMON_T_INPUT | HWMON_T_LABEL,
349 HWMON_T_INPUT | HWMON_T_LABEL,
8bb050cd
BM
350 HWMON_T_INPUT | HWMON_T_LABEL,
351 HWMON_T_INPUT | HWMON_T_LABEL,
352 HWMON_T_INPUT | HWMON_T_LABEL,
353 HWMON_T_INPUT | HWMON_T_LABEL,
d547552a
GR
354 HWMON_T_INPUT | HWMON_T_LABEL),
355 NULL
356};
357
358static const struct hwmon_ops k10temp_hwmon_ops = {
359 .is_visible = k10temp_is_visible,
360 .read = k10temp_read,
361 .read_string = k10temp_read_labels,
362};
363
364static const struct hwmon_chip_info k10temp_chip_info = {
365 .ops = &k10temp_hwmon_ops,
366 .info = k10temp_info,
367};
368
fd8bdb23
GR
369static void k10temp_get_ccd_support(struct pci_dev *pdev,
370 struct k10temp_data *data, int limit)
371{
372 u32 regval;
373 int i;
374
375 for (i = 0; i < limit; i++) {
376 amd_smn_read(amd_pci_dev_to_node_id(pdev),
0e3f52bb 377 ZEN_CCD_TEMP(data->ccd_offset, i), &regval);
17822417 378 if (regval & ZEN_CCD_TEMP_VALID)
60465245 379 data->show_temp |= BIT(TCCD_BIT(i));
fd8bdb23
GR
380 }
381}
382
d547552a 383static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3c57e89b 384{
c5114a1c 385 int unreliable = has_erratum_319(pdev);
3e3e1022 386 struct device *dev = &pdev->dev;
68546abf 387 struct k10temp_data *data;
3e3e1022 388 struct device *hwmon_dev;
1b50b776 389 int i;
3c57e89b 390
3e3e1022
GR
391 if (unreliable) {
392 if (!force) {
393 dev_err(dev,
394 "unreliable CPU thermal sensor; monitoring disabled\n");
395 return -ENODEV;
396 }
397 dev_warn(dev,
3c57e89b 398 "unreliable CPU thermal sensor; check erratum 319\n");
3e3e1022 399 }
3c57e89b 400
68546abf
GR
401 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
402 if (!data)
403 return -ENOMEM;
404
405 data->pdev = pdev;
60465245 406 data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */
68546abf 407
53dfa008
GR
408 if (boot_cpu_data.x86 == 0x15 &&
409 ((boot_cpu_data.x86_model & 0xf0) == 0x60 ||
410 (boot_cpu_data.x86_model & 0xf0) == 0x70)) {
40626a1b 411 data->read_htcreg = read_htcreg_nb_f15;
68546abf 412 data->read_tempreg = read_tempreg_nb_f15;
d93217d8 413 } else if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
17822417
WH
414 data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
415 data->read_tempreg = read_tempreg_nb_zen;
60465245 416 data->is_zen = true;
c7579389
GR
417
418 switch (boot_cpu_data.x86_model) {
419 case 0x1: /* Zen */
420 case 0x8: /* Zen+ */
421 case 0x11: /* Zen APU */
422 case 0x18: /* Zen+ APU */
0e3f52bb 423 data->ccd_offset = 0x154;
fd8bdb23 424 k10temp_get_ccd_support(pdev, data, 4);
c7579389
GR
425 break;
426 case 0x31: /* Zen2 Threadripper */
128066c8
ML
427 case 0x60: /* Renoir */
428 case 0x68: /* Lucienne */
c7579389 429 case 0x71: /* Zen2 */
0e3f52bb 430 data->ccd_offset = 0x154;
fd8bdb23 431 k10temp_get_ccd_support(pdev, data, 8);
c7579389 432 break;
d906fa73
ML
433 case 0xa0 ... 0xaf:
434 data->ccd_offset = 0x300;
435 k10temp_get_ccd_support(pdev, data, 8);
436 break;
c7579389 437 }
55163a1c
WH
438 } else if (boot_cpu_data.x86 == 0x19) {
439 data->temp_adjust_mask = ZEN_CUR_TEMP_RANGE_SEL_MASK;
440 data->read_tempreg = read_tempreg_nb_zen;
55163a1c
WH
441 data->is_zen = true;
442
443 switch (boot_cpu_data.x86_model) {
c8d0d3fa
GC
444 case 0x0 ... 0x1: /* Zen3 SP3/TR */
445 case 0x21: /* Zen3 Ryzen Desktop */
128066c8 446 case 0x50 ... 0x5f: /* Green Sardine */
0e3f52bb 447 data->ccd_offset = 0x154;
55163a1c
WH
448 k10temp_get_ccd_support(pdev, data, 8);
449 break;
25572c81
ML
450 case 0x40 ... 0x4f: /* Yellow Carp */
451 data->ccd_offset = 0x300;
452 k10temp_get_ccd_support(pdev, data, 8);
453 break;
d906fa73
ML
454 case 0x60 ... 0x6f:
455 case 0x70 ... 0x7f:
456 data->ccd_offset = 0x308;
457 k10temp_get_ccd_support(pdev, data, 8);
458 break;
8bb050cd
BM
459 case 0x10 ... 0x1f:
460 case 0xa0 ... 0xaf:
461 data->ccd_offset = 0x300;
462 k10temp_get_ccd_support(pdev, data, 12);
463 break;
55163a1c 464 }
1b597889 465 } else {
40626a1b 466 data->read_htcreg = read_htcreg_pci;
68546abf 467 data->read_tempreg = read_tempreg_pci;
1b597889 468 }
68546abf 469
1b50b776
GR
470 for (i = 0; i < ARRAY_SIZE(tctl_offset_table); i++) {
471 const struct tctl_offset *entry = &tctl_offset_table[i];
472
473 if (boot_cpu_data.x86 == entry->model &&
474 strstr(boot_cpu_data.x86_model_id, entry->id)) {
02a2484c 475 data->show_temp |= BIT(TDIE_BIT); /* show Tdie */
1b50b776
GR
476 data->temp_offset = entry->offset;
477 break;
478 }
479 }
480
d547552a
GR
481 hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
482 &k10temp_chip_info,
483 NULL);
8999eabf 484 return PTR_ERR_OR_ZERO(hwmon_dev);
3c57e89b
CL
485}
486
cd9bb056 487static const struct pci_device_id k10temp_id_table[] = {
3c57e89b
CL
488 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
489 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
aa4790a6 490 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
9e581311 491 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
24214449 492 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
d303b1b5 493 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
f89ce270 494 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M60H_NB_F3) },
ccaf63b4 495 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_M70H_NB_F3) },
30b146d1 496 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
ec015950 497 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
9af0a9ae 498 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3b031622 499 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
210ba120 500 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
279f0b3a 501 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) },
12163cfb 502 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
d906fa73 503 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
55163a1c 504 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_DF_F3) },
3cf90efa 505 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M10H_DF_F3) },
25572c81 506 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M40H_DF_F3) },
02c9dce4 507 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M50H_DF_F3) },
d906fa73
ML
508 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M60H_DF_F3) },
509 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M70H_DF_F3) },
7d8accfa 510 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
d93217d8 511 { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
3c57e89b
CL
512 {}
513};
514MODULE_DEVICE_TABLE(pci, k10temp_id_table);
515
516static struct pci_driver k10temp_driver = {
517 .name = "k10temp",
518 .id_table = k10temp_id_table,
519 .probe = k10temp_probe,
3c57e89b
CL
520};
521
f71f5a55 522module_pci_driver(k10temp_driver);