Merge master.kernel.org:/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[pandora-kernel.git] / drivers / hwmon / abituguru.c
index 59122cc..b1dc63e 100644 (file)
     etc voltage & frequency control is not supported!
 */
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
 #include <linux/err.h>
+#include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #define ABIT_UGURU_IN_SENSOR                   0
 #define ABIT_UGURU_TEMP_SENSOR                 1
 #define ABIT_UGURU_NC                          2
-/* Timeouts / Retries, if these turn out to need a lot of fiddling we could
-   convert them to params. */
-/* 250 was determined by trial and error, 200 works most of the time, but not
-   always. I assume this is cpu-speed independent, since the ISA-bus and not
-   the CPU should be the bottleneck. Note that 250 sometimes is still not
-   enough (only reported on AN7 mb) this is handled by a higher layer. */
-#define ABIT_UGURU_WAIT_TIMEOUT                        250
+/* In many cases we need to wait for the uGuru to reach a certain status, most
+   of the time it will reach this status within 30 - 90 ISA reads, and thus we
+   can best busy wait. This define gives the total amount of reads to try. */
+#define ABIT_UGURU_WAIT_TIMEOUT                        125
+/* However sometimes older versions of the uGuru seem to be distracted and they
+   do not respond for a long time. To handle this we sleep before each of the
+   last ABIT_UGURU_WAIT_TIMEOUT_SLEEP tries. */
+#define ABIT_UGURU_WAIT_TIMEOUT_SLEEP          5
 /* Normally all expected status in abituguru_ready, are reported after the
-   first read, but sometimes not and we need to poll, 5 polls was not enough
-   50 sofar is. */
-#define ABIT_UGURU_READY_TIMEOUT               50
+   first read, but sometimes not and we need to poll. */
+#define ABIT_UGURU_READY_TIMEOUT               5
 /* Maximum 3 retries on timedout reads/writes, delay 200 ms before retrying */
 #define ABIT_UGURU_MAX_RETRIES                 3
 #define ABIT_UGURU_RETRY_DELAY                 (HZ/5)
@@ -142,6 +144,14 @@ static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 };
 static int force;
 module_param(force, bool, 0);
 MODULE_PARM_DESC(force, "Set to one to force detection.");
+static int bank1_types[ABIT_UGURU_MAX_BANK1_SENSORS] = { -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+module_param_array(bank1_types, int, NULL, 0);
+MODULE_PARM_DESC(bank1_types, "Bank1 sensortype autodetection override:\n"
+       "   -1 autodetect\n"
+       "    0 volt sensor\n"
+       "    1 temp sensor\n"
+       "    2 not connected");
 static int fan_sensors;
 module_param(fan_sensors, int, 0);
 MODULE_PARM_DESC(fan_sensors, "Number of fan sensors on the uGuru "
@@ -218,6 +228,10 @@ static int abituguru_wait(struct abituguru_data *data, u8 state)
                timeout--;
                if (timeout == 0)
                        return -EBUSY;
+               /* sleep a bit before our last few tries, see the comment on
+                  this where ABIT_UGURU_WAIT_TIMEOUT_SLEEP is defined. */
+               if (timeout <= ABIT_UGURU_WAIT_TIMEOUT_SLEEP)
+                       msleep(0);
        }
        return 0;
 }
@@ -248,6 +262,7 @@ static int abituguru_ready(struct abituguru_data *data)
                           "CMD reg does not hold 0xAC after ready command\n");
                        return -EIO;
                }
