diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/acpi_power_meter.c | 1 | ||||
-rw-r--r-- | drivers/hwmon/ad7314.c | 12 | ||||
-rw-r--r-- | drivers/hwmon/ads1015.c | 33 | ||||
-rw-r--r-- | drivers/hwmon/coretemp.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/fam15h_power.c | 42 | ||||
-rw-r--r-- | drivers/hwmon/pmbus/pmbus_core.c | 17 | ||||
-rw-r--r-- | drivers/hwmon/smsc47b397.c | 14 | ||||
-rw-r--r-- | drivers/hwmon/smsc47m1.c | 19 |
8 files changed, 95 insertions, 49 deletions
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 145f13580ff0..9140236a0182 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -391,6 +391,7 @@ static ssize_t show_str(struct device *dev, break; default: BUG(); + val = ""; } return sprintf(buf, "%s\n", val); diff --git a/drivers/hwmon/ad7314.c b/drivers/hwmon/ad7314.c index ce43642ef03e..f85ce70d9677 100644 --- a/drivers/hwmon/ad7314.c +++ b/drivers/hwmon/ad7314.c @@ -47,7 +47,7 @@ struct ad7314_data { u16 rx ____cacheline_aligned; }; -static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) +static int ad7314_spi_read(struct ad7314_data *chip) { int ret; @@ -57,9 +57,7 @@ static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) return ret; } - *data = be16_to_cpu(chip->rx); - - return ret; + return be16_to_cpu(chip->rx); } static ssize_t ad7314_show_temperature(struct device *dev, @@ -70,12 +68,12 @@ static ssize_t ad7314_show_temperature(struct device *dev, s16 data; int ret; - ret = ad7314_spi_read(chip, &data); + ret = ad7314_spi_read(chip); if (ret < 0) return ret; switch (spi_get_device_id(chip->spi_dev)->driver_data) { case ad7314: - data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; + data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; data = (data << 6) >> 6; return sprintf(buf, "%d\n", 250 * data); @@ -86,7 +84,7 @@ static ssize_t ad7314_show_temperature(struct device *dev, * with a sign bit - which is a 14 bit 2's complement * register. 1lsb - 31.25 milli degrees centigrade */ - data &= ADT7301_TEMP_MASK; + data = ret & ADT7301_TEMP_MASK; data = (data << 2) >> 2; return sprintf(buf, "%d\n", diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c index 7765e4f74ec5..1958f03efd7a 100644 --- a/drivers/hwmon/ads1015.c +++ b/drivers/hwmon/ads1015.c @@ -59,14 +59,11 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_value(struct i2c_client *client, unsigned int channel, - int *value) +static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) { u16 config; - s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; - int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -78,7 +75,6 @@ static int ads1015_read_value(struct i2c_client *client, unsigned int channel, if (res < 0) goto err_unlock; config = res; - fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* 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); - if (res < 0) - goto err_unlock; - conversion = res; - - mutex_unlock(&data->update_lock); - - *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); - - return 0; err_unlock: mutex_unlock(&data->update_lock); 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 */ static ssize_t show_in(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); - int in; 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[] = { diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 0d3141fbbc20..b9d512331ed4 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444); MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ +#define NUM_REAL_CORES 32 /* Number of Real cores per cpu */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) @@ -709,6 +709,10 @@ static void __cpuinit put_core_offline(unsigned int cpu) indx = TO_ATTR_NO(cpu); + /* The core id is too big, just return */ + if (indx > MAX_CORE_DATA - 1) + return; + if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) coretemp_remove_core(pdata, &pdev->dev, indx); diff --git a/drivers/hwmon/fam15h_power.c b/drivers/hwmon/fam15h_power.c index b7494af1e4a9..e8e18cab1fb8 100644 --- a/drivers/hwmon/fam15h_power.c +++ b/drivers/hwmon/fam15h_power.c @@ -122,6 +122,41 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) 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 DEFINE_PCI_DEVICE_TABLE(affected_device) = { + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, + { 0 } +}; + +static void __devinit tweak_runavg_range(struct pci_dev *pdev) +{ + u32 val; + + /* + * 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, struct fam15h_power_data *data) { @@ -155,6 +190,13 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; 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)) { err = -ENODEV; goto exit; diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index be51037363c8..29b319db573e 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -710,13 +710,13 @@ static u16 pmbus_data2reg(struct pmbus_data *data, * If a negative value is stored in any of the referenced registers, this value * reflects an error code which will be returned. */ -static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) +static int pmbus_get_boolean(struct pmbus_data *data, int index) { u8 s1 = (index >> 24) & 0xff; u8 s2 = (index >> 16) & 0xff; u8 reg = (index >> 8) & 0xff; u8 mask = index & 0xff; - int status; + int ret, status; u8 regval; status = data->status[reg]; @@ -725,7 +725,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) regval = status & mask; if (!s1 && !s2) - *val = !!regval; + ret = !!regval; else { long v1, v2; struct pmbus_sensor *sensor1, *sensor2; @@ -739,9 +739,9 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) v1 = pmbus_reg2data(data, sensor1); v2 = pmbus_reg2data(data, sensor2); - *val = !!(regval && v1 >= v2); + ret = !!(regval && v1 >= v2); } - return 0; + return ret; } static ssize_t pmbus_show_boolean(struct device *dev, @@ -750,11 +750,10 @@ static ssize_t pmbus_show_boolean(struct device *dev, struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct pmbus_data *data = pmbus_update_device(dev); int val; - int err; - err = pmbus_get_boolean(data, attr->index, &val); - if (err) - return err; + val = pmbus_get_boolean(data, attr->index); + if (val < 0) + return val; return snprintf(buf, PAGE_SIZE, "%d\n", val); } diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index d3b778da3f86..c5f6be478bad 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c @@ -343,10 +343,11 @@ exit: return err; } -static int __init smsc47b397_find(unsigned short *addr) +static int __init smsc47b397_find(void) { u8 id, rev; char *name; + unsigned short addr; superio_enter(); id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -370,14 +371,14 @@ static int __init smsc47b397_find(unsigned short *addr) rev = superio_inb(SUPERIO_REG_DEVREV); superio_select(SUPERIO_REG_LD8); - *addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) + addr = (superio_inb(SUPERIO_REG_BASE_MSB) << 8) | superio_inb(SUPERIO_REG_BASE_LSB); pr_info("found SMSC %s (base address 0x%04x, revision %u)\n", - name, *addr, rev); + name, addr, rev); superio_exit(); - return 0; + return addr; } static int __init smsc47b397_init(void) @@ -385,9 +386,10 @@ static int __init smsc47b397_init(void) unsigned short address; int ret; - ret = smsc47b397_find(&address); - if (ret) + ret = smsc47b397_find(); + if (ret < 0) return ret; + address = ret; ret = platform_driver_register(&smsc47b397_driver); if (ret) diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index c590c1469793..b5aa38dd7ab9 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -491,10 +491,10 @@ static const struct attribute_group smsc47m1_group = { .attrs = smsc47m1_attributes, }; -static int __init smsc47m1_find(unsigned short *addr, - struct smsc47m1_sio_data *sio_data) +static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data) { u8 val; + unsigned short addr; superio_enter(); val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); @@ -546,9 +546,9 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_select(); - *addr = (superio_inb(SUPERIO_REG_BASE) << 8) + addr = (superio_inb(SUPERIO_REG_BASE) << 8) | superio_inb(SUPERIO_REG_BASE + 1); - if (*addr == 0) { + if (addr == 0) { pr_info("Device address not set, will not use\n"); superio_exit(); return -ENODEV; @@ -565,7 +565,7 @@ static int __init smsc47m1_find(unsigned short *addr, } superio_exit(); - return 0; + return addr; } /* Restore device to its initial state */ @@ -938,13 +938,15 @@ static int __init sm_smsc47m1_init(void) unsigned short address; struct smsc47m1_sio_data sio_data; - if (smsc47m1_find(&address, &sio_data)) - return -ENODEV; + err = smsc47m1_find(&sio_data); + if (err < 0) + return err; + address = err; /* Sets global pdev as a side effect */ err = smsc47m1_device_add(address, &sio_data); if (err) - goto exit; + return err; err = platform_driver_probe(&smsc47m1_driver, smsc47m1_probe); if (err) @@ -955,7 +957,6 @@ static int __init sm_smsc47m1_init(void) exit_device: platform_device_unregister(pdev); smsc47m1_restore(&sio_data); -exit: return err; } |