aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/Kconfig1
-rw-r--r--drivers/hwmon/via-cputemp.c44
2 files changed, 40 insertions, 5 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 70b5704baf31..0598cd22edf2 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1162,6 +1162,7 @@ config SENSORS_TWL4030_MADC
1162config SENSORS_VIA_CPUTEMP 1162config SENSORS_VIA_CPUTEMP
1163 tristate "VIA CPU temperature sensor" 1163 tristate "VIA CPU temperature sensor"
1164 depends on X86 1164 depends on X86
1165 select HWMON_VID
1165 help 1166 help
1166 If you say yes here you get support for the temperature 1167 If you say yes here you get support for the temperature
1167 sensor inside your CPU. Supported are all known variants of 1168 sensor inside your CPU. Supported are all known variants of
diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c
index 0d18de424c66..8eac67d769fa 100644
--- a/drivers/hwmon/via-cputemp.c
+++ b/drivers/hwmon/via-cputemp.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/hwmon.h> 29#include <linux/hwmon.h>
30#include <linux/hwmon-vid.h>
30#include <linux/sysfs.h> 31#include <linux/sysfs.h>
31#include <linux/hwmon-sysfs.h> 32#include <linux/hwmon-sysfs.h>
32#include <linux/err.h> 33#include <linux/err.h>
@@ -48,8 +49,10 @@ enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };
48struct via_cputemp_data { 49struct via_cputemp_data {
49 struct device *hwmon_dev; 50 struct device *hwmon_dev;
50 const char *name; 51 const char *name;
52 u8 vrm;
51 u32 id; 53 u32 id;
52 u32 msr; 54 u32 msr_temp;
55 u32 msr_vid;
53}; 56};
54 57
55/* 58/*
@@ -77,13 +80,27 @@ static ssize_t show_temp(struct device *dev,
77 u32 eax, edx; 80 u32 eax, edx;
78 int err; 81 int err;
79 82
80 err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); 83 err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
81 if (err) 84 if (err)
82 return -EAGAIN; 85 return -EAGAIN;
83 86
84 return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000); 87 return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);
85} 88}
86 89
90static ssize_t show_cpu_vid(struct device *dev,
91 struct device_attribute *devattr, char *buf)
92{
93 struct via_cputemp_data *data = dev_get_drvdata(dev);
94 u32 eax, edx;
95 int err;
96
97 err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx);
98 if (err)
99 return -EAGAIN;
100
101 return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm));
102}
103
87static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 104static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
88 SHOW_TEMP); 105 SHOW_TEMP);
89static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); 106static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
@@ -100,6 +117,9 @@ static const struct attribute_group via_cputemp_group = {
100 .attrs = via_cputemp_attributes, 117 .attrs = via_cputemp_attributes,
101}; 118};
102 119
120/* Optional attributes */
121static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_cpu_vid, NULL);
122
103static int __devinit via_cputemp_probe(struct platform_device *pdev) 123static int __devinit via_cputemp_probe(struct platform_device *pdev)
104{ 124{
105 struct via_cputemp_data *data; 125 struct via_cputemp_data *data;
@@ -122,11 +142,12 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
122 /* C7 A */ 142 /* C7 A */
123 case 0xD: 143 case 0xD:
124 /* C7 D */ 144 /* C7 D */
125 data->msr = 0x1169; 145 data->msr_temp = 0x1169;
146 data->msr_vid = 0x198;
126 break; 147 break;
127 case 0xF: 148 case 0xF:
128 /* Nano */ 149 /* Nano */
129 data->msr = 0x1423; 150 data->msr_temp = 0x1423;
130 break; 151 break;
131 default: 152 default:
132 err = -ENODEV; 153 err = -ENODEV;
@@ -134,7 +155,7 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
134 } 155 }
135 156
136 /* test if we can access the TEMPERATURE MSR */ 157 /* test if we can access the TEMPERATURE MSR */
137 err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); 158 err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);
138 if (err) { 159 if (err) {
139 dev_err(&pdev->dev, 160 dev_err(&pdev->dev,
140 "Unable to access TEMPERATURE MSR, giving up\n"); 161 "Unable to access TEMPERATURE MSR, giving up\n");
@@ -147,6 +168,15 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
147 if (err) 168 if (err)
148 goto exit_free; 169 goto exit_free;
149 170
171 if (data->msr_vid)
172 data->vrm = vid_which_vrm();
173
174 if (data->vrm) {
175 err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid);
176 if (err)
177 goto exit_remove;
178 }
179
150 data->hwmon_dev = hwmon_device_register(&pdev->dev); 180 data->hwmon_dev = hwmon_device_register(&pdev->dev);
151 if (IS_ERR(data->hwmon_dev)) { 181 if (IS_ERR(data->hwmon_dev)) {
152 err = PTR_ERR(data->hwmon_dev); 182 err = PTR_ERR(data->hwmon_dev);
@@ -158,6 +188,8 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
158 return 0; 188 return 0;
159 189
160exit_remove: 190exit_remove:
191 if (data->vrm)
192 device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
161 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); 193 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
162exit_free: 194exit_free:
163 platform_set_drvdata(pdev, NULL); 195 platform_set_drvdata(pdev, NULL);
@@ -171,6 +203,8 @@ static int __devexit via_cputemp_remove(struct platform_device *pdev)
171 struct via_cputemp_data *data = platform_get_drvdata(pdev); 203 struct via_cputemp_data *data = platform_get_drvdata(pdev);
172 204
173 hwmon_device_unregister(data->hwmon_dev); 205 hwmon_device_unregister(data->hwmon_dev);
206 if (data->vrm)
207 device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
174 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group); 208 sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
175 platform_set_drvdata(pdev, NULL); 209 platform_set_drvdata(pdev, NULL);
176 kfree(data); 210 kfree(data);