diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/coretemp.c | 32 | ||||
-rw-r--r-- | drivers/hwmon/i5k_amb.c | 6 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 22 | ||||
-rw-r--r-- | drivers/hwmon/k10temp.c | 14 | ||||
-rw-r--r-- | drivers/hwmon/k8temp.c | 12 |
5 files changed, 77 insertions, 9 deletions
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 2988da150ed6..05344af50734 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -53,6 +53,7 @@ struct coretemp_data { struct mutex update_lock; const char *name; u32 id; + u16 core_id; char valid; /* zero until following fields are valid */ unsigned long last_updated; /* in jiffies */ int temp; @@ -75,7 +76,7 @@ static ssize_t show_name(struct device *dev, struct device_attribute if (attr->index == SHOW_NAME) ret = sprintf(buf, "%s\n", data->name); else /* show label */ - ret = sprintf(buf, "Core %d\n", data->id); + ret = sprintf(buf, "Core %d\n", data->core_id); return ret; } @@ -304,6 +305,9 @@ static int __devinit coretemp_probe(struct platform_device *pdev) } data->id = pdev->id; +#ifdef CONFIG_SMP + data->core_id = c->cpu_core_id; +#endif data->name = "coretemp"; mutex_init(&data->update_lock); @@ -405,6 +409,10 @@ struct pdev_entry { struct list_head list; struct platform_device *pdev; unsigned int cpu; +#ifdef CONFIG_SMP + u16 phys_proc_id; + u16 cpu_core_id; +#endif }; static LIST_HEAD(pdev_list); @@ -415,6 +423,22 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) int err; struct platform_device *pdev; struct pdev_entry *pdev_entry; +#ifdef CONFIG_SMP + struct cpuinfo_x86 *c = &cpu_data(cpu); +#endif + + mutex_lock(&pdev_list_mutex); + +#ifdef CONFIG_SMP + /* Skip second HT entry of each core */ + list_for_each_entry(pdev_entry, &pdev_list, list) { + if (c->phys_proc_id == pdev_entry->phys_proc_id && + c->cpu_core_id == pdev_entry->cpu_core_id) { + err = 0; /* Not an error */ + goto exit; + } + } +#endif pdev = platform_device_alloc(DRVNAME, cpu); if (!pdev) { @@ -438,7 +462,10 @@ static int __cpuinit coretemp_device_add(unsigned int cpu) pdev_entry->pdev = pdev; pdev_entry->cpu = cpu; - mutex_lock(&pdev_list_mutex); +#ifdef CONFIG_SMP + pdev_entry->phys_proc_id = c->phys_proc_id; + pdev_entry->cpu_core_id = c->cpu_core_id; +#endif list_add_tail(&pdev_entry->list, &pdev_list); mutex_unlock(&pdev_list_mutex); @@ -449,6 +476,7 @@ exit_device_free: exit_device_put: platform_device_put(pdev); exit: + mutex_unlock(&pdev_list_mutex); return err; } diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index e880e2c3871d..937983407e2a 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -289,6 +289,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_label; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -303,6 +304,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_temp; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -318,6 +320,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_min; iattr->s_attr.dev_attr.store = store_amb_min; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -333,6 +336,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_mid; iattr->s_attr.dev_attr.store = store_amb_mid; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -348,6 +352,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_max; iattr->s_attr.dev_attr.store = store_amb_max; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -362,6 +367,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_alarm; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 5be09c048c5f..25763d2223b6 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -80,6 +80,13 @@ superio_inb(int reg) return inb(VAL); } +static inline void +superio_outb(int reg, int val) +{ + outb(reg, REG); + outb(val, VAL); +} + static int superio_inw(int reg) { int val; @@ -1517,6 +1524,21 @@ static int __init it87_find(unsigned short *address, sio_data->vid_value = superio_inb(IT87_SIO_VID_REG); reg = superio_inb(IT87_SIO_PINX2_REG); + /* + * The IT8720F has no VIN7 pin, so VCCH should always be + * routed internally to VIN7 with an internal divider. + * Curiously, there still is a configuration bit to control + * this, which means it can be set incorrectly. And even + * more curiously, many boards out there are improperly + * configured, even though the IT8720F datasheet claims + * that the internal routing of VCCH to VIN7 is the default + * setting. So we force the internal routing in this case. + */ + if (sio_data->type == it8720 && !(reg & (1 << 1))) { + reg |= (1 << 1); + superio_outb(IT87_SIO_PINX2_REG, reg); + pr_notice("it87: Routing internal VCCH to in7\n"); + } if (reg & (1 << 0)) pr_info("it87: in3 is VCC (+5V)\n"); if (reg & (1 << 1)) diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 099a2138cdf6..da5a2404cd3e 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -112,11 +112,21 @@ static bool __devinit has_erratum_319(struct pci_dev *pdev) if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3) return false; - /* Differentiate between AM2+ (bad) and AM3 (good) */ + /* DDR3 memory implies socket AM3, which is good */ pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2), REG_DCT0_CONFIG_HIGH, ®_dram_cfg); - return !(reg_dram_cfg & DDR3_MODE); + if (reg_dram_cfg & DDR3_MODE) + return false; + + /* + * Unfortunately it is possible to run a socket AM3 CPU with DDR2 + * memory. We blacklist all the cores which do exist in socket AM2+ + * format. It still isn't perfect, as RB-C2 cores exist in both AM2+ + * and AM3 formats, but that's the best we can do. + */ + return boot_cpu_data.x86_model < 4 || + (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2); } static int __devinit k10temp_probe(struct pci_dev *pdev, diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 0ceb6d6200a3..8bdf80d91598 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -120,7 +120,7 @@ static ssize_t show_temp(struct device *dev, int temp; struct k8temp_data *data = k8temp_update_device(dev); - if (data->swap_core_select) + if (data->swap_core_select && (data->sensorsp & SEL_CORE)) core = core ? 0 : 1; temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; @@ -180,11 +180,13 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, } if ((model >= 0x69) && - !(model == 0xc1 || model == 0x6c || model == 0x7c)) { + !(model == 0xc1 || model == 0x6c || model == 0x7c || + model == 0x6b || model == 0x6f || model == 0x7f)) { /* - * RevG desktop CPUs (i.e. no socket S1G1 parts) - * need additional offset, otherwise reported - * temperature is below ambient temperature + * RevG desktop CPUs (i.e. no socket S1G1 or + * ASB1 parts) need additional offset, + * otherwise reported temperature is below + * ambient temperature */ data->temp_offset = 21000; } |