-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlinux-4wire-pps.patch
129 lines (120 loc) · 4.02 KB
/
linux-4wire-pps.patch
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
diff -rNup linux-4.13.orig/drivers/tty/serial/serial_core.c linux-4.13/drivers/tty/serial/serial_core.c
--- linux-4.13.orig/drivers/tty/serial/serial_core.c 2017-09-03 22:56:17.000000000 +0200
+++ linux-4.13/drivers/tty/serial/serial_core.c 2017-10-10 11:58:02.259478128 +0200
@@ -2664,6 +2664,56 @@ static ssize_t uart_get_attr_iomem_reg_s
return snprintf(buf, PAGE_SIZE, "%d\n", tmp.iomem_reg_shift);
}
+static ssize_t uart_get_attr_pps_4wire(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct tty_port *port = dev_get_drvdata(dev);
+ struct uart_state *state = container_of(port, struct uart_state, port);
+ struct uart_port *uport;
+ int mode = 0;
+
+ mutex_lock(&port->mutex);
+ uport = uart_port_check(state);
+ if (!uport)
+ goto out;
+
+ mode = uport->pps_4wire;
+
+out:
+ mutex_unlock(&port->mutex);
+ return snprintf(buf, PAGE_SIZE, mode ? "yes" : "no");
+}
+
+static ssize_t uart_set_attr_pps_4wire(struct device *dev,
+ struct device_attribute *attr, const char *buf,size_t count)
+{
+ struct tty_port *port = dev_get_drvdata(dev);
+ struct uart_state *state = container_of(port, struct uart_state, port);
+ struct uart_port *uport;
+ bool mode;
+ int ret;
+
+ if (!count)
+ return -EINVAL;
+
+ ret = kstrtobool(buf, &mode);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&port->mutex);
+ uport = uart_port_check(state);
+ if (!uport)
+ goto out;
+
+ spin_lock_irq(&uport->lock);
+ uport->pps_4wire = mode;
+ spin_unlock_irq(&uport->lock);
+
+out:
+ mutex_unlock(&port->mutex);
+ return count;
+}
+
static DEVICE_ATTR(type, S_IRUSR | S_IRGRP, uart_get_attr_type, NULL);
static DEVICE_ATTR(line, S_IRUSR | S_IRGRP, uart_get_attr_line, NULL);
static DEVICE_ATTR(port, S_IRUSR | S_IRGRP, uart_get_attr_port, NULL);
@@ -2677,6 +2727,7 @@ static DEVICE_ATTR(custom_divisor, S_IRU
static DEVICE_ATTR(io_type, S_IRUSR | S_IRGRP, uart_get_attr_io_type, NULL);
static DEVICE_ATTR(iomem_base, S_IRUSR | S_IRGRP, uart_get_attr_iomem_base, NULL);
static DEVICE_ATTR(iomem_reg_shift, S_IRUSR | S_IRGRP, uart_get_attr_iomem_reg_shift, NULL);
+static DEVICE_ATTR(pps_4wire, S_IRUSR | S_IWUSR | S_IRGRP, uart_get_attr_pps_4wire, uart_set_attr_pps_4wire);
static struct attribute *tty_dev_attrs[] = {
&dev_attr_type.attr,
@@ -2692,6 +2743,7 @@ static struct attribute *tty_dev_attrs[]
&dev_attr_io_type.attr,
&dev_attr_iomem_base.attr,
&dev_attr_iomem_reg_shift.attr,
+ &dev_attr_pps_4wire.attr,
NULL,
};
@@ -2748,6 +2800,9 @@ int uart_add_one_port(struct uart_driver
goto out;
}
+ /* assert that pps handling is done via DCD as default */
+ uport->pps_4wire = 0;
+
/*
* If this port is a console, then the spinlock is already
* initialised.
@@ -2923,7 +2978,7 @@ void uart_handle_dcd_change(struct uart_
lockdep_assert_held_once(&uport->lock);
- if (tty) {
+ if (tty && !uport->pps_4wire) {
ld = tty_ldisc_ref(tty);
if (ld) {
if (ld->ops->dcd_change)
@@ -2952,8 +3007,21 @@ EXPORT_SYMBOL_GPL(uart_handle_dcd_change
*/
void uart_handle_cts_change(struct uart_port *uport, unsigned int status)
{
+ struct tty_port *port = &uport->state->port;
+ struct tty_struct *tty = port->tty;
+ struct tty_ldisc *ld;
+
lockdep_assert_held_once(&uport->lock);
+ if (tty && uport->pps_4wire) {
+ ld = tty_ldisc_ref(tty);
+ if (ld) {
+ if (ld->ops->dcd_change)
+ ld->ops->dcd_change(tty, status);
+ tty_ldisc_deref(ld);
+ }
+ }
+
uport->icount.cts++;
if (uart_softcts_mode(uport)) {
diff -rNup linux-4.13.orig/include/linux/serial_core.h linux-4.13/include/linux/serial_core.h
--- linux-4.13.orig/include/linux/serial_core.h 2017-09-03 22:56:17.000000000 +0200
+++ linux-4.13/include/linux/serial_core.h 2017-10-10 11:58:02.257478108 +0200
@@ -144,7 +144,7 @@ struct uart_port {
unsigned char x_char; /* xon/xoff char */
unsigned char regshift; /* reg offset shift */
unsigned char iotype; /* io access style */
- unsigned char unused1;
+ unsigned char pps_4wire; /* CTS instead of DCD */
#define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
#define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */