1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include <common.h>
#include <serdev.h>
static void serdev_device_poller(void *context)
{
struct serdev_device *serdev = context;
struct console_device *cdev = to_console_device(serdev);
unsigned char *buf = serdev->buf;
int ret, len;
/*
* Since this callback is a part of poller infrastructure we
* want to use _non_interruptible version of the function
* below to prevent recursion from happening (regular
* console_drain will call is_timeout, which might end up
* calling this function again).
*/
len = console_drain_non_interruptible(cdev, serdev->fifo, buf,
PAGE_SIZE,
serdev->polling_window);
while (len > 0) {
ret = serdev->receive_buf(serdev, buf, len);
len -= ret;
buf += ret;
}
if (serdev->polling_interval) {
/*
* Re-schedule ourselves in 'serdev->polling_interval'
* nanoseconds
*/
poller_call_async(&serdev->poller,
serdev->polling_interval,
serdev_device_poller,
serdev);
}
}
int serdev_device_open(struct serdev_device *serdev)
{
struct console_device *cdev = to_console_device(serdev);
int ret;
if (!cdev->putc || !cdev->getc)
return -EINVAL;
if (!serdev->polling_window)
return -EINVAL;
serdev->buf = xzalloc(PAGE_SIZE);
serdev->fifo = kfifo_alloc(PAGE_SIZE);
if (!serdev->fifo)
return -ENOMEM;
ret = poller_async_register(&serdev->poller);
if (ret)
return ret;
return console_open(cdev);
}
unsigned int serdev_device_set_baudrate(struct serdev_device *serdev,
unsigned int speed)
{
struct console_device *cdev = to_console_device(serdev);
if (console_set_baudrate(cdev, speed) < 0)
return 0;
return console_get_baudrate(cdev);
}
int serdev_device_write(struct serdev_device *serdev, const unsigned char *buf,
size_t count, unsigned long timeout)
{
struct console_device *cdev = to_console_device(serdev);
while (count--)
cdev->putc(cdev, *buf++);
/*
* Poll Rx once right after we just send some data in case our
* serdev device implements command/response type of a
* protocol and we need to start draining input as soon as
* possible.
*/
serdev_device_poller(serdev);
return 0;
}
|