Skip to content

Commit a22e48c

Browse files
committed
Merge tag 'tty-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here is the big tty/serial driver update for 4.18-rc1. There's nothing major here, just lots of serial driver updates. Full details are in the shortlog, nothing anything specific to call out here. All have been in linux-next for a while with no reported issues" * tag 'tty-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (55 commits) vt: Perform safe console erase only once serial: imx: disable UCR4_OREN on shutdown serial: imx: drop CTS/RTS handling from shutdown tty: fix typo in ASYNCB_FOURPORT comment serial: samsung: check DMA engine capabilities before using DMA mode tty: Fix data race in tty_insert_flip_string_fixed_flag tty: serial: msm_geni_serial: Fix TX infinite loop serial: 8250_dw: Fix runtime PM handling serial: 8250: omap: Fix idling of clocks for unused uarts tty: serial: drop ATH79 specific SoC symbols serial: 8250: Add missing rxtrig_bytes on Altera 16550 UART serial/aspeed-vuart: fix a couple mod_timer() calls serial: sh-sci: Use spin_{try}lock_irqsave instead of open coding version serial: 8250_of: Add IO space support tty/serial: atmel: use port->name as name in request_irq() serial: imx: dma_unmap_sg buffers on shutdown serial: imx: cleanup imx_uart_disable_dma() tty: serial: qcom_geni_serial: Add early console support tty: serial: qcom_geni_serial: Return IRQ_NONE for spurious interrupts tty: serial: qcom_geni_serial: Use iowrite32_rep to write to FIFO ...
2 parents ec064d3 + 4b4ecd9 commit a22e48c

31 files changed

+694
-297
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,12 @@
10201020
address. The serial port must already be setup
10211021
and configured. Options are not yet supported.
10221022

1023+
qcom_geni,<addr>
1024+
Start an early, polled-mode console on a Qualcomm
1025+
Generic Interface (GENI) based serial port at the
1026+
specified address. The serial port must already be
1027+
setup and configured. Options are not yet supported.
1028+
10231029
earlyprintk= [X86,SH,ARM,M68k,S390]
10241030
earlyprintk=vga
10251031
earlyprintk=efi

arch/arm/boot/dts/armada-38x.dtsi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@
163163
};
164164

165165
uart0: serial@12000 {
166-
compatible = "snps,dw-apb-uart";
166+
compatible = "marvell,armada-38x-uart";
167167
reg = <0x12000 0x100>;
168168
reg-shift = <2>;
169169
interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
@@ -173,7 +173,7 @@
173173
};
174174

