diff --git a/drivers/gnss/serial.c b/drivers/gnss/serial.c index 31e891f00175..def64b36d994 100644 --- a/drivers/gnss/serial.c +++ b/drivers/gnss/serial.c @@ -65,7 +65,7 @@ static int gnss_serial_write_raw(struct gnss_device *gdev, /* write is only buffered synchronously */ ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); - if (ret < 0) + if (ret < 0 || ret < count) return ret; /* FIXME: determine if interrupted? */ diff --git a/drivers/gnss/sirf.c b/drivers/gnss/sirf.c index 71d014edd167..b3a4c0e91947 100644 --- a/drivers/gnss/sirf.c +++ b/drivers/gnss/sirf.c @@ -85,7 +85,7 @@ static int sirf_write_raw(struct gnss_device *gdev, const unsigned char *buf, /* write is only buffered synchronously */ ret = serdev_device_write(serdev, buf, count, MAX_SCHEDULE_TIMEOUT); - if (ret < 0) + if (ret < 0 || ret < count) return ret; /* FIXME: determine if interrupted? */ diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index c7d637d2bc56..ee4c40336633 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -234,6 +234,7 @@ int serdev_device_write(struct serdev_device *serdev, unsigned long timeout) { struct serdev_controller *ctrl = serdev->ctrl; + int written = 0; int ret; if (!ctrl || !ctrl->ops->write_buf || !serdev->ops->write_wakeup) @@ -250,14 +251,21 @@ int serdev_device_write(struct serdev_device *serdev, if (ret < 0) break; + written += ret; buf += ret; count -= ret; - } while (count && (timeout = wait_for_completion_timeout(&serdev->write_comp, timeout))); mutex_unlock(&serdev->write_lock); - return ret < 0 ? ret : (count ? -ETIMEDOUT : 0); + + if (ret < 0) + return ret; + + if (timeout == 0 && written == 0) + return -ETIMEDOUT; + + return written; } EXPORT_SYMBOL_GPL(serdev_device_write);