diff options
| author | Jean Delvare <khali@linux-fr.org> | 2011-07-25 21:46:10 +0200 | 
|---|---|---|
| committer | Jean Delvare <khali@endymion.delvare> | 2011-07-25 21:46:10 +0200 | 
| commit | 764e043bb48b6b94f9dec228aedbd8ab08f4708b (patch) | |
| tree | ab67f59ceaf59cecb5f8f460c2bcf1ff6097c145 | |
| parent | 0a88f4b55749239c4ec8b33da74ff924ccb87dad (diff) | |
| download | olio-linux-3.10-764e043bb48b6b94f9dec228aedbd8ab08f4708b.tar.xz olio-linux-3.10-764e043bb48b6b94f9dec228aedbd8ab08f4708b.zip  | |
hwmon: (via-cputemp) Add VID reporting support
At least VIA family 6 model D CPU report the VID settings in a MSR,
so expose the value to user-space. Not sure about model A.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
Tested-by: Jeff Rickman <jrickman@myamigos.us>
| -rw-r--r-- | drivers/hwmon/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/hwmon/via-cputemp.c | 44 | 
2 files changed, 40 insertions, 5 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 70b5704baf3..0598cd22edf 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1162,6 +1162,7 @@ config SENSORS_TWL4030_MADC  config SENSORS_VIA_CPUTEMP  	tristate "VIA CPU temperature sensor"  	depends on X86 +	select HWMON_VID  	help  	  If you say yes here you get support for the temperature  	  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 0d18de424c6..8eac67d769f 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -27,6 +27,7 @@  #include <linux/init.h>  #include <linux/slab.h>  #include <linux/hwmon.h> +#include <linux/hwmon-vid.h>  #include <linux/sysfs.h>  #include <linux/hwmon-sysfs.h>  #include <linux/err.h> @@ -48,8 +49,10 @@ enum { SHOW_TEMP, SHOW_LABEL, SHOW_NAME };  struct via_cputemp_data {  	struct device *hwmon_dev;  	const char *name; +	u8 vrm;  	u32 id; -	u32 msr; +	u32 msr_temp; +	u32 msr_vid;  };  /* @@ -77,13 +80,27 @@ static ssize_t show_temp(struct device *dev,  	u32 eax, edx;  	int err; -	err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); +	err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);  	if (err)  		return -EAGAIN;  	return sprintf(buf, "%lu\n", ((unsigned long)eax & 0xffffff) * 1000);  } +static ssize_t show_cpu_vid(struct device *dev, +			    struct device_attribute *devattr, char *buf) +{ +	struct via_cputemp_data *data = dev_get_drvdata(dev); +	u32 eax, edx; +	int err; + +	err = rdmsr_safe_on_cpu(data->id, data->msr_vid, &eax, &edx); +	if (err) +		return -EAGAIN; + +	return sprintf(buf, "%d\n", vid_from_reg(~edx & 0x7f, data->vrm)); +} +  static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,  			  SHOW_TEMP);  static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL); @@ -100,6 +117,9 @@ static const struct attribute_group via_cputemp_group = {  	.attrs = via_cputemp_attributes,  }; +/* Optional attributes */ +static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_cpu_vid, NULL); +  static int __devinit via_cputemp_probe(struct platform_device *pdev)  {  	struct via_cputemp_data *data; @@ -122,11 +142,12 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)  		/* C7 A */  	case 0xD:  		/* C7 D */ -		data->msr = 0x1169; +		data->msr_temp = 0x1169; +		data->msr_vid = 0x198;  		break;  	case 0xF:  		/* Nano */ -		data->msr = 0x1423; +		data->msr_temp = 0x1423;  		break;  	default:  		err = -ENODEV; @@ -134,7 +155,7 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)  	}  	/* test if we can access the TEMPERATURE MSR */ -	err = rdmsr_safe_on_cpu(data->id, data->msr, &eax, &edx); +	err = rdmsr_safe_on_cpu(data->id, data->msr_temp, &eax, &edx);  	if (err) {  		dev_err(&pdev->dev,  			"Unable to access TEMPERATURE MSR, giving up\n"); @@ -147,6 +168,15 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)  	if (err)  		goto exit_free; +	if (data->msr_vid) +		data->vrm = vid_which_vrm(); + +	if (data->vrm) { +		err = device_create_file(&pdev->dev, &dev_attr_cpu0_vid); +		if (err) +			goto exit_remove; +	} +  	data->hwmon_dev = hwmon_device_register(&pdev->dev);  	if (IS_ERR(data->hwmon_dev)) {  		err = PTR_ERR(data->hwmon_dev); @@ -158,6 +188,8 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)  	return 0;  exit_remove: +	if (data->vrm) +		device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);  	sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);  exit_free:  	platform_set_drvdata(pdev, NULL); @@ -171,6 +203,8 @@ static int __devexit via_cputemp_remove(struct platform_device *pdev)  	struct via_cputemp_data *data = platform_get_drvdata(pdev);  	hwmon_device_unregister(data->hwmon_dev); +	if (data->vrm) +		device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);  	sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);  	platform_set_drvdata(pdev, NULL);  	kfree(data);  |