From: Johan Hovold Date: Wed, 14 Nov 2018 15:09:03 +0000 (+0100) Subject: serdev: make synchronous write helper interruptible X-Git-Tag: v5.4-rc1~1926^2~42 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70d188041e6f1f92004f1d5d7ddfd5013273b7a5;p=platform%2Fkernel%2Flinux-rpi.git serdev: make synchronous write helper interruptible 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 Reviewed-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index ee4c403..c7006bb 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -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; } diff --git a/include/linux/serdev.h b/include/linux/serdev.h index f153b2c..070bf4e 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -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 *);