revert "dpt_i2o: convert to SCSI hotplug model"
[powerpc.git] / drivers / misc / thinkpad_acpi.c
index 109bd27..ab23a32 100644 (file)
@@ -21,7 +21,7 @@
  *  02110-1301, USA.
  */
 
-#define IBM_VERSION "0.16"
+#define IBM_VERSION "0.17"
 #define TPACPI_SYSFS_VERSION 0x020000
 
 /*
@@ -1342,9 +1342,8 @@ static int hotkey_read(char *p)
                return len;
        }
 
-       res = mutex_lock_interruptible(&hotkey_mutex);
-       if (res < 0)
-               return res;
+       if (mutex_lock_interruptible(&hotkey_mutex))
+               return -ERESTARTSYS;
        res = hotkey_get(&status, &mask);
        mutex_unlock(&hotkey_mutex);
        if (res)
@@ -1373,9 +1372,8 @@ static int hotkey_write(char *buf)
        if (!tp_features.hotkey)
                return -ENODEV;
 
-       res = mutex_lock_interruptible(&hotkey_mutex);
-       if (res < 0)
-               return res;
+       if (mutex_lock_interruptible(&hotkey_mutex))
+               return -ERESTARTSYS;
 
        res = hotkey_get(&status, &mask);
        if (res)
@@ -3280,6 +3278,8 @@ static void brightness_exit(void)
 
 static int brightness_update_status(struct backlight_device *bd)
 {
+       /* it is the backlight class's job (caller) to handle
+        * EINTR and other errors properly */
        return brightness_set(
                (bd->props.fb_blank == FB_BLANK_UNBLANK &&
                 bd->props.power == FB_BLANK_UNBLANK) ?
@@ -3320,6 +3320,7 @@ static int brightness_get(struct backlight_device *bd)
        return level;
 }
 
+/* May return EINTR which can always be mapped to ERESTARTSYS */
 static int brightness_set(int value)
 {
        int cmos_cmd, inc, i, res;
@@ -3383,29 +3384,34 @@ static int brightness_read(char *p)
 static int brightness_write(char *buf)
 {
        int level;
-       int new_level;
+       int rc;
        char *cmd;
        int max_level = (tp_features.bright_16levels) ? 15 : 7;
 
-       while ((cmd = next_cmd(&buf))) {
-               if ((level = brightness_get(NULL)) < 0)
-                       return level;
+       level = brightness_get(NULL);
+       if (level < 0)
+               return level;
 
+       while ((cmd = next_cmd(&buf))) {
                if (strlencmp(cmd, "up") == 0) {
-                       new_level = level == (max_level)?
-                                               max_level : level + 1;
+                       if (level < max_level)
+                               level++;
                } else if (strlencmp(cmd, "down") == 0) {
-                       new_level = level == 0? 0 : level - 1;
-               } else if (sscanf(cmd, "level %d", &new_level) == 1 &&
-                          new_level >= 0 && new_level <= max_level) {
-                       /* new_level set */
+                       if (level > 0)
+                               level--;
+               } else if (sscanf(cmd, "level %d", &level) == 1 &&
+                          level >= 0 && level <= max_level) {
+                       /* new level set */
                } else
                        return -EINVAL;
-
-               brightness_set(new_level);
        }
 
-       return 0;
+       /*
+        * Now we know what the final level should be, so we try to set it.
+        * Doing it this way makes the syscall restartable in case of EINTR
+        */
+       rc = brightness_set(level);
+       return (rc == -EINTR)? ERESTARTSYS : rc;
 }
 
 static struct ibm_struct brightness_driver_data = {
@@ -3768,9 +3774,8 @@ static ssize_t fan_pwm1_store(struct device *dev,
        /* scale down from 0-255 to 0-7 */
        newlevel = (s >> 5) & 0x07;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
 
        rc = fan_get_status(&status);
        if (!rc && (status &
@@ -4020,9 +4025,8 @@ static int fan_get_status_safe(u8 *status)
        int rc;
        u8 s;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
        rc = fan_get_status(&s);
        if (!rc)
                fan_update_desired_level(s);
@@ -4156,9 +4160,8 @@ static int fan_set_level_safe(int level)
        if (!fan_control_allowed)
                return -EPERM;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
 
        if (level == TPACPI_FAN_LAST_LEVEL)
                level = fan_control_desired_level;
@@ -4179,9 +4182,8 @@ static int fan_set_enable(void)
        if (!fan_control_allowed)
                return -EPERM;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
 
        switch (fan_control_access_mode) {
        case TPACPI_FAN_WR_ACPI_FANS:
@@ -4235,9 +4237,8 @@ static int fan_set_disable(void)
        if (!fan_control_allowed)
                return -EPERM;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
 
        rc = 0;
        switch (fan_control_access_mode) {
@@ -4274,9 +4275,8 @@ static int fan_set_speed(int speed)
        if (!fan_control_allowed)
                return -EPERM;
 
-       rc = mutex_lock_interruptible(&fan_mutex);
-       if (rc < 0)
-               return rc;
+       if (mutex_lock_interruptible(&fan_mutex))
+               return -ERESTARTSYS;
 
        rc = 0;
        switch (fan_control_access_mode) {
@@ -4817,9 +4817,15 @@ static int __init set_ibm_param(const char *val, struct kernel_param *kp)
        unsigned int i;
        struct ibm_struct *ibm;
 
+       if (!kp || !kp->name || !val)
+               return -EINVAL;
+
        for (i = 0; i < ARRAY_SIZE(ibms_init); i++) {
                ibm = ibms_init[i].data;
-               BUG_ON(ibm == NULL);
+               WARN_ON(ibm == NULL);
+
+               if (!ibm || !ibm->name)
+                       continue;
 
                if (strcmp(ibm->name, kp->name) == 0 && ibm->write) {
                        if (strlen(val) > sizeof(ibms_init[i].param) - 2)