[PATCH] hwmon: k8temp.c Add support for AMD 11h

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I think Jean will have some comments too. Here is quick review.


> 
> Added AMD 11h support in k8temp. Thanks to Rudolf Marek for help.
> 
> Signed-off-by: Jaswinder Singh Rajput <jaswinderrajput at gmail.com>
> ---
>  drivers/hwmon/Kconfig  |    4 +-
>  drivers/hwmon/k8temp.c |   75 ++++++++++++++++++++++++++++++-----------------
>  2 files changed, 50 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
> index 2d50166..e7b4941 100644
> --- a/drivers/hwmon/Kconfig
> +++ b/drivers/hwmon/Kconfig
> @@ -200,11 +200,11 @@ config SENSORS_ADT7475
>  	  will be called adt7475.
>  
>  config SENSORS_K8TEMP
> -	tristate "AMD Athlon64/FX or Opteron temperature sensor"
> +	tristate "AMD Athlon64/FX or Opteron or 11h temperature sensor"


maybe something else? like fam11h All it sounds too technical. Maybe we can
leave it and fix the help. Also the documentation/hwmon/k8temp should be updated.

>  	depends on X86 && PCI && EXPERIMENTAL
>  	help
>  	  If you say yes here you get support for the temperature
> -	  sensor(s) inside your CPU. Supported is whole AMD K8
> +	  sensor(s) inside your CPU. Supported is whole AMD K8 and 11h
>  	  microarchitecture. Please note that you will need at least
>  	  lm-sensors 2.10.1 for proper userspace support.

Maybe we can add note why fam10h is not supported, and also to a readme. Best it
would be with another patch.

>  
> diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
> index 1fe9951..f91da26 100644
> --- a/drivers/hwmon/k8temp.c
> +++ b/drivers/hwmon/k8temp.c
> @@ -1,5 +1,6 @@
>  /*
>   * k8temp.c - Linux kernel module for hardware monitoring
> + *	      for AMD K8 and 11h
>   *
>   * Copyright (C) 2006 Rudolf Marek <r.marek at assembler.cz>
>   *
> @@ -33,7 +34,7 @@
>  #include <linux/mutex.h>
>  #include <asm/processor.h>
>  
> -#define TEMP_FROM_REG(val)	(((((val) >> 16) & 0xff) - 49) * 1000)
> +#define REG_TCTL	0xa4
>  #define REG_TEMP	0xe4
>  #define SEL_PLACE	0x40
>  #define SEL_CORE	0x04
> @@ -52,42 +53,61 @@ struct k8temp_data {
>  	u32 temp_offset;
>  };
>  
> -static struct k8temp_data *k8temp_update_device(struct device *dev)

> +static inline unsigned long temp_from_reg(unsigned long val)

maybe the unsigned long val should be u32 so it is fixed - regs is also fixed size.

> +{
> +	if (boot_cpu_data.x86 > 0xf)
> +		return (val >> 21) * 125;
> +	else
> +		return (((val >> 16) & 0xff) - 49) * 1000;
> +}
> +
> +static void update_11h_temp(struct pci_dev *pdev, struct k8temp_data *data)
> +{
> +	pci_read_config_dword(pdev, REG_TCTL, &data->temp[0][0]);
> +}
> +
> +static void update_k8_temp(struct pci_dev *pdev, struct k8temp_data *data)
>  {
> -	struct k8temp_data *data = dev_get_drvdata(dev);
> -	struct pci_dev *pdev = to_pci_dev(dev);
>  	u8 tmp;
>  
> -	mutex_lock(&data->update_lock);
> +	pci_read_config_byte(pdev, REG_TEMP, &tmp);
> +	tmp &= ~(SEL_PLACE | SEL_CORE);		/* Select sensor 0, core0 */
> +	pci_write_config_byte(pdev, REG_TEMP, tmp);
> +	pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]);
>  
> -	if (!data->valid
> -	    || time_after(jiffies, data->last_updated + HZ)) {
> -		pci_read_config_byte(pdev, REG_TEMP, &tmp);
> -		tmp &= ~(SEL_PLACE | SEL_CORE);		/* Select sensor 0, core0 */
> +	if (data->sensorsp & SEL_PLACE) {
> +		tmp |= SEL_PLACE;		/* Select sensor 1, core0 */
>  		pci_write_config_byte(pdev, REG_TEMP, tmp);
> -		pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]);
> +		pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][1]);
> +	}
> +
> +	if (data->sensorsp & SEL_CORE) {
> +		tmp &= ~SEL_PLACE;		/* Select sensor 0, core1 */
> +		tmp |= SEL_CORE;
> +		pci_write_config_byte(pdev, REG_TEMP, tmp);
> +		pci_read_config_dword(pdev, REG_TEMP, &data->temp[1][0]);
>  
>  		if (data->sensorsp & SEL_PLACE) {
> -			tmp |= SEL_PLACE;	/* Select sensor 1, core0 */
> +			tmp |= SEL_PLACE;	/* Select sensor 1, core1 */
>  			pci_write_config_byte(pdev, REG_TEMP, tmp);
>  			pci_read_config_dword(pdev, REG_TEMP,
> -					      &data->temp[0][1]);
> +					      &data->temp[1][1]);
>  		}
> +	}
> +}
>  
> -		if (data->sensorsp & SEL_CORE) {
> -			tmp &= ~SEL_PLACE;	/* Select sensor 0, core1 */
> -			tmp |= SEL_CORE;
> -			pci_write_config_byte(pdev, REG_TEMP, tmp);
> -			pci_read_config_dword(pdev, REG_TEMP,
> -					      &data->temp[1][0]);
> -
> -			if (data->sensorsp & SEL_PLACE) {
> -				tmp |= SEL_PLACE;	/* Select sensor 1, core1 */
> -				pci_write_config_byte(pdev, REG_TEMP, tmp);
> -				pci_read_config_dword(pdev, REG_TEMP,
> -						      &data->temp[1][1]);
> -			}
> -		}
> +static struct k8temp_data *k8temp_update_device(struct device *dev)
> +{
> +	struct pci_dev *pdev = to_pci_dev(dev);
> +	struct k8temp_data *data = dev_get_drvdata(dev);
> +
> +	mutex_lock(&data->update_lock);
> +
> +	if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
> +		if (boot_cpu_data.x86 > 0xf)
> +			update_11h_temp(pdev, data);
> +		else
> +			update_k8_temp(pdev, data);
>  
>  		data->last_updated = jiffies;
>  		data->valid = 1;


Rest looks ok. Anyone else can test?

Rudolf
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkpVDpgACgkQ3J9wPJqZRNUo9ACgnsmlkNYiCXnqmW18stl2T8Vb
GAgAoJHlrO9BtGSEprPrAUMyZd/F/9Z3
=xlSR
-----END PGP SIGNATURE-----



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux