hwmon: (coretemp) Drop duplicate function get_pkg_tjmax
[linux-2.6.git] / drivers / hwmon / pc87360.c
index 7153b63..3d99b88 100644 (file)
@@ -33,6 +33,8 @@
  *  the standard Super-I/O addresses is used (0x2E/0x2F or 0x4E/0x4F).
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -43,7 +45,8 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <asm/io.h>
+#include <linux/acpi.h>
+#include <linux/io.h>
 
 static u8 devid;
 static struct platform_device *pdev;
@@ -714,12 +717,68 @@ static struct sensor_device_attribute therm_crit[] = {
                    show_therm_crit, set_therm_crit, 2+11),
 };
 
+/* show_therm_min/max_alarm() reads data from the per-channel voltage
+   status register (sec 11.5.12) */
+
+static ssize_t show_therm_min_alarm(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+       return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN));
+}
+static ssize_t show_therm_max_alarm(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+       return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX));
+}
+static ssize_t show_therm_crit_alarm(struct device *dev,
+                               struct device_attribute *devattr, char *buf)
+{
+       struct pc87360_data *data = pc87360_update_device(dev);
+       unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+       return sprintf(buf, "%u\n", !!(data->in_status[nr] & TEMP_ALM_CRIT));
+}
+
+static struct sensor_device_attribute therm_min_alarm[] = {
+       SENSOR_ATTR(temp4_min_alarm, S_IRUGO,
+                   show_therm_min_alarm, NULL, 0+11),
+       SENSOR_ATTR(temp5_min_alarm, S_IRUGO,
+                   show_therm_min_alarm, NULL, 1+11),
+       SENSOR_ATTR(temp6_min_alarm, S_IRUGO,
+                   show_therm_min_alarm, NULL, 2+11),
+};
+static struct sensor_device_attribute therm_max_alarm[] = {
+       SENSOR_ATTR(temp4_max_alarm, S_IRUGO,
+                   show_therm_max_alarm, NULL, 0+11),
+       SENSOR_ATTR(temp5_max_alarm, S_IRUGO,
+                   show_therm_max_alarm, NULL, 1+11),
+       SENSOR_ATTR(temp6_max_alarm, S_IRUGO,
+                   show_therm_max_alarm, NULL, 2+11),
+};
+static struct sensor_device_attribute therm_crit_alarm[] = {
+       SENSOR_ATTR(temp4_crit_alarm, S_IRUGO,
+                   show_therm_crit_alarm, NULL, 0+11),
+       SENSOR_ATTR(temp5_crit_alarm, S_IRUGO,
+                   show_therm_crit_alarm, NULL, 1+11),
+       SENSOR_ATTR(temp6_crit_alarm, S_IRUGO,
+                   show_therm_crit_alarm, NULL, 2+11),
+};
+
 #define THERM_UNIT_ATTRS(X) \
        &therm_input[X].dev_attr.attr,  \
        &therm_status[X].dev_attr.attr, \
        &therm_min[X].dev_attr.attr,    \
        &therm_max[X].dev_attr.attr,    \
