|
26 | 26 | */
|
27 | 27 |
|
28 | 28 | #include <linux/bitops.h>
|
| 29 | +#include <linux/debugfs.h> |
29 | 30 | #include <linux/err.h>
|
30 | 31 | #include <linux/hwmon.h>
|
31 | 32 | #include <linux/init.h>
|
@@ -442,6 +443,76 @@ static bool has_erratum_319(struct pci_dev *pdev)
|
442 | 443 | (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_stepping <= 2);
|
443 | 444 | }
|
444 | 445 |
|
| 446 | +#ifdef CONFIG_DEBUG_FS |
| 447 | + |
| 448 | +static void k10temp_smn_regs_show(struct seq_file *s, struct pci_dev *pdev, |
| 449 | + u32 addr, int count) |
| 450 | +{ |
| 451 | + u32 reg; |
| 452 | + int i; |
| 453 | + |
| 454 | + for (i = 0; i < count; i++) { |
| 455 | + if (!(i & 3)) |
| 456 | + seq_printf(s, "0x%06x: ", addr + i * 4); |
| 457 | + amd_smn_read(amd_pci_dev_to_node_id(pdev), addr + i * 4, ®); |
| 458 | + seq_printf(s, "%08x ", reg); |
| 459 | + if ((i & 3) == 3) |
| 460 | + seq_puts(s, "\n"); |
| 461 | + } |
| 462 | +} |
| 463 | + |
| 464 | +static int svi_show(struct seq_file *s, void *unused) |
| 465 | +{ |
| 466 | + struct k10temp_data *data = s->private; |
| 467 | + |
| 468 | + k10temp_smn_regs_show(s, data->pdev, F17H_M01H_SVI, 32); |
| 469 | + return 0; |
| 470 | +} |
| 471 | +DEFINE_SHOW_ATTRIBUTE(svi); |
| 472 | + |
| 473 | +static int thm_show(struct seq_file *s, void *unused) |
| 474 | +{ |
| 475 | + struct k10temp_data *data = s->private; |
| 476 | + |
| 477 | + k10temp_smn_regs_show(s, data->pdev, |
| 478 | + F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, 256); |
| 479 | + return 0; |
| 480 | +} |
| 481 | +DEFINE_SHOW_ATTRIBUTE(thm); |
| 482 | + |
| 483 | +static void k10temp_debugfs_cleanup(void *ddir) |
| 484 | +{ |
| 485 | + debugfs_remove_recursive(ddir); |
| 486 | +} |
| 487 | + |
| 488 | +static void k10temp_init_debugfs(struct k10temp_data *data) |
| 489 | +{ |
| 490 | + struct dentry *debugfs; |
| 491 | + char name[32]; |
| 492 | + |
| 493 | + /* Only show debugfs data for Family 17h/18h CPUs */ |
| 494 | + if (!data->show_tdie) |
| 495 | + return; |
| 496 | + |
| 497 | + scnprintf(name, sizeof(name), "k10temp-%s", pci_name(data->pdev)); |
| 498 | + |
| 499 | + debugfs = debugfs_create_dir(name, NULL); |
| 500 | + if (debugfs) { |
| 501 | + debugfs_create_file("svi", 0444, debugfs, data, &svi_fops); |
| 502 | + debugfs_create_file("thm", 0444, debugfs, data, &thm_fops); |
| 503 | + devm_add_action_or_reset(&data->pdev->dev, |
| 504 | + k10temp_debugfs_cleanup, debugfs); |
| 505 | + } |
| 506 | +} |
| 507 | + |
| 508 | +#else |
| 509 | + |
| 510 | +static void k10temp_init_debugfs(struct k10temp_data *data) |
| 511 | +{ |
| 512 | +} |
| 513 | + |
| 514 | +#endif |
| 515 | + |
445 | 516 | static const struct hwmon_channel_info *k10temp_info[] = {
|
446 | 517 | HWMON_CHANNEL_INFO(temp,
|
447 | 518 | HWMON_T_INPUT | HWMON_T_MAX |
|
@@ -553,7 +624,12 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
553 | 624 | hwmon_dev = devm_hwmon_device_register_with_info(dev, "k10temp", data,
|
554 | 625 | &k10temp_chip_info,
|
555 | 626 | NULL);
|
556 |
| - return PTR_ERR_OR_ZERO(hwmon_dev); |
| 627 | + if (IS_ERR(hwmon_dev)) |
| 628 | + return PTR_ERR(hwmon_dev); |
| 629 | + |
| 630 | + k10temp_init_debugfs(data); |
| 631 | + |
| 632 | + return 0; |
557 | 633 | }
|
558 | 634 |
|
559 | 635 | static const struct pci_device_id k10temp_id_table[] = {
|
|
0 commit comments