k10temp fixes

Fix race condition when accessing System Management Network registers
 Fix reading critical temperatures on F15h M60h and M70h
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJa+0BbAAoJEMsfJm/On5mBo3EQAJxtFC7pA7JzY0yZsXvaA+50
 ObN9EtG5mhVMZQfcOThcN6ZGzV12rpJltsCp6Poy0g8n7rgLiB5y2IJvinM7ETil
 6zbw5onfv2So/WyvXWBylEI0J4WjtGc8n17S1+nlT+Ppy4ID6PQPv1pGfr7YVI0o
 0T2sLSfDQD7vgtvpHi7A+4q2hbsI0HjS3LKI8CAy4UboZ8yltxJBsgV7gJ3fbv4Z
 tX9DOH05bGsCR/9vwoA3rRVbUKbvPnwTY36DCAyT53QuYRIBwREXi/xkxCkKdSsn
 X3o78TPkvE/qTyK1ZjuJ5yxDdLmesibiKOtyPBeaPaTQ+jcayfSr+rQrAvsZ2Ogp
 8pjZ5he3LR4/8wdmBhZBBcDXDdBMar8SRMSpPrBRyWONpn5fSLuszUkintKTND4c
 dH1zlXmYjRFsQBW2O+/b6k1Hq/p654mwD4hBbxHN7FVBnrWDWzUgd2xSpQLxSqkz
 sfyd6wsvrVeUCGHAsgVY9sXYlbrTjI1WWkOX4EAJC2YKvWDYTB/kQXg0I5vICN4m
 9tLyoC8tvKothIe8J1U5VUeGgpP5QES+yf7YNF9gc02D8l5xlsWuUAVrBI1XBOdS
 0MXFFFxM68Y6ufhIiahSXPM7vocSFi6CuuYbuz6Z09a2L9cahG4C5+Qe9E9h6PjM
 N4uOoFJGKckctQYJB0rO
 =SujR
 -----END PGP SIGNATURE-----

Merge tag 'hwmon-for-linus-v4.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:
 "Two k10temp fixes:

   - fix race condition when accessing System Management Network
     registers

   - fix reading critical temperatures on F15h M60h and M70h

  Also add PCI ID's for the AMD Raven Ridge root bridge"

* tag 'hwmon-for-linus-v4.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (k10temp) Use API function to access System Management Network
  x86/amd_nb: Add support for Raven Ridge CPUs
  hwmon: (k10temp) Fix reading critical temperature register
This commit is contained in:
Linus Torvalds 2018-05-17 15:58:12 -07:00
commit 3acf4e3952
3 changed files with 43 additions and 16 deletions

View File

@ -14,8 +14,11 @@
#include <asm/amd_nb.h> #include <asm/amd_nb.h>
#define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450 #define PCI_DEVICE_ID_AMD_17H_ROOT 0x1450
#define PCI_DEVICE_ID_AMD_17H_M10H_ROOT 0x15d0
#define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463
#define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464 #define PCI_DEVICE_ID_AMD_17H_DF_F4 0x1464
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
#define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
/* Protect the PCI config register pairs used for SMN and DF indirect access. */ /* Protect the PCI config register pairs used for SMN and DF indirect access. */
static DEFINE_MUTEX(smn_mutex); static DEFINE_MUTEX(smn_mutex);
@ -24,6 +27,7 @@ static u32 *flush_words;
static const struct pci_device_id amd_root_ids[] = { static const struct pci_device_id amd_root_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_ROOT) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_ROOT) },
{} {}
}; };
@ -39,6 +43,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
{} {}
}; };
@ -51,6 +56,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
{} {}
}; };

View File

@ -272,7 +272,7 @@ config SENSORS_K8TEMP
config SENSORS_K10TEMP config SENSORS_K10TEMP
tristate "AMD Family 10h+ temperature sensor" tristate "AMD Family 10h+ temperature sensor"
depends on X86 && PCI depends on X86 && PCI && AMD_NB
help help
If you say yes here you get support for the temperature If you say yes here you get support for the temperature
sensor(s) inside your CPU. Supported are later revisions of sensor(s) inside your CPU. Supported are later revisions of

View File

