Commit 70d18804 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

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: default avatarJohan Hovold <johan@kernel.org>
Reviewed-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0bbf0a88
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -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)
	if (timeout <= 0 && written == 0) {
		if (timeout == -ERESTARTSYS)
			return -ERESTARTSYS;
		else
			return -ETIMEDOUT;
	}

	return written;
}
+1 −1
Original line number Diff line number Diff line
@@ -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 *);