mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 13:00:54 +07:00
hwmon fixes for 3.4-rc4
Two patches: Fix build warning in ads1015 driver, and fix bogus power values with current BIOSes in fam15h_power driver. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAABAgAGBQJPkWoDAAoJEMsfJm/On5mB+HcQAJNR2hzXhLemwlueR8WXSv5o QEOmULAqi2rE/VwXvBFLxv/XuIMzmg4+cdWSJUwdkho2d1+72N98Q1Wto48MPD44 UNYyI1H1/rQuKfmAeA5zWFjIMwoDMfRm8RmaioRNZnQl2YUQ9Z7HUWfcsEfEWNLU X+UBqgdER5d+tn+8T3l69R9XVUTCD5ZhMAdNS2k7FYzWWkf2CNjGN4yvWmj9oXpM skS+4tKhcGgBvMuyib7GmhB6M8Lv2Mr3f9vv7VKDvIfEIpEcD5hbFX/EeXQKIKzW Wf/yXoHwSdkIro0m5OAdvv/8lmoOkLErvhJT9nwmCMfTvYx4CTlGsAM7o7gSIegA 2hOPKtOiyDpHZMaC2s5Z4VRE8Ylp9jyUNo4tequvTbp/uz6Qg67CkEPZtL/iB8aj dgp2UmjARrQApPlnpO3WOxJgASsEme22P3xw7iGj+07vnMsiU8ThBe6Pge+QLMR5 ZdKpuPgsMRnz+JLGuBDRp0YhvqtTXFmEkrJMxdmTnfsK72Anmo7VM00eFDY2/QjB C1E0AAZ5EYTfk6qMkYTwonEe6BMbOO7xS8C6ZYka0P+YTJJ7EPqAxTzgbBJBoK1a NQMOzofPElqGZMT+D3hevBjBcBApvcvbtLPqg+sdvVAiyCiyLHd2ahxAYuPayLpR HTUQY1jy830ty4edZnJJ =QMAO -----END PGP SIGNATURE----- Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging Pyll hwmon fixes from Guenter Roeck: "Two patches: Fix build warning in ads1015 driver, and fix bogus power values with current BIOSes in fam15h_power driver." * tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: hwmon: (ads1015) Fix build warning hwmon: fam15h_power: fix bogus values with current BIOSes
This commit is contained in:
commit
310eb77650
@ -59,14 +59,11 @@ struct ads1015_data {
|
|||||||
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
|
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
|
static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
|
||||||
int *value)
|
|
||||||
{
|
{
|
||||||
u16 config;
|
u16 config;
|
||||||
s16 conversion;
|
|
||||||
struct ads1015_data *data = i2c_get_clientdata(client);
|
struct ads1015_data *data = i2c_get_clientdata(client);
|
||||||
unsigned int pga = data->channel_data[channel].pga;
|
unsigned int pga = data->channel_data[channel].pga;
|
||||||
int fullscale;
|
|
||||||
unsigned int data_rate = data->channel_data[channel].data_rate;
|
unsigned int data_rate = data->channel_data[channel].data_rate;
|
||||||
unsigned int conversion_time_ms;
|
unsigned int conversion_time_ms;
|
||||||
int res;
|
int res;
|
||||||
@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
config = res;
|
config = res;
|
||||||
fullscale = fullscale_table[pga];
|
|
||||||
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
|
conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]);
|
||||||
|
|
||||||
/* setup and start single conversion */
|
/* setup and start single conversion */
|
||||||
@ -105,33 +101,36 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
|
res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
|
||||||
if (res < 0)
|
|
||||||
goto err_unlock;
|
|
||||||
conversion = res;
|
|
||||||
|
|
||||||
mutex_unlock(&data->update_lock);
|
|
||||||
|
|
||||||
*value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_unlock:
|
err_unlock:
|
||||||
mutex_unlock(&data->update_lock);
|
mutex_unlock(&data->update_lock);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
|
||||||
|
s16 reg)
|
||||||
|
{
|
||||||
|
struct ads1015_data *data = i2c_get_clientdata(client);
|
||||||
|
unsigned int pga = data->channel_data[channel].pga;
|
||||||
|
int fullscale = fullscale_table[pga];
|
||||||
|
|
||||||
|
return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0);
|
||||||
|
}
|
||||||
|
|
||||||
/* sysfs callback function */
|
/* sysfs callback function */
|
||||||
static ssize_t show_in(struct device *dev, struct device_attribute *da,
|
static ssize_t show_in(struct device *dev, struct device_attribute *da,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
int in;
|
|
||||||
int res;
|
int res;
|
||||||
|
int index = attr->index;
|
||||||
|
|
||||||
res = ads1015_read_value(client, attr->index, &in);
|
res = ads1015_read_adc(client, index);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
return (res < 0) ? res : sprintf(buf, "%d\n", in);
|
return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct sensor_device_attribute ads1015_in[] = {
|
static const struct sensor_device_attribute ads1015_in[] = {
|
||||||
|
@ -122,6 +122,38 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Newer BKDG versions have an updated recommendation on how to properly
|
||||||
|
* initialize the running average range (was: 0xE, now: 0x9). This avoids
|
||||||
|
* counter saturations resulting in bogus power readings.
|
||||||
|
* We correct this value ourselves to cope with older BIOSes.
|
||||||
|
*/
|
||||||
|
static void __devinit tweak_runavg_range(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
const struct pci_device_id affected_device = {
|
||||||
|
PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* let this quirk apply only to the current version of the
|
||||||
|
* northbridge, since future versions may change the behavior
|
||||||
|
*/
|
||||||
|
if (!pci_match_id(&affected_device, pdev))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pci_bus_read_config_dword(pdev->bus,
|
||||||
|
PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
|
||||||
|
REG_TDP_RUNNING_AVERAGE, &val);
|
||||||
|
if ((val & 0xf) != 0xe)
|
||||||
|
return;
|
||||||
|
|
||||||
|
val &= ~0xf;
|
||||||
|
val |= 0x9;
|
||||||
|
pci_bus_write_config_dword(pdev->bus,
|
||||||
|
PCI_DEVFN(PCI_SLOT(pdev->devfn), 5),
|
||||||
|
REG_TDP_RUNNING_AVERAGE, val);
|
||||||
|
}
|
||||||
|
|
||||||
static void __devinit fam15h_power_init_data(struct pci_dev *f4,
|
static void __devinit fam15h_power_init_data(struct pci_dev *f4,
|
||||||
struct fam15h_power_data *data)
|
struct fam15h_power_data *data)
|
||||||
{
|
{
|
||||||
@ -155,6 +187,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
|
|||||||
struct device *dev;
|
struct device *dev;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* though we ignore every other northbridge, we still have to
|
||||||
|
* do the tweaking on _each_ node in MCM processors as the counters
|
||||||
|
* are working hand-in-hand
|
||||||
|
*/
|
||||||
|
tweak_runavg_range(pdev);
|
||||||
|
|
||||||
if (!fam15h_power_is_internal_node0(pdev)) {
|
if (!fam15h_power_is_internal_node0(pdev)) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
Loading…
Reference in New Issue
Block a user