@ -23,6 +23,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/amd_nb.h>
#include <asm/processor.h> #include <asm/processor.h>
MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor"); MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
@ -40,8 +41,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
#define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463
#endif #endif
#ifndef PCI_DEVICE_ID_AMD_17H_RR_NB #ifndef PCI_DEVICE_ID_AMD_17H_M10H_DF_F3
#define PCI_DEVICE_ID_AMD_17H_RR_NB 0x15d0 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
#endif #endif
/* CPUID function 0x80000001, ebx */ /* CPUID function 0x80000001, ebx */
@ -63,10 +64,12 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
#define NB_CAP_HTC 0x00000400 #define NB_CAP_HTC 0x00000400
/* /*
* For F15h M60h, functionality of REG_REPORTED_TEMPERATURE * For F15h M60h and M70h, REG_HARDWARE_THERMAL_CONTROL
* has been moved to D0F0xBC_xD820_0CA4 [Reported Temperature * and REG_REPORTED_TEMPERATURE have been moved to
* Control] * D0F0xBC_xD820_0C64 [Hardware Temperature Control]
* D0F0xBC_xD820_0CA4 [Reported Temperature Control]
*/ */
#define F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET 0xd8200c64
#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4 #define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET 0xd8200ca4
/* F17h M01h Access througn SMN */ /* F17h M01h Access througn SMN */
@ -74,6 +77,7 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
struct k10temp_data { struct k10temp_data {
struct pci_dev *pdev; struct pci_dev *pdev;
void (*read_htcreg)(struct pci_dev *pdev, u32 *regval);
void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); void (*read_tempreg)(struct pci_dev *pdev, u32 *regval);
int temp_offset; int temp_offset;
u32 temp_adjust_mask; u32 temp_adjust_mask;
@ -98,6 +102,11 @@ static const struct tctl_offset tctl_offset_table[] = {
{ 0x17, "AMD Ryzen Threadripper 1910", 10000 }, { 0x17, "AMD Ryzen Threadripper 1910", 10000 },
}; };
static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval)
{
pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval);
}
static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval) static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval)
{ {
pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval);
@ -114,6 +123,12 @@ static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
mutex_unlock(&nb_smu_ind_mutex); mutex_unlock(&nb_smu_ind_mutex);
} }
static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval)
{
amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
F15H_M60H_HARDWARE_TEMP_CTRL_OFFSET, regval);
}
static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
{ {
amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8,
@ -122,8 +137,8 @@ static void read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval)
static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval) static void read_tempreg_nb_f17(struct pci_dev *pdev, u32 *regval)
{ {
amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0x60, amd_smn_read(amd_pci_dev_to_node_id(pdev),
F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval); F17H_M01H_REPORTED_TEMP_CTRL_OFFSET, regval);
} }
static ssize_t temp1_input_show(struct device *dev, static ssize_t temp1_input_show(struct device *dev,
@ -160,8 +175,7 @@ static ssize_t show_temp_crit(struct device *dev,
u32 regval; u32 regval;
int value; int value;
pci_read_config_dword(data->pdev, data->read_htcreg(data->pdev, &regval);
REG_HARDWARE_THERMAL_CONTROL, &regval);
value = ((regval >> 16) & 0x7f) * 500 + 52000; value = ((regval >> 16) & 0x7f) * 500 + 52000;
if (show_hyst) if (show_hyst)
value -= ((regval >> 24) & 0xf) * 500; value -= ((regval >> 24) & 0xf) * 500;
@ -181,13 +195,18 @@ static umode_t k10temp_is_visible(struct kobject *kobj,
struct pci_dev *pdev = data->pdev; struct pci_dev *pdev = data->pdev;
if (index >= 2) { if (index >= 2) {
u32 reg_caps, reg_htc; u32 reg;
if (!data->read_htcreg)
return 0;
pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES, pci_read_config_dword(pdev, REG_NORTHBRIDGE_CAPABILITIES,
&reg_caps); &reg);
pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, if (!(reg & NB_CAP_HTC))
&reg_htc); return 0;
if (!(reg_caps & NB_CAP_HTC) || !(reg_htc & HTC_ENABLE))
data->read_htcreg(data->pdev, &reg);
if (!(reg & HTC_ENABLE))
return 0; return 0;
} }
return attr->mode; return attr->mode;
@ -268,11 +287,13 @@ static int k10temp_probe(struct pci_dev *pdev,
if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 || if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
boot_cpu_data.x86_model == 0x70)) { boot_cpu_data.x86_model == 0x70)) {
data->read_htcreg = read_htcreg_nb_f15;
data->read_tempreg = read_tempreg_nb_f15; data->read_tempreg = read_tempreg_nb_f15;
} else if (boot_cpu_data.x86 == 0x17) { } else if (boot_cpu_data.x86 == 0x17) {
data->temp_adjust_mask = 0x80000; data->temp_adjust_mask = 0x80000;
data->read_tempreg = read_tempreg_nb_f17; data->read_tempreg = read_tempreg_nb_f17;
} else { } else {
data->read_htcreg = read_htcreg_pci;
data->read_tempreg = read_tempreg_pci; data->read_tempreg = read_tempreg_pci;
} }
@ -302,7 +323,7 @@ static const struct pci_device_id k10temp_id_table[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_16H_M30H_NB_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_RR_NB) }, { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
{} {}
}; };
MODULE_DEVICE_TABLE(pci, k10temp_id_table); MODULE_DEVICE_TABLE(pci, k10temp_id_table);