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 <johan@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Johan Hovold 2018-11-14 16:09:03 +01:00 committed by Greg Kroah-Hartman
parent 0bbf0a88fa
commit 70d188041e
2 changed files with 15 additions and 7 deletions

View 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;
}

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