+               msleep(0);
        }
 
        /* After this the ABIT_UGURU_DATA port should contain
@@ -260,6 +275,7 @@ static int abituguru_ready(struct abituguru_data *data)
                                "state != more input after ready command\n");
                        return -EIO;
                }
+               msleep(0);
        }
 
        data->uguru_ready = 1;
@@ -323,7 +339,8 @@ static int abituguru_read(struct abituguru_data *data,
        /* And read the data */
        for (i = 0; i < count; i++) {
                if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
-                       ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for "
+                       ABIT_UGURU_DEBUG(retries ? 1 : 3,
+                               "timeout exceeded waiting for "
                                "read state (bank: %d, sensor: %d)\n",
                                (int)bank_addr, (int)sensor_addr);
                        break;
@@ -342,7 +359,9 @@ static int abituguru_read(struct abituguru_data *data,
 static int abituguru_write(struct abituguru_data *data,
        u8 bank_addr, u8 sensor_addr, u8 *buf, int count)
 {
-       int i;
+       /* We use the ready timeout as we have to wait for 0xAC just like the
+          ready function */
+       int i, timeout = ABIT_UGURU_READY_TIMEOUT;
 
        /* Send the address */
        i = abituguru_send_address(data, bank_addr, sensor_addr,
@@ -362,7 +381,8 @@ static int abituguru_write(struct abituguru_data *data,
        }
 
        /* Now we need to wait till the chip is ready to be read again,
-          don't ask why */
+          so that we can read 0xAC as confirmation that our write has
+          succeeded. */
        if (abituguru_wait(data, ABIT_UGURU_STATUS_READ)) {
                ABIT_UGURU_DEBUG(1, "timeout exceeded waiting for read state "
                        "after write (bank: %d, sensor: %d)\n", (int)bank_addr,
@@ -371,11 +391,15 @@ static int abituguru_write(struct abituguru_data *data,
        }
 
        /* Cmd port MUST be read now and should contain 0xAC */
-       if (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
-               ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after write "
-                       "(bank: %d, sensor: %d)\n", (int)bank_addr,
-                       (int)sensor_addr);
-               return -EIO;
+       while (inb_p(data->addr + ABIT_UGURU_CMD) != 0xAC) {
+               timeout--;
+               if (timeout == 0) {
+                       ABIT_UGURU_DEBUG(1, "CMD reg does not hold 0xAC after "
+                               "write (bank: %d, sensor: %d)\n",
+                               (int)bank_addr, (int)sensor_addr);
+                       return -EIO;
+               }
+               msleep(0);
        }
 
        /* Last put the chip back in ready state */
@@ -395,7 +419,16 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
                                   u8 sensor_addr)
 {
        u8 val, buf[3];
-       int ret = ABIT_UGURU_NC;
+       int i, ret = -ENODEV; /* error is the most common used retval :| */
+
+       /* If overriden by the user return the user selected type */
+       if (bank1_types[sensor_addr] >= ABIT_UGURU_IN_SENSOR &&
+                       bank1_types[sensor_addr] <= ABIT_UGURU_NC) {
+               ABIT_UGURU_DEBUG(2, "assuming sensor type %d for bank1 sensor "
+                       "%d because of \"bank1_types\" module param\n",
+                       bank1_types[sensor_addr], (int)sensor_addr);
+               return bank1_types[sensor_addr];
+       }
 
        /* First read the sensor and the current settings */
        if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1, sensor_addr, &val,
@@ -422,7 +455,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
        buf[2] = 250;
        if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
                        buf, 3) != 3)
-               return -ENODEV;
+               goto abituguru_detect_bank1_sensor_type_exit;
        /* Now we need 20 ms to give the uguru time to read the sensors
           and raise a voltage alarm */
        set_current_state(TASK_UNINTERRUPTIBLE);
@@ -430,21 +463,16 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
        /* Check for alarm and check the alarm is a volt low alarm. */
        if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3,
                        ABIT_UGURU_MAX_RETRIES) != 3)
-               return -ENODEV;
+               goto abituguru_detect_bank1_sensor_type_exit;
        if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) {
                if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
                                sensor_addr, buf, 3,
                                ABIT_UGURU_MAX_RETRIES) != 3)
-                       return -ENODEV;
+                       goto abituguru_detect_bank1_sensor_type_exit;
                if (buf[0] & ABIT_UGURU_VOLT_LOW_ALARM_FLAG) {
-                       /* Restore original settings */
-                       if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2,
-                                       sensor_addr,
-                                       data->bank1_settings[sensor_addr],
-                                       3) != 3)
-                               return -ENODEV;
                        ABIT_UGURU_DEBUG(2, "  found volt sensor\n");
-                       return ABIT_UGURU_IN_SENSOR;
+                       ret = ABIT_UGURU_IN_SENSOR;
+                       goto abituguru_detect_bank1_sensor_type_exit;
                } else
                        ABIT_UGURU_DEBUG(2, "  alarm raised during volt "
                                "sensor test, but volt low flag not set\n");
@@ -460,7 +488,7 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
        buf[2] = 10;
        if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
                        buf, 3) != 3)
-               return -ENODEV;
+               goto abituguru_detect_bank1_sensor_type_exit;
        /* Now we need 50 ms to give the uguru time to read the sensors
           and raise a temp alarm */
        set_current_state(TASK_UNINTERRUPTIBLE);
@@ -468,15 +496,16 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
        /* Check for alarm and check the alarm is a temp high alarm. */
        if (abituguru_read(data, ABIT_UGURU_ALARM_BANK, 0, buf, 3,
                        ABIT_UGURU_MAX_RETRIES) != 3)