175175
uart1: serial@12100 {
176-
compatible = "snps,dw-apb-uart";
176+
compatible = "marvell,armada-38x-uart";
177177
reg = <0x12100 0x100>;
178178
reg-shift = <2>;
179179
interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;

drivers/tty/ipwireless/network.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ void ipwireless_network_packet_received(struct ipw_network *network,
416416
struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw)
417417
{
418418
struct ipw_network *network =
419-
kzalloc(sizeof(struct ipw_network), GFP_ATOMIC);
419+
kzalloc(sizeof(struct ipw_network), GFP_KERNEL);
420420

421421
if (!network)
422422
return NULL;

drivers/tty/n_gsm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,7 @@ static inline void muxnet_put(struct gsm_mux_net *mux_net)
26752675
kref_put(&mux_net->ref, net_free);
26762676
}
26772677

2678-
static int gsm_mux_net_start_xmit(struct sk_buff *skb,
2678+
static netdev_tx_t gsm_mux_net_start_xmit(struct sk_buff *skb,
26792679
struct net_device *net)
26802680
{
26812681
struct gsm_mux_net *mux_net = netdev_priv(net);

drivers/tty/nozomi.c

Lines changed: 52 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,19 @@ do { \
7272

7373
#define TMP_BUF_MAX 256
7474

75-
#define DUMP(buf__,len__) \
76-
do { \
77-
char tbuf[TMP_BUF_MAX] = {0};\
78-
if (len__ > 1) {\
79-
snprintf(tbuf, len__ > TMP_BUF_MAX ? TMP_BUF_MAX : len__, "%s", buf__);\
80-
if (tbuf[len__-2] == '\r') {\
81-
tbuf[len__-2] = 'r';\
82-
} \
83-
DBG1("SENDING: '%s' (%d+n)", tbuf, len__);\
84-
} else {\
85-
DBG1("SENDING: '%s' (%d)", tbuf, len__);\
86-
} \
87-
} while (0)
75+
#define DUMP(buf__, len__) \
76+
do { \
77+
char tbuf[TMP_BUF_MAX] = {0}; \
78+
if (len__ > 1) { \
79+
u32 data_len = min_t(u32, len__, TMP_BUF_MAX); \
80+
strscpy(tbuf, buf__, data_len); \
81+
if (tbuf[data_len - 2] == '\r') \
82+
tbuf[data_len - 2] = 'r'; \
83+
DBG1("SENDING: '%s' (%d+n)", tbuf, len__); \
84+
} else { \
85+
DBG1("SENDING: '%s' (%d)", tbuf, len__); \
86+
} \
87+
} while (0)
8888

8989
/* Defines */
9090
#define NOZOMI_NAME "nozomi"
@@ -102,41 +102,41 @@ do { \
102102
#define RECEIVE_BUF_MAX 4
103103

104104

105-
#define R_IIR 0x0000 /* Interrupt Identity Register */
106-
#define R_FCR 0x0000 /* Flow Control Register */
107-
#define R_IER 0x0004 /* Interrupt Enable Register */
105+
#define R_IIR 0x0000 /* Interrupt Identity Register */
106+
#define R_FCR 0x0000 /* Flow Control Register */
107+
#define R_IER 0x0004 /* Interrupt Enable Register */
108108

109109
#define NOZOMI_CONFIG_MAGIC 0xEFEFFEFE
110110
#define TOGGLE_VALID 0x0000
111111

112112
/* Definition of interrupt tokens */
113-
#define MDM_DL1 0x0001
114-
#define MDM_UL1 0x0002
115-
#define MDM_DL2 0x0004
116-
#define MDM_UL2 0x0008
117-
#define DIAG_DL1 0x0010
118-
#define DIAG_DL2 0x0020
119-
#define DIAG_UL 0x0040
120-
#define APP1_DL 0x0080
121-
#define APP1_UL 0x0100
122-
#define APP2_DL 0x0200
123-
#define APP2_UL 0x0400
124-
#define CTRL_DL 0x0800
125-
#define CTRL_UL 0x1000
126-
#define RESET 0x8000
127-
128-
#define MDM_DL (MDM_DL1 | MDM_DL2)
129-
#define MDM_UL (MDM_UL1 | MDM_UL2)
130-
#define DIAG_DL (DIAG_DL1 | DIAG_DL2)
113+
#define MDM_DL1 0x0001
114+
#define MDM_UL1 0x0002
115+
#define MDM_DL2 0x0004
116+
#define MDM_UL2 0x0008
117+
#define DIAG_DL1 0x0010
118+
#define DIAG_DL2 0x0020
119+
#define DIAG_UL 0x0040
120+
#define APP1_DL 0x0080
121+
#define APP1_UL 0x0100
122+
#define APP2_DL 0x0200
123+
#define APP2_UL 0x0400
124+
#define CTRL_DL 0x0800
125+
#define CTRL_UL 0x1000
126+
#define RESET 0x8000
127+
128+
#define MDM_DL (MDM_DL1 | MDM_DL2)
129+
#define MDM_UL (MDM_UL1 | MDM_UL2)
130+
#define DIAG_DL (DIAG_DL1 | DIAG_DL2)
131131

132132
/* modem signal definition */
133-
#define CTRL_DSR 0x0001
134-
#define CTRL_DCD 0x0002
135-
#define CTRL_RI 0x0004
136-
#define CTRL_CTS 0x0008
133+
#define CTRL_DSR 0x0001
134+
#define CTRL_DCD 0x0002
135+
#define CTRL_RI 0x0004
136+
#define CTRL_CTS 0x0008
137137

138-
#define CTRL_DTR 0x0001
139-
#define CTRL_RTS 0x0002
138+
#define CTRL_DTR 0x0001
139+
#define CTRL_RTS 0x0002
140140

141141
#define MAX_PORT 4
142142
#define NOZOMI_MAX_PORTS 5
@@ -155,7 +155,7 @@ enum card_type {
155155

156156
/* Initialization states a card can be in */
157157
enum card_state {
158-
NOZOMI_STATE_UKNOWN = 0,
158+
NOZOMI_STATE_UNKNOWN = 0,
159159
NOZOMI_STATE_ENABLED = 1, /* pci device enabled */
160160
NOZOMI_STATE_ALLOCATED = 2, /* config setup done */
161161
NOZOMI_STATE_READY = 3, /* flowcontrols received */
@@ -365,7 +365,7 @@ struct buffer {
365365
u8 *data;
366366
} __attribute__ ((packed));
367367

368-
/* Global variables */
368+
/* Global variables */
369369
static const struct pci_device_id nozomi_pci_tbl[] = {
370370
{PCI_DEVICE(0x1931, 0x000c)}, /* Nozomi HSDPA */
371371
{},
@@ -1686,12 +1686,12 @@ static int ntty_tiocmget(struct tty_struct *tty)
16861686

16871687
/* Note: these could change under us but it is not clear this
16881688
matters if so */
1689-
return (ctrl_ul->RTS ? TIOCM_RTS : 0) |
1690-
(ctrl_ul->DTR ? TIOCM_DTR : 0) |
1691-
(ctrl_dl->DCD ? TIOCM_CAR : 0) |
1692-
(ctrl_dl->RI ? TIOCM_RNG : 0) |
1693-
(ctrl_dl->DSR ? TIOCM_DSR : 0) |
1694-
(ctrl_dl->CTS ? TIOCM_CTS : 0);
1689+
return (ctrl_ul->RTS ? TIOCM_RTS : 0)
1690+
| (ctrl_ul->DTR ? TIOCM_DTR : 0)
1691+
| (ctrl_dl->DCD ? TIOCM_CAR : 0)
1692+
| (ctrl_dl->RI ? TIOCM_RNG : 0)
1693+
| (ctrl_dl->DSR ? TIOCM_DSR : 0)
1694+
| (ctrl_dl->CTS ? TIOCM_CTS : 0);
16951695
}
16961696

16971697
/* Sets io controls parameters */
@@ -1722,10 +1722,10 @@ static int ntty_cflags_changed(struct port *port, unsigned long flags,
17221722
const struct async_icount cnow = port->tty_icount;
17231723
int ret;
17241724

1725-
ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng)) ||
1726-
((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr)) ||
1727-
((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd)) ||
1728-
((flags & TIOCM_CTS) && (cnow.cts != cprev->cts));
1725+
ret = ((flags & TIOCM_RNG) && (cnow.rng != cprev->rng))
1726+
|| ((flags & TIOCM_DSR) && (cnow.dsr != cprev->dsr))
1727+
|| ((flags & TIOCM_CD) && (cnow.dcd != cprev->dcd))
1728+
|| ((flags & TIOCM_CTS) && (cnow.cts != cprev->cts));
17291729

17301730
*cprev = cnow;
17311731

drivers/tty/pty.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,19 @@ static void pty_unthrottle(struct tty_struct *tty)
110110
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
111111
{
112112
struct tty_struct *to = tty->link;
113+
unsigned long flags;
113114

114115
if (tty->stopped)
115116
return 0;
116117

117118
if (c > 0) {
119+
spin_lock_irqsave(&to->port->lock, flags);
118120
/* Stuff the data into the input queue of the other end */
119121
c = tty_insert_flip_string(to->port, buf, c);
120122
/* And shovel */
121123
if (c)
122124
tty_flip_buffer_push(to->port);
125+
spin_unlock_irqrestore(&to->port->lock, flags);
123126
}
124127
return c;
125128
}

drivers/tty/serial/8250/8250_aspeed_vuart.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/of_address.h>
1111
#include <linux/of_irq.h>
1212
#include <linux/of_platform.h>
13+
#include <linux/tty.h>
14+
#include <linux/tty_flip.h>
1315
#include <linux/clk.h>
1416

1517
#include "8250.h"
@@ -28,8 +30,17 @@ struct aspeed_vuart {
2830
void __iomem *regs;
2931
struct clk *clk;
3032
int line;
33+
struct timer_list unthrottle_timer;
34+
struct uart_8250_port *port;
3135
};
3236

37+
/*
38+
* If we fill the tty flip buffers, we throttle the data ready interrupt
39+
* to prevent dropped characters. This timeout defines how long we wait
40+
* to (conditionally, depending on buffer state) unthrottle.
41+
*/
42+
static const int unthrottle_timeout = HZ/10;
43+
3344
/*
3445
* The VUART is basically two UART 'front ends' connected by their FIFO
3546
* (no actual serial line in between). One is on the BMC side (management
@@ -179,6 +190,114 @@ static void aspeed_vuart_shutdown(struct uart_port *uart_port)
179190
serial8250_do_shutdown(uart_port);
180191
}
181192

193+
static void __aspeed_vuart_set_throttle(struct uart_8250_port *up,
194+
bool throttle)
195+
{
196+
unsigned char irqs = UART_IER_RLSI | UART_IER_RDI;
197+
198+
up->ier &= ~irqs;
199+
if (!throttle)
200+
up->ier |= irqs;
201+
serial_out(up, UART_IER, up->ier);
202+
}
203+
static void aspeed_vuart_set_throttle(struct uart_port *port, bool throttle)
204+
{
205+
struct uart_8250_port *up = up_to_u8250p(port);
206+
unsigned long flags;
207+
208+
spin_lock_irqsave(&port->lock, flags);
209+
__aspeed_vuart_set_throttle(up, throttle);
210+
spin_unlock_irqrestore(&port->lock, flags);
211+
}
212+
213+
static void aspeed_vuart_throttle(struct uart_port *port)
214+
{
215+
aspeed_vuart_set_throttle(port, true);
216+
}
217+
218+
static void aspeed_vuart_unthrottle(struct uart_port *port)
219+
{
220+
aspeed_vuart_set_throttle(port, false);
221+
}
222+
223+
static void aspeed_vuart_unthrottle_exp(struct timer_list *timer)
224+
{
225+
struct aspeed_vuart *vuart = from_timer(vuart, timer, unthrottle_timer);
226+
struct uart_8250_port *up = vuart->port;
227+
228+
if (!tty_buffer_space_avail(&up->port.state->port)) {
229+
mod_timer(&vuart->unthrottle_timer,
230+
jiffies + unthrottle_timeout);
231+
return;
232+
}
233+
234+
aspeed_vuart_unthrottle(&up->port);
235+
}
236+
237+
/*
238+
* Custom interrupt handler to manage finer-grained flow control. Although we
239+
* have throttle/unthrottle callbacks, we've seen that the VUART device can
240+
* deliver characters faster than the ldisc has a chance to check buffer space
241+
* against the throttle threshold. This results in dropped characters before
242+
* the throttle.
243+
*
244+
* We do this by checking for flip buffer space before RX. If we have no space,
245+
* throttle now and schedule an unthrottle for later, once the ldisc has had
246+
* a chance to drain the buffers.
247+
*/
248+
static int aspeed_vuart_handle_irq(struct uart_port *port)
249+
{
250+
struct uart_8250_port *up = up_to_u8250p(port);
251+
unsigned int iir, lsr;
252+
unsigned long flags;
253+
int space, count;
254+
255+
iir = serial_port_in(port, UART_IIR);
256+
257+
if (iir & UART_IIR_NO_INT)
258+
return 0;
259+
260+
spin_lock_irqsave(&port->lock, flags);
261+
262+
lsr = serial_port_in(port, UART_LSR);
263+
264+
if (lsr & (UART_LSR_DR | UART_LSR_BI)) {
265+
space = tty_buffer_space_avail(&port->state->port);
266+
267+
if (!space) {
268+
/* throttle and schedule an unthrottle later */
269+
struct aspeed_vuart *vuart = port->private_data;
270+
__aspeed_vuart_set_throttle(up, true);
271+
272+
if (!timer_pending(&vuart->unthrottle_timer)) {
273+
vuart->port = up;
274+
mod_timer(&vuart->unthrottle_timer,
275+
jiffies + unthrottle_timeout);
276+
}
277+
278+
} else {
279+
count = min(space, 256);
280+
281+
do {
282+
serial8250_read_char(up, lsr);
283+
lsr = serial_in(up, UART_LSR);
284+
if (--count == 0)
285+
break;
286+
} while (lsr & (UART_LSR_DR | UART_LSR_BI));
287+
288+
tty_flip_buffer_push(&port->state->port);
289+
}
290+
}
291+
292+
serial8250_modem_status(up);
293+
if (lsr & UART_LSR_THRE)
294+
serial8250_tx_chars(up);
295+
296+
spin_unlock_irqrestore(&port->lock, flags);
297+
298+
return 1;
299+
}
300+
182301
static int aspeed_vuart_probe(struct platform_device *pdev)
183302
{
184303
struct uart_8250_port port;
@@ -195,6 +314,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
195314
return -ENOMEM;
196315

197316
vuart->dev = &pdev->dev;
317+
timer_setup(&vuart->unthrottle_timer, aspeed_vuart_unthrottle_exp, 0);
198318

199319
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
200320
vuart->regs = devm_ioremap_resource(&pdev->dev, res);
@@ -208,6 +328,9 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
208328
port.port.mapsize = resource_size(res);
209329
port.port.startup = aspeed_vuart_startup;
210330
port.port.shutdown = aspeed_vuart_shutdown;
331+
port.port.throttle = aspeed_vuart_throttle;
332+
port.port.unthrottle = aspeed_vuart_unthrottle;
333+
port.port.status = UPSTAT_SYNC_FIFO;
211334
port.port.dev = &pdev->dev;
212335

213336
rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
@@ -253,6 +376,7 @@ static int aspeed_vuart_probe(struct platform_device *pdev)
253376

254377
port.port.irq = irq_of_parse_and_map(np, 0);
255378
port.port.irqflags = IRQF_SHARED;
379+
port.port.handle_irq = aspeed_vuart_handle_irq;
256380
port.port.iotype = UPIO_MEM;
257381
port.port.type = PORT_16550A;
258382
port.port.uartclk = clk;
@@ -292,6 +416,7 @@ static int aspeed_vuart_remove(struct platform_device *pdev)
292416
{
293417
struct aspeed_vuart *vuart = platform_get_drvdata(pdev);
294418

419+
del_timer_sync(&vuart->unthrottle_timer);
295420
aspeed_vuart_set_enabled(vuart, false);
296421
serial8250_unregister_port(vuart->line);
297422
sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);

0 commit comments

Comments
 (0)