[PATCH v2 3/3] hwmon: (k10temp): Show errors failing to read

From: Mario Limonciello
Date: Fri Aug 27 2021 - 16:15:43 EST


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, &regval);
- temp = (regval >> ZEN_CUR_TEMP_SHIFT) * 125;
+ ret = data->read_tempreg(data->pdev, &regval);
+ 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),
&regval);
+ 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, &regval);
+ ret = data->read_htcreg(data->pdev, &regval);
+ if (ret)
+ return ret;
*val = ((regval >> 16) & 0x7f) * 500 + 52000;
break;
case hwmon_temp_crit_hyst:
- data->read_htcreg(data->pdev, &regval);
+ ret = data->read_htcreg(data->pdev, &regval);
+ if (ret)
+ return ret;
*val = (((regval >> 16) & 0x7f)
- ((regval >> 24) & 0xf)) * 500 + 52000;
break;
--
2.25.1