Enabling Yellow Carp was initially not working "properly" because extra IDs were needed, but this wasn't obvious because fail values from `amd_smn_read` were ignored. Don't discard errors from any functions providing them, instead pass up to the caller. Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx> --- drivers/hwmon/k10temp.c | 87 ++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 38bc35ac8135..2edb49d39d22 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -98,8 +98,8 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); struct k10temp_data { struct pci_dev *pdev; - void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); - void (*read_tempreg)(struct pci_dev *pdev, u32 *regval); + int (*read_htcreg)(struct pci_dev *pdev, u32 *regval); + int (*read_tempreg)(struct pci_dev *pdev, u32 *regval); int temp_offset; u32 temp_adjust_mask; u32 show_temp; @@ -129,55 +129,65 @@ static const struct tctl_offset tctl_offset_table[] = { { 0x17, "AMD Ryzen Threadripper 29", 27000 }, /* 29{20,50,70,90}[W]X */ }; -static void read_htcreg_pci(struct pci_dev *pdev, u32 *regval) +static int read_htcreg_pci(struct pci_dev *pdev, u32 *regval) { - pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval); + return pci_read_config_dword(pdev, REG_HARDWARE_THERMAL_CONTROL, regval); } -static void read_tempreg_pci(struct pci_dev *pdev, u32 *regval) +static int read_tempreg_pci(struct pci_dev *pdev, u32 *regval) { - pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); + return pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, regval); } -static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn, +static int amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn, unsigned int base, int offset, u32 *val) { + int ret; + mutex_lock(&nb_smu_ind_mutex); - pci_bus_write_config_dword(pdev->bus, devfn, - base, offset); - pci_bus_read_config_dword(pdev->bus, devfn, - base + 4, val); + ret = pci_bus_write_config_dword(pdev->bus, devfn, + base, offset); + if (ret) + goto out; + ret = pci_bus_read_config_dword(pdev->bus, devfn, + base + 4, val); +out: mutex_unlock(&nb_smu_ind_mutex); + return ret; } -static void read_htcreg_nb_f15(struct pci_dev *pdev, u32 *regval) +static int 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); + return 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 int read_tempreg_nb_f15(struct pci_dev *pdev, u32 *regval) { - amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, - F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval); + return amd_nb_index_read(pdev, PCI_DEVFN(0, 0), 0xb8, + F15H_M60H_REPORTED_TEMP_CTRL_OFFSET, regval); } -static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval) +static int read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval) { - amd_smn_read(amd_pci_dev_to_node_id(pdev), - ZEN_REPORTED_TEMP_CTRL_BASE, regval); + return amd_smn_read(amd_pci_dev_to_node_id(pdev), + ZEN_REPORTED_TEMP_CTRL_BASE, regval); } -static long get_raw_temp(struct k10temp_data *data) +static int get_raw_temp(struct k10temp_data *data, long *val) { u32 regval; - long temp; + int ret; - data->read_tempreg(data->pdev, ®val); - temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125; + ret = data->read_tempreg(data->pdev, ®val); + if (ret) + return ret; + *val = (regval >> ZEN_CUR_TEMP_SHIFT) * 125; if (regval & data->temp_adjust_mask) - temp -= 49000; - return temp; + *val -= 49000; + if (*val < 0) + return -EINVAL; + return 0; } static const char *k10temp_temp_label[] = { @@ -212,24 +222,27 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, { struct k10temp_data *data = dev_get_drvdata(dev); u32 regval; + int ret; switch (attr) { case hwmon_temp_input: switch (channel) { case 0: /* Tctl */ - *val = get_raw_temp(data); - if (*val < 0) - *val = 0; + ret = get_raw_temp(data, val); + if (ret) + return ret; break; case 1: /* Tdie */ - *val = get_raw_temp(data) - data->temp_offset; - if (*val < 0) - *val = 0; + ret = get_raw_temp(data, val) - data->temp_offset; + if (ret) + return ret; break; case 2 ... 9: /* Tccd{1-8} */ - amd_smn_read(amd_pci_dev_to_node_id(data->pdev), + ret = amd_smn_read(amd_pci_dev_to_node_id(data->pdev), ZEN_CCD_TEMP(data->ccd_offset, channel - 2), ®val); + if (ret) + return ret; *val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000; break; default: @@ -240,11 +253,15 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, *val = 70 * 1000; break; case hwmon_temp_crit: - data->read_htcreg(data->pdev, ®val); + ret = data->read_htcreg(data->pdev, ®val); + if (ret) + return ret; *val = ((regval >> 16) & 0x7f) * 500 + 52000; break; case hwmon_temp_crit_hyst: - data->read_htcreg(data->pdev, ®val); + ret = data->read_htcreg(data->pdev, ®val); + if (ret) + return ret; *val = (((regval >> 16) & 0x7f) - ((regval >> 24) & 0xf)) * 500 + 52000; break; -- 2.25.1