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