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: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
fc483a9bf7
commit
68546abf7a
1 changed files with 44 additions and 16 deletions
|
@ -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);
|
||||
unsigned int temp;
|
||||
|
||||
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,
|
||||
®val);
|
||||
} else {
|
||||
pci_read_config_dword(pdev, REG_REPORTED_TEMPERATURE, ®val);
|
||||
}
|
||||
return sprintf(buf, "%u\n", (regval >> 21) * 125);
|
||||
data->read_tempreg(data->pdev, ®val);
|
||||
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, ®val);
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue