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>
 
 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;
                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;
 }
 
 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 *);