diff options
Diffstat (limited to 'drivers/hwmon')
34 files changed, 4110 insertions, 793 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 5f888f7e7dc..0b62c3c6b7c 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -623,7 +623,7 @@ config SENSORS_LM90 LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, - and Winbond/Nuvoton W83L771W/G/AWG/ASG sensor chips. + Winbond/Nuvoton W83L771W/G/AWG/ASG and Philips SA56004 sensor chips. This driver can also be built as a module. If so, the module will be called lm90. @@ -694,14 +694,24 @@ config SENSORS_LTC4261 be called ltc4261. config SENSORS_LM95241 - tristate "National Semiconductor LM95241 sensor chip" + tristate "National Semiconductor LM95241 and compatibles" depends on I2C help - If you say yes here you get support for LM95241 sensor chip. + If you say yes here you get support for LM95231 and LM95241 sensor + chips. This driver can also be built as a module. If so, the module will be called lm95241. +config SENSORS_LM95245 + tristate "National Semiconductor LM95245 sensor chip" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for LM95245 sensor chip. + + This driver can also be built as a module. If so, the module + will be called lm95245. + config SENSORS_MAX1111 tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip" depends on SPI_MASTER @@ -736,6 +746,16 @@ config SENSORS_MAX1619 This driver can also be built as a module. If so, the module will be called max1619. +config SENSORS_MAX1668 + tristate "Maxim MAX1668 and compatibles" + depends on I2C && EXPERIMENTAL + help + If you say yes here you get support for MAX1668, MAX1989 and + MAX1805 chips. + + This driver can also be built as a module. If so, the module + will be called max1668. + config SENSORS_MAX6639 tristate "Maxim MAX6639 sensor chip" depends on I2C && EXPERIMENTAL @@ -767,6 +787,20 @@ config SENSORS_MAX6650 This driver can also be built as a module. If so, the module will be called max6650. +config SENSORS_NTC_THERMISTOR + tristate "NTC thermistor support" + depends on EXPERIMENTAL + help + This driver supports NTC thermistors sensor reading and its + interpretation. The driver can also monitor the temperature and + send notifications about the temperature. + + Currently, this driver supports + NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333. + + This driver can also be built as a module. If so, the module + will be called ntc-thermistor. + config SENSORS_PC87360 tristate "National Semiconductor PC87360 family" select HWMON_VID @@ -807,92 +841,7 @@ config SENSORS_PCF8591 These devices are hard to detect and rarely found on mainstream hardware. If unsure, say N. -config PMBUS - tristate "PMBus support" - depends on I2C && EXPERIMENTAL - default n - help - Say yes here if you want to enable PMBus support. - - This driver can also be built as a module. If so, the module will - be called pmbus_core. - -if PMBUS - -config SENSORS_PMBUS - tristate "Generic PMBus devices" - default n - help - If you say yes here you get hardware monitoring support for generic - PMBus devices, including but not limited to BMR450, BMR451, BMR453, - BMR454, and LTC2978. - - This driver can also be built as a module. If so, the module will - be called pmbus. - -config SENSORS_ADM1275 - tristate "Analog Devices ADM1275" - default n - help - If you say yes here you get hardware monitoring support for Analog - Devices ADM1275 Hot-Swap Controller and Digital Power Monitor. - - This driver can also be built as a module. If so, the module will - be called adm1275. - -config SENSORS_MAX16064 - tristate "Maxim MAX16064" - default n - help - If you say yes here you get hardware monitoring support for Maxim - MAX16064. - - This driver can also be built as a module. If so, the module will - be called max16064. - -config SENSORS_MAX34440 - tristate "Maxim MAX34440/MAX34441" - default n - help - If you say yes here you get hardware monitoring support for Maxim - MAX34440 and MAX34441. - - This driver can also be built as a module. If so, the module will - be called max34440. - -config SENSORS_MAX8688 - tristate "Maxim MAX8688" - default n - help - If you say yes here you get hardware monitoring support for Maxim - MAX8688. - - This driver can also be built as a module. If so, the module will - be called max8688. - -config SENSORS_UCD9000 - tristate "TI UCD90120, UCD90124, UCD9090, UCD90910" - default n - help - If you say yes here you get hardware monitoring support for TI - UCD90120, UCD90124, UCD9090, UCD90910 Sequencer and System Health - Controllers. - - This driver can also be built as a module. If so, the module will - be called ucd9000. - -config SENSORS_UCD9200 - tristate "TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, UCD9248" - default n - help - If you say yes here you get hardware monitoring support for TI - UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248 - Digital PWM System Controllers. - - This driver can also be built as a module. If so, the module will - be called ucd9200. - -endif # PMBUS +source drivers/hwmon/pmbus/Kconfig config SENSORS_SHT15 tristate "Sensiron humidity and temperature sensors. SHT15 and compat." @@ -1041,8 +990,13 @@ config SENSORS_SMSC47B397 This driver can also be built as a module. If so, the module will be called smsc47b397. +config SENSORS_SCH56XX_COMMON + tristate + default n + config SENSORS_SCH5627 tristate "SMSC SCH5627" + select SENSORS_SCH56XX_COMMON help If you say yes here you get support for the hardware monitoring features of the SMSC SCH5627 Super-I/O chip. @@ -1050,6 +1004,21 @@ config SENSORS_SCH5627 This driver can also be built as a module. If so, the module will be called sch5627. +config SENSORS_SCH5636 + tristate "SMSC SCH5636" + select SENSORS_SCH56XX_COMMON + help + SMSC SCH5636 Super I/O chips include an embedded microcontroller for + hardware monitoring solutions, allowing motherboard manufacturers to + create their own custom hwmon solution based upon the SCH5636. + + Currently this driver only supports the Fujitsu Theseus SCH5636 based + hwmon solution. Say yes here if you want support for the Fujitsu + Theseus' hardware monitoring features. + + This driver can also be built as a module. If so, the module + will be called sch5636. + config SENSORS_ADS1015 tristate "Texas Instruments ADS1015" depends on I2C @@ -1142,6 +1111,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/Makefile b/drivers/hwmon/Makefile index 28061cfa0cd..3c9ccefea79 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_LM92) += lm92.o obj-$(CONFIG_SENSORS_LM93) += lm93.o obj-$(CONFIG_SENSORS_LM95241) += lm95241.o +obj-$(CONFIG_SENSORS_LM95245) += lm95245.o obj-$(CONFIG_SENSORS_LTC4151) += ltc4151.o obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o @@ -87,15 +88,19 @@ obj-$(CONFIG_SENSORS_LTC4261) += ltc4261.o obj-$(CONFIG_SENSORS_MAX1111) += max1111.o obj-$(CONFIG_SENSORS_MAX16065) += max16065.o obj-$(CONFIG_SENSORS_MAX1619) += max1619.o +obj-$(CONFIG_SENSORS_MAX1668) += max1668.o obj-$(CONFIG_SENSORS_MAX6639) += max6639.o obj-$(CONFIG_SENSORS_MAX6642) += max6642.o obj-$(CONFIG_SENSORS_MAX6650) += max6650.o obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o +obj-$(CONFIG_SENSORS_NTC_THERMISTOR) += ntc_thermistor.o obj-$(CONFIG_SENSORS_PC87360) += pc87360.o obj-$(CONFIG_SENSORS_PC87427) += pc87427.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o +obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o +obj-$(CONFIG_SENSORS_SCH5636) += sch5636.o obj-$(CONFIG_SENSORS_SHT15) += sht15.o obj-$(CONFIG_SENSORS_SHT21) += sht21.o obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o @@ -119,15 +124,7 @@ obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o obj-$(CONFIG_SENSORS_WM831X) += wm831x-hwmon.o obj-$(CONFIG_SENSORS_WM8350) += wm8350-hwmon.o -# PMBus drivers -obj-$(CONFIG_PMBUS) += pmbus_core.o -obj-$(CONFIG_SENSORS_PMBUS) += pmbus.o -obj-$(CONFIG_SENSORS_ADM1275) += adm1275.o -obj-$(CONFIG_SENSORS_MAX16064) += max16064.o -obj-$(CONFIG_SENSORS_MAX34440) += max34440.o -obj-$(CONFIG_SENSORS_MAX8688) += max8688.o -obj-$(CONFIG_SENSORS_UCD9000) += ucd9000.o -obj-$(CONFIG_SENSORS_UCD9200) += ucd9200.o +obj-$(CONFIG_PMBUS) += pmbus/ ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 0070d5476dd..41125767613 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -44,7 +44,9 @@ #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ #define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ -#define MAX_ATTRS 5 /* Maximum no of per-core attrs */ +#define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ +#define MAX_THRESH_ATTRS 3 /* Maximum no of Threshold attrs */ +#define TOTAL_ATTRS (MAX_CORE_ATTRS + MAX_THRESH_ATTRS) #define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO) #ifdef CONFIG_SMP @@ -67,6 +69,9 @@ * This value is passed as "id" field to rdmsr/wrmsr functions. * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS, * from where the temperature values should be read. + * @intrpt_reg: One of IA32_THERM_INTERRUPT or IA32_PACKAGE_THERM_INTERRUPT, + * from where the thresholds are read. + * @attr_size: Total number of pre-core attrs displayed in the sysfs. * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data. * Otherwise, temp_data holds coretemp data. * @valid: If this is 1, the current temperature is valid. @@ -74,15 +79,18 @@ struct temp_data { int temp; int ttarget; + int tmin; int tjmax; unsigned long last_updated; unsigned int cpu; u32 cpu_core_id; u32 status_reg; + u32 intrpt_reg; + int attr_size; bool is_pkg_data; bool valid; - struct sensor_device_attribute sd_attrs[MAX_ATTRS]; - char attr_name[MAX_ATTRS][CORETEMP_NAME_LENGTH]; + struct sensor_device_attribute sd_attrs[TOTAL_ATTRS]; + char attr_name[TOTAL_ATTRS][CORETEMP_NAME_LENGTH]; struct mutex update_lock; }; @@ -135,6 +143,19 @@ static ssize_t show_crit_alarm(struct device *dev, return sprintf(buf, "%d\n", (eax >> 5) & 1); } +static ssize_t show_max_alarm(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + u32 eax, edx; + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct platform_data *pdata = dev_get_drvdata(dev); + struct temp_data *tdata = pdata->core_data[attr->index]; + + rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx); + + return sprintf(buf, "%d\n", !!(eax & THERM_STATUS_THRESHOLD1)); +} + static ssize_t show_tjmax(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -153,6 +174,83 @@ static ssize_t show_ttarget(struct device *dev, return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget); } +static ssize_t store_ttarget(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct platform_data *pdata = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct temp_data *tdata = pdata->core_data[attr->index]; + u32 eax, edx; + unsigned long val; + int diff; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + + /* + * THERM_MASK_THRESHOLD1 is 7 bits wide. Values are entered in terms + * of milli degree celsius. Hence don't accept val > (127 * 1000) + */ + if (val > tdata->tjmax || val > 127000) + return -EINVAL; + + diff = (tdata->tjmax - val) / 1000; + + mutex_lock(&tdata->update_lock); + rdmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, &eax, &edx); + eax = (eax & ~THERM_MASK_THRESHOLD1) | + (diff << THERM_SHIFT_THRESHOLD1); + wrmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, eax, edx); + tdata->ttarget = val; + mutex_unlock(&tdata->update_lock); + + return count; +} + +static ssize_t show_tmin(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct platform_data *pdata = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tmin); +} + +static ssize_t store_tmin(struct device *dev, + struct device_attribute *devattr, + const char *buf, size_t count) +{ + struct platform_data *pdata = dev_get_drvdata(dev); + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct temp_data *tdata = pdata->core_data[attr->index]; + u32 eax, edx; + unsigned long val; + int diff; + + if (strict_strtoul(buf, 10, &val)) + return -EINVAL; + + /* + * THERM_MASK_THRESHOLD0 is 7 bits wide. Values are entered in terms + * of milli degree celsius. Hence don't accept val > (127 * 1000) + */ + if (val > tdata->tjmax || val > 127000) + return -EINVAL; + + diff = (tdata->tjmax - val) / 1000; + + mutex_lock(&tdata->update_lock); + rdmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, &eax, &edx); + eax = (eax & ~THERM_MASK_THRESHOLD0) | + (diff << THERM_SHIFT_THRESHOLD0); + wrmsr_on_cpu(tdata->cpu, tdata->intrpt_reg, eax, edx); + tdata->tmin = val; + mutex_unlock(&tdata->update_lock); + + return count; +} + static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -344,23 +442,31 @@ static int create_core_attrs(struct temp_data *tdata, struct device *dev, int attr_no) { int err, i; - static ssize_t (*rd_ptr[MAX_ATTRS]) (struct device *dev, + static ssize_t (*rd_ptr[TOTAL_ATTRS]) (struct device *dev, struct device_attribute *devattr, char *buf) = { - show_label, show_crit_alarm, show_ttarget, - show_temp, show_tjmax }; - static const char *names[MAX_ATTRS] = { + show_label, show_crit_alarm, show_temp, show_tjmax, + show_max_alarm, show_ttarget, show_tmin }; + static ssize_t (*rw_ptr[TOTAL_ATTRS]) (struct device *dev, + struct device_attribute *devattr, const char *buf, + size_t count) = { NULL, NULL, NULL, NULL, NULL, + store_ttarget, store_tmin }; + static const char *names[TOTAL_ATTRS] = { "temp%d_label", "temp%d_crit_alarm", - "temp%d_max", "temp%d_input", - "temp%d_crit" }; + "temp%d_input", "temp%d_crit", + "temp%d_max_alarm", "temp%d_max", + "temp%d_max_hyst" }; - for (i = 0; i < MAX_ATTRS; i++) { + for (i = 0; i < tdata->attr_size; i++) { snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, names[i], attr_no); sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr); tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i]; tdata->sd_attrs[i].dev_attr.attr.mode = S_IRUGO; + if (rw_ptr[i]) { + tdata->sd_attrs[i].dev_attr.attr.mode |= S_IWUSR; + tdata->sd_attrs[i].dev_attr.store = rw_ptr[i]; + } tdata->sd_attrs[i].dev_attr.show = rd_ptr[i]; - tdata->sd_attrs[i].dev_attr.store = NULL; tdata->sd_attrs[i].index = attr_no; err = device_create_file(dev, &tdata->sd_attrs[i].dev_attr); if (err) @@ -374,38 +480,6 @@ exit_free: return err; } -static void update_ttarget(__u8 cpu_model, struct temp_data *tdata, - struct device *dev) -{ - int err; - u32 eax, edx; - - /* - * Initialize ttarget value. Eventually this will be - * initialized with the value from MSR_IA32_THERM_INTERRUPT - * register. If IA32_TEMPERATURE_TARGET is supported, this - * value will be over written below. - * To Do: Patch to initialize ttarget from MSR_IA32_THERM_INTERRUPT - */ - tdata->ttarget = tdata->tjmax - 20000; - - /* - * Read the still undocumented IA32_TEMPERATURE_TARGET. It exists - * on older CPUs but not in this register, - * Atoms don't have it either. - */ - if (cpu_model > 0xe && cpu_model != 0x1c) { - err = rdmsr_safe_on_cpu(tdata->cpu, - MSR_IA32_TEMPERATURE_TARGET, &eax, &edx); - if (err) { - dev_warn(dev, - "Unable to read IA32_TEMPERATURE_TARGET MSR\n"); - } else { - tdata->ttarget = tdata->tjmax - - ((eax >> 8) & 0xff) * 1000; - } - } -} static int __devinit chk_ucode_version(struct platform_device *pdev) { @@ -464,9 +538,12 @@ static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag) tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS; + tdata->intrpt_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_INTERRUPT : + MSR_IA32_THERM_INTERRUPT; tdata->is_pkg_data = pkg_flag; tdata->cpu = cpu; tdata->cpu_core_id = TO_CORE_ID(cpu); + tdata->attr_size = MAX_CORE_ATTRS; mutex_init(&tdata->update_lock); return tdata; } @@ -516,7 +593,22 @@ static int create_core_data(struct platform_data *pdata, else tdata->tjmax = get_tjmax(c, cpu, &pdev->dev); - update_ttarget(c->x86_model, tdata, &pdev->dev); + /* + * Test if we can access the intrpt register. If so, increase the + * 'size' enough to have ttarget/tmin/max_alarm interfaces. + * Initialize ttarget with bits 16:22 of MSR_IA32_THERM_INTERRUPT + */ + err = rdmsr_safe_on_cpu(cpu, tdata->intrpt_reg, &eax, &edx); + if (!err) { + tdata->attr_size += MAX_THRESH_ATTRS; + tdata->tmin = tdata->tjmax - + ((eax & THERM_MASK_THRESHOLD0) >> + THERM_SHIFT_THRESHOLD0) * 1000; + tdata->ttarget = tdata->tjmax - + ((eax & THERM_MASK_THRESHOLD1) >> + THERM_SHIFT_THRESHOLD1) * 1000; + } + pdata->core_data[attr_no] = tdata; /* Create sysfs interfaces */ @@ -553,7 +645,7 @@ static void coretemp_remove_core(struct platform_data *pdata, struct temp_data *tdata = pdata->core_data[indx]; /* Remove the sysfs attributes */ - for (i = 0; i < MAX_ATTRS; i++) + for (i = 0; i < tdata->attr_size; i++) device_remove_file(dev, &tdata->sd_attrs[i].dev_attr); kfree(pdata->core_data[indx]); diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c index ec588026f0a..131ea8625f0 100644 --- a/drivers/hwmon/gl520sm.c +++ b/drivers/hwmon/gl520sm.c @@ -273,7 +273,7 @@ static SENSOR_DEVICE_ATTR(in4_max, S_IRUGO | S_IWUSR, #define DIV_FROM_REG(val) (1 << (val)) #define FAN_FROM_REG(val,div) ((val)==0 ? 0 : (480000/((val) << (div)))) -#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)); +#define FAN_TO_REG(val,div) ((val)<=0?0:SENSORS_LIMIT((480000 + ((val) << ((div)-1))) / ((val) << (div)), 1, 255)) static ssize_t get_fan_input(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index c8195a077da..932da8a5aaf 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -140,7 +140,11 @@ int vid_from_reg(int val, u8 vrm) return(val & 0x10 ? 975 - (val & 0xF) * 25 : 1750 - val * 50); case 13: + case 131: val &= 0x3f; + /* Exception for Eden ULV 500 MHz */ + if (vrm == 131 && val == 0x3f) + val++; return(1708 - val * 16); case 14: /* Intel Core */ /* compute in uV, round to mV */ @@ -205,11 +209,45 @@ static struct vrm_model vrm_models[] = { {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */ {X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */ {X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */ - {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */ + {X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7-M, C7, Eden (Esther) */ + {X86_VENDOR_CENTAUR, 0x6, 0xD, ANY, 134}, /* C7-D, C7-M, C7, Eden (Esther) */ {X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0} /* stop here */ }; +/* + * Special case for VIA model D: there are two different possible + * VID tables, so we have to figure out first, which one must be + * used. This resolves temporary drm value 134 to 14 (Intel Core + * 7-bit VID), 13 (Pentium M 6-bit VID) or 131 (Pentium M 6-bit VID + * + quirk for Eden ULV 500 MHz). + * Note: something similar might be needed for model A, I'm not sure. + */ +static u8 get_via_model_d_vrm(void) +{ + unsigned int vid, brand, dummy; + static const char *brands[4] = { + "C7-M", "C7", "Eden", "C7-D" + }; + + rdmsr(0x198, dummy, vid); + vid &= 0xff; + + rdmsr(0x1154, brand, dummy); + brand = ((brand >> 4) ^ (brand >> 2)) & 0x03; + + if (vid > 0x3f) { + pr_info("Using %d-bit VID table for VIA %s CPU\n", + 7, brands[brand]); + return 14; + } else { + pr_info("Using %d-bit VID table for VIA %s CPU\n", + 6, brands[brand]); + /* Enable quirk for Eden */ + return brand == 2 ? 131 : 13; + } +} + static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) { int i = 0; @@ -247,6 +285,8 @@ u8 vid_which_vrm(void) eff_model += ((eax & 0x000F0000)>>16)<<4; } vrm_ret = find_vrm(eff_family, eff_model, eff_stepping, c->x86_vendor); + if (vrm_ret == 134) + vrm_ret = get_via_model_d_vrm(); if (vrm_ret == 0) pr_info("Unknown VRM version of your x86 CPU\n"); return vrm_ret; diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index c4c40be0edb..d22f241b6a6 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -114,7 +114,6 @@ struct i5k_amb_data { void __iomem *amb_mmio; struct i5k_device_attribute *attrs; unsigned int num_attrs; - unsigned long chipset_id; }; static ssize_t show_name(struct device *dev, struct device_attribute *devattr, @@ -444,8 +443,6 @@ static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, goto out; } - data->chipset_id = devid; - res = 0; out: pci_dev_put(pcidev); @@ -478,23 +475,13 @@ out: return res; } -static unsigned long i5k_channel_pci_id(struct i5k_amb_data *data, - unsigned long channel) -{ - switch (data->chipset_id) { - case PCI_DEVICE_ID_INTEL_5000_ERR: - return PCI_DEVICE_ID_INTEL_5000_FBD0 + channel; - case PCI_DEVICE_ID_INTEL_5400_ERR: - return PCI_DEVICE_ID_INTEL_5400_FBD0 + channel; - default: - BUG(); - } -} - -static unsigned long chipset_ids[] = { - PCI_DEVICE_ID_INTEL_5000_ERR, - PCI_DEVICE_ID_INTEL_5400_ERR, - 0 +static struct { + unsigned long err; + unsigned long fbd0; +} chipset_ids[] __devinitdata = { + { PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 }, + { PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 }, + { 0, 0 } }; #ifdef MODULE @@ -510,8 +497,7 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) { struct i5k_amb_data *data; struct resource *reso; - int i; - int res = -ENODEV; + int i, res; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) @@ -520,22 +506,22 @@ static int __devinit i5k_amb_probe(struct platform_device *pdev) /* Figure out where the AMB registers live */ i = 0; do { - res = i5k_find_amb_registers(data, chipset_ids[i]); + res = i5k_find_amb_registers(data, chipset_ids[i].err); + if (res == 0) + break; i++; - } while (res && chipset_ids[i]); + } while (chipset_ids[i].err); if (res) goto err; /* Copy the DIMM presence map for the first two channels */ - res = i5k_channel_probe(&data->amb_present[0], - i5k_channel_pci_id(data, 0)); + res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0); if (res) goto err; /* Copy the DIMM presence map for the optional second two channels */ - i5k_channel_probe(&data->amb_present[2], - i5k_channel_pci_id(data, 1)); + i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1); /* Set up resource regions */ reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 1a409c5bc9b..c316294c48b 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -432,13 +432,15 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, aem_send_message(ipmi); res = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!res) - return -ETIMEDOUT; + if (!res) { + res = -ETIMEDOUT; + goto out; + } if (ipmi->rx_result || ipmi->rx_msg_len != rs_size || memcmp(&rs_resp->id, &system_x_id, sizeof(system_x_id))) { - kfree(rs_resp); - return -ENOENT; + res = -ENOENT; + goto out; } switch (size) { @@ -463,8 +465,11 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, break; } } + res = 0; - return 0; +out: + kfree(rs_resp); + return res; } /* Update AEM energy registers */ diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 5f524775043..d912649fac5 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -1172,6 +1172,32 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr, struct it87_data *data = it87_update_device(dev); return sprintf(buf, "%u\n", (data->alarms >> bitnr) & 1); } + +static ssize_t clear_intrusion(struct device *dev, struct device_attribute |