Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68546abf authored by Guenter Roeck's avatar Guenter Roeck
Browse files

hwmon: (k10temp) Move chip specific code into probe function



Introduce a local data structure and determine the temperature read
function at probe time to reduce runtime complexity.

Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent fc483a9b
Loading
Loading
Loading
Loading
+45 −17
Original line number Diff line number Diff line
@@ -61,31 +61,44 @@ static DEFINE_MUTEX(nb_smu_ind_mutex);
 */
#define F15H_M60H_REPORTED_TEMP_CTRL_OFFSET	0xd8200ca4

static void amd_nb_smu_index_read(struct pci_dev *pdev, unsigned int devfn,
				  int offset, u32 *val)
struct k10temp_data {
	struct pci_dev *pdev;
	void (*read_tempreg)(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);
}

static void amd_nb_index_read(struct pci_dev *pdev, unsigned int devfn,
			      unsigned int base, int offset, u32 *val)
{
	mutex_lock(&nb_smu_ind_mutex);
	pci_bus_write_config_dword(pdev->bus, devfn,
				   0xb8, offset);
				   base, offset);
	pci_bus_read_config_dword(pdev->bus, devfn,
				  0xbc, val);
				  base + 4, val);
	mutex_unlock(&nb_smu_ind_mutex);
}

static void 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);
}

static ssize_t temp1_input_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct k10temp_data *data = dev_get_drvdata(dev);
	u32 regval;
	struct pci_dev *pdev = dev_get_drvdata(dev);

	if (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model == 0x60) {
		amd_nb_smu_index_read(pdev, PCI_DEVFN(0, 0),
				      F15H_M60H_REPORTED_TEMP_CTRL_OFFSET,
				      &regval);
	} else {
		pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, &regval);
	}
	return sprintf(buf, "%u\n", (regval >> 21) * 125);
	unsigned int temp;

	data->read_tempreg(data->pdev, &regval);
	temp = (regval >> 21) * 125;

	return sprintf(buf, "%u\n", temp);
}

static ssize_t temp1_max_show(struct device *dev,
@@ -98,11 +111,12 @@ static ssize_t show_temp_crit(struct device *dev,
			      struct device_attribute *devattr, char *buf)
{
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
	struct k10temp_data *data = dev_get_drvdata(dev);
	int show_hyst = attr->index;
	u32 regval;
	int value;

	pci_read_config_dword(dev_get_drvdata(dev),
	pci_read_config_dword(data->pdev,
			      REG_HARDWARE_THERMAL_CONTROL, &regval);
	value = ((regval >> 16) & 0x7f) * 500 + 52000;
	if (show_hyst)
@@ -119,7 +133,8 @@ static umode_t k10temp_is_visible(struct kobject *kobj,
				  struct attribute *attr, int index)
{
	struct device *dev = container_of(kobj, struct device, kobj);
	struct pci_dev *pdev = dev_get_drvdata(dev);
	struct k10temp_data *data = dev_get_drvdata(dev);
	struct pci_dev *pdev = data->pdev;

	if (index >= 2) {
		u32 reg_caps, reg_htc;
@@ -187,6 +202,7 @@ static int k10temp_probe(struct pci_dev *pdev,
{
	int unreliable = has_erratum_319(pdev);
	struct device *dev = &pdev->dev;
	struct k10temp_data *data;
	struct device *hwmon_dev;

	if (unreliable) {
@@ -199,7 +215,19 @@ static int k10temp_probe(struct pci_dev *pdev,
			 "unreliable CPU thermal sensor; check erratum 319\n");
	}

	hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", pdev,
	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->pdev = pdev;

	if (boot_cpu_data.x86 == 0x15 && (boot_cpu_data.x86_model == 0x60 ||
					  boot_cpu_data.x86_model == 0x70))
		data->read_tempreg = read_tempreg_nb_f15;
	else
		data->read_tempreg = read_tempreg_pci;

	hwmon_dev = devm_hwmon_device_register_with_groups(dev, "k10temp", data,
							   k10temp_groups);
	return PTR_ERR_OR_ZERO(hwmon_dev);
}