-               return -ENODEV;
+               goto abituguru_detect_bank1_sensor_type_exit;
        if (buf[sensor_addr/8] & (0x01 << (sensor_addr % 8))) {
                if (abituguru_read(data, ABIT_UGURU_SENSOR_BANK1 + 1,
                                sensor_addr, buf, 3,
                                ABIT_UGURU_MAX_RETRIES) != 3)
-                       return -ENODEV;
+                       goto abituguru_detect_bank1_sensor_type_exit;
                if (buf[0] & ABIT_UGURU_TEMP_HIGH_ALARM_FLAG) {
-                       ret = ABIT_UGURU_TEMP_SENSOR;
                        ABIT_UGURU_DEBUG(2, "  found temp sensor\n");
+                       ret = ABIT_UGURU_TEMP_SENSOR;
+                       goto abituguru_detect_bank1_sensor_type_exit;
                } else
                        ABIT_UGURU_DEBUG(2, "  alarm raised during temp "
                                "sensor test, but temp high flag not set\n");
@@ -484,11 +513,23 @@ abituguru_detect_bank1_sensor_type(struct abituguru_data *data,
                ABIT_UGURU_DEBUG(2, "  alarm not raised during temp sensor "
                        "test\n");
 
-       /* Restore original settings */
-       if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2, sensor_addr,
-                       data->bank1_settings[sensor_addr], 3) != 3)
+       ret = ABIT_UGURU_NC;
+abituguru_detect_bank1_sensor_type_exit:
+       /* Restore original settings, failing here is really BAD, it has been
+          reported that some BIOS-es hang when entering the uGuru menu with
+          invalid settings present in the uGuru, so we try this 3 times. */
+       for (i = 0; i < 3; i++)
+               if (abituguru_write(data, ABIT_UGURU_SENSOR_BANK1 + 2,
+                               sensor_addr, data->bank1_settings[sensor_addr],
+                               3) == 3)
+                       break;
+       if (i == 3) {
+               printk(KERN_ERR ABIT_UGURU_NAME
+                       ": Fatal error could not restore original settings. "
+                       "This should never happen please report this to the "
+                       "abituguru maintainer (see MAINTAINERS)\n");
                return -ENODEV;
-
+       }
        return ret;
 }
 
@@ -514,7 +555,7 @@ abituguru_detect_no_bank2_sensors(struct abituguru_data *data)
 {
        int i;
 
-       if (fan_sensors) {
+       if (fan_sensors > 0 && fan_sensors <= ABIT_UGURU_MAX_BANK2_SENSORS) {
                data->bank2_sensors = fan_sensors;
                ABIT_UGURU_DEBUG(2, "assuming %d fan sensors because of "
                        "\"fan_sensors\" module param\n",
@@ -568,7 +609,7 @@ abituguru_detect_no_pwms(struct abituguru_data *data)
 {
        int i, j;
 
-       if (pwms) {
+       if (pwms > 0 && pwms <= ABIT_UGURU_MAX_PWMS) {
                data->pwms = pwms;
                ABIT_UGURU_DEBUG(2, "assuming %d PWM outputs because of "
                        "\"pwms\" module param\n", (int)data->pwms);
@@ -1288,7 +1329,7 @@ static struct abituguru_data *abituguru_update_device(struct device *dev)
                data->update_timeouts = 0;
 LEAVE_UPDATE:
                /* handle timeout condition */
-               if (err == -EBUSY) {
+               if (!success && (err == -EBUSY || err >= 0)) {
                        /* No overflow please */
                        if (data->update_timeouts < 255u)
                                data->update_timeouts++;
@@ -1314,13 +1355,39 @@ LEAVE_UPDATE:
                return NULL;
 }
 
+#ifdef CONFIG_PM
+static int abituguru_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct abituguru_data *data = platform_get_drvdata(pdev);
+       /* make sure all communications with the uguru are done and no new
+          ones are started */
+       mutex_lock(&data->update_lock);
+       return 0;
+}
+
+static int abituguru_resume(struct platform_device *pdev)
+{
+       struct abituguru_data *data = platform_get_drvdata(pdev);
+       /* See if the uGuru is still ready */
+       if (inb_p(data->addr + ABIT_UGURU_DATA) != ABIT_UGURU_STATUS_INPUT)
+               data->uguru_ready = 0;
+       mutex_unlock(&data->update_lock);
+       return 0;
+}
+#else
+#define abituguru_suspend      NULL
+#define abituguru_resume       NULL
+#endif /* CONFIG_PM */
+
 static struct platform_driver abituguru_driver = {
        .driver = {
                .owner  = THIS_MODULE,
                .name   = ABIT_UGURU_NAME,
        },
-       .probe  = abituguru_probe,
-       .remove = __devexit_p(abituguru_remove),
+       .probe          = abituguru_probe,
+       .remove         = __devexit_p(abituguru_remove),
+       .suspend        = abituguru_suspend,
+       .resume         = abituguru_resume,
 };
 
 static int __init abituguru_detect(void)