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:
Родитель
0bbf0a88fa
Коммит
70d188041e
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче