]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
serdev: make synchronous write helper interruptible
authorJohan Hovold <johan@kernel.org>
Wed, 14 Nov 2018 15:09:03 +0000 (16:09 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Nov 2018 18:44:21 +0000 (19:44 +0100)
Allow the synchronous serdev_device_write() helper to be interrupted.

This is useful for cases where I/O is performed on behalf of user space
and we don't want to block indefinitely when using flow control.

Signed-off-by: Johan Hovold <johan@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serdev/core.c
include/linux/serdev.h

index ee4c4033663342ee90f82f97358484b85245d8f6..c7006bbb793af137472a8138d03f348ea1fef999 100644 (file)
@@ -231,7 +231,7 @@ EXPORT_SYMBOL_GPL(serdev_device_write_buf);
 
 int serdev_device_write(struct serdev_device *serdev,
                        const unsigned char *buf, size_t count,
-                       unsigned long timeout)
+                       long timeout)
 {
        struct serdev_controller *ctrl = serdev->ctrl;
        int written = 0;
@@ -254,16 +254,24 @@ int serdev_device_write(struct serdev_device *serdev,
                written += ret;
                buf += ret;
                count -= ret;
-       } while (count &&
-                (timeout = wait_for_completion_timeout(&serdev->write_comp,
-                                                       timeout)));
+
+               if (count == 0)
+                       break;
+
+               timeout = wait_for_completion_interruptible_timeout(&serdev->write_comp,
+                                                                   timeout);
+       } while (timeout > 0);
        mutex_unlock(&serdev->write_lock);
 
        if (ret < 0)
                return ret;
 
-       if (timeout == 0 && written == 0)
-               return -ETIMEDOUT;
+       if (timeout <= 0 && written == 0) {
+               if (timeout == -ERESTARTSYS)
+                       return -ERESTARTSYS;
+               else
+                       return -ETIMEDOUT;
+       }
 
        return written;
 }
index f153b2c7f0cd65610906f15c083643fba54e527f..070bf4e92df7d4999c902f89d010101c831de15d 100644 (file)
@@ -210,7 +210,7 @@ void serdev_device_wait_until_sent(struct serdev_device *, long);
 int serdev_device_get_tiocm(struct serdev_device *);
 int serdev_device_set_tiocm(struct serdev_device *, int, int);
 void serdev_device_write_wakeup(struct serdev_device *);
-int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, unsigned long);
+int serdev_device_write(struct serdev_device *, const unsigned char *, size_t, long);
 void serdev_device_write_flush(struct serdev_device *);
 int serdev_device_write_room(struct serdev_device *);