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