-       &therm_crit[X].dev_attr.attr
+       &therm_crit[X].dev_attr.attr,   \
+       &therm_min_alarm[X].dev_attr.attr, \
+       &therm_max_alarm[X].dev_attr.attr, \
+       &therm_crit_alarm[X].dev_attr.attr
 
 static struct attribute * pc8736x_therm_attr_array[] = {
        THERM_UNIT_ATTRS(0),
@@ -974,16 +1033,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
 
                val = superio_inb(sioaddr, ACT);
                if (!(val & 0x01)) {
-                       printk(KERN_INFO "pc87360: Device 0x%02x not "
-                              "activated\n", logdev[i]);
+                       pr_info("Device 0x%02x not activated\n", logdev[i]);
                        continue;
                }
 
                val = (superio_inb(sioaddr, BASE) << 8)
                    | superio_inb(sioaddr, BASE + 1);
                if (!val) {
-                       printk(KERN_INFO "pc87360: Base address not set for "
-                              "device 0x%02x\n", logdev[i]);
+                       pr_info("Base address not set for device 0x%02x\n",
+                               logdev[i]);
                        continue;
                }
 
@@ -993,17 +1051,15 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
                        confreg[0] = superio_inb(sioaddr, 0xF0);
                        confreg[1] = superio_inb(sioaddr, 0xF1);
 
-#ifdef DEBUG
-                       printk(KERN_DEBUG "pc87360: Fan 1: mon=%d "
-                              "ctrl=%d inv=%d\n", (confreg[0]>>2)&1,
-                              (confreg[0]>>3)&1, (confreg[0]>>4)&1);
-                       printk(KERN_DEBUG "pc87360: Fan 2: mon=%d "
-                              "ctrl=%d inv=%d\n", (confreg[0]>>5)&1,
-                              (confreg[0]>>6)&1, (confreg[0]>>7)&1);
-                       printk(KERN_DEBUG "pc87360: Fan 3: mon=%d "
-                              "ctrl=%d inv=%d\n", confreg[1]&1,
-                              (confreg[1]>>1)&1, (confreg[1]>>2)&1);
-#endif
+                       pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 1,
+                                (confreg[0] >> 2) & 1, (confreg[0] >> 3) & 1,
+                                (confreg[0] >> 4) & 1);
+                       pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 2,
+                                (confreg[0] >> 5) & 1, (confreg[0] >> 6) & 1,
+                                (confreg[0] >> 7) & 1);
+                       pr_debug("Fan %d: mon=%d ctrl=%d inv=%d\n", 3,
+                                confreg[1] & 1, (confreg[1] >> 1) & 1,
+                                (confreg[1] >> 2) & 1);
                } else if (i==1) { /* Voltages */
                        /* Are we using thermistors? */
                        if (*devid == 0xE9) { /* PC87366 */
@@ -1014,14 +1070,12 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
                                confreg[3] = superio_inb(sioaddr, 0x25);
 
                                if (confreg[2] & 0x40) {
-                                       printk(KERN_INFO "pc87360: Using "
-                                              "thermistors for temperature "
-                                              "monitoring\n");
+                                       pr_info("Using thermistors for "
+                                               "temperature monitoring\n");
                                }
                                if (confreg[3] & 0xE0) {
-                                       printk(KERN_INFO "pc87360: VID "
-                                              "inputs routed (mode %u)\n",
-                                              confreg[3] >> 5);
+                                       pr_info("VID inputs routed (mode %u)\n",
+                                               confreg[3] >> 5);
                                }
                        }
                }
@@ -1290,10 +1344,11 @@ static void pc87360_init_device(struct platform_device *pdev,
 
        nr = data->innr < 11 ? data->innr : 11;
        for (i = 0; i < nr; i++) {
+               reg = pc87360_read_value(data, LD_IN, i,
+                                        PC87365_REG_IN_STATUS);
+               dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg);
                if (init >= init_in[i]) {
                        /* Forcibly enable voltage channel */
-                       reg = pc87360_read_value(data, LD_IN, i,
-                                                PC87365_REG_IN_STATUS);
                        if (!(reg & CHAN_ENA)) {
                                dev_dbg(&pdev->dev, "Forcibly "
                                        "enabling in%d\n", i);
@@ -1306,18 +1361,23 @@ static void pc87360_init_device(struct platform_device *pdev,
 
        /* We can't blindly trust the Super-I/O space configuration bit,
           most BIOS won't set it properly */
+       dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors);
        for (i = 11; i < data->innr; i++) {
                reg = pc87360_read_value(data, LD_IN, i,
                                         PC87365_REG_TEMP_STATUS);
                use_thermistors = use_thermistors || (reg & CHAN_ENA);
+               /* thermistors are temp[4-6], measured on vin[11-14] */
+               dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg);
        }
+       dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors);
 
        i = use_thermistors ? 2 : 0;
        for (; i < data->tempnr; i++) {
+               reg = pc87360_read_value(data, LD_TEMP, i,
+                                        PC87365_REG_TEMP_STATUS);
+               dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg);
                if (init >= init_temp[i]) {
                        /* Forcibly enable temperature channel */
-                       reg = pc87360_read_value(data, LD_TEMP, i,
-                                                PC87365_REG_TEMP_STATUS);
                        if (!(reg & CHAN_ENA)) {
                                dev_dbg(&pdev->dev, "Forcibly "
                                        "enabling temp%d\n", i+1);
@@ -1359,6 +1419,7 @@ static void pc87360_init_device(struct platform_device *pdev,
        if (data->innr) {
                reg = pc87360_read_value(data, LD_IN, NO_BANK,
                                         PC87365_REG_IN_CONFIG);
+               dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg);
                if (reg & CHAN_ENA) {
                        dev_dbg(&pdev->dev, "Forcibly "
                                "enabling monitoring (VLM)\n");
@@ -1371,6 +1432,7 @@ static void pc87360_init_device(struct platform_device *pdev,
        if (data->tempnr) {
                reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
                                         PC87365_REG_TEMP_CONFIG);
+               dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg);
                if (reg & CHAN_ENA) {
                        dev_dbg(&pdev->dev, "Forcibly enabling "
                                "monitoring (TMS)\n");
@@ -1545,36 +1607,42 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
 
 static int __init pc87360_device_add(unsigned short address)
 {
-       struct resource res = {
-               .name   = "pc87360",
-               .flags  = IORESOURCE_IO,
-       };
-       int err, i;
+       struct resource res[3];
+       int err, i, res_count;
 
        pdev = platform_device_alloc("pc87360", address);
        if (!pdev) {
                err = -ENOMEM;
-               printk(KERN_ERR "pc87360: Device allocation failed\n");
+               pr_err("Device allocation failed\n");
                goto exit;
        }
 
+       memset(res, 0, 3 * sizeof(struct resource));
+       res_count = 0;
        for (i = 0; i < 3; i++) {
                if (!extra_isa[i])
                        continue;
-               res.start = extra_isa[i];
-               res.end = extra_isa[i] + PC87360_EXTENT - 1;
-               err = platform_device_add_resources(pdev, &res, 1);
-               if (err) {
-                       printk(KERN_ERR "pc87360: Device resource[%d] "
-                              "addition failed (%d)\n", i, err);
+               res[res_count].start = extra_isa[i];
+               res[res_count].end = extra_isa[i] + PC87360_EXTENT - 1;
+               res[res_count].name = "pc87360",
+               res[res_count].flags = IORESOURCE_IO,
+
+               err = acpi_check_resource_conflict(&res[res_count]);
+               if (err)
                        goto exit_device_put;
-               }
+
+               res_count++;
+       }
+
+       err = platform_device_add_resources(pdev, res, res_count);
+       if (err) {
+               pr_err("Device resources addition failed (%d)\n", err);
+               goto exit_device_put;
        }
 
        err = platform_device_add(pdev);
        if (err) {
-               printk(KERN_ERR "pc87360: Device addition failed (%d)\n",
-                      err);
+               pr_err("Device addition failed (%d)\n", err);
                goto exit_device_put;
        }
 
@@ -1593,8 +1661,7 @@ static int __init pc87360_init(void)
 
        if (pc87360_find(0x2e, &devid, extra_isa)
         && pc87360_find(0x4e, &devid, extra_isa)) {
-               printk(KERN_WARNING "pc87360: PC8736x not detected, "
-                      "module not inserted.\n");
+               pr_warn("PC8736x not detected, module not inserted\n");
                return -ENODEV;
        }
 
@@ -1607,8 +1674,7 @@ static int __init pc87360_init(void)
        }
 
        if (address == 0x0000) {
-               printk(KERN_WARNING "pc87360: No active logical device, "
-                      "module not inserted.\n");
+               pr_warn("No active logical device, module not inserted\n");
                return -ENODEV;
        }