11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * linux/drivers/char/serial_core.h
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * Copyright (C) 2000 Deep Blue Solutions Ltd.
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds #ifndef LINUX_SERIAL_CORE_H
81da177e4SLinus Torvalds #define LINUX_SERIAL_CORE_H
91da177e4SLinus Torvalds
10c7ac15ceSAndy Shevchenko #include <linux/bitops.h>
11661f83a6SRussell King #include <linux/compiler.h>
123e6f8806SDouglas Anderson #include <linux/console.h>
131da177e4SLinus Torvalds #include <linux/interrupt.h>
141da177e4SLinus Torvalds #include <linux/circ_buf.h>
151da177e4SLinus Torvalds #include <linux/spinlock.h>
161da177e4SLinus Torvalds #include <linux/sched.h>
171da177e4SLinus Torvalds #include <linux/tty.h>
18e2862f6aSIngo Molnar #include <linux/mutex.h>
19b11115c1SMaciej W. Rozycki #include <linux/sysrq.h>
20607ca46eSDavid Howells #include <uapi/linux/serial_core.h>
211da177e4SLinus Torvalds
22cf0ebee0SSourav Poddar #ifdef CONFIG_SERIAL_CORE_CONSOLE
23cf0ebee0SSourav Poddar #define uart_console(port) \
24cf0ebee0SSourav Poddar ((port)->cons && (port)->cons->index == (port)->line)
25cf0ebee0SSourav Poddar #else
266b3cddccSPeter Hurley #define uart_console(port) ({ (void)port; 0; })
27cf0ebee0SSourav Poddar #endif
28cf0ebee0SSourav Poddar
291da177e4SLinus Torvalds struct uart_port;
301da177e4SLinus Torvalds struct serial_struct;
3184a9582fSTony Lindgren struct serial_port_device;
321da177e4SLinus Torvalds struct device;
33167cbce2SJohan Hovold struct gpio_desc;
341da177e4SLinus Torvalds
35e60a7233SJiri Slaby /**
36e60a7233SJiri Slaby * struct uart_ops -- interface between serial_core and the driver
37e60a7233SJiri Slaby *
38e759d7c5SKevin Cernekee * This structure describes all the operations that can be done on the
39e60a7233SJiri Slaby * physical hardware.
40e60a7233SJiri Slaby *
41e60a7233SJiri Slaby * @tx_empty: ``unsigned int ()(struct uart_port *port)``
42e60a7233SJiri Slaby *
43e60a7233SJiri Slaby * This function tests whether the transmitter fifo and shifter for the
44e60a7233SJiri Slaby * @port is empty. If it is empty, this function should return
45e60a7233SJiri Slaby * %TIOCSER_TEMT, otherwise return 0. If the port does not support this
46e60a7233SJiri Slaby * operation, then it should return %TIOCSER_TEMT.
47e60a7233SJiri Slaby *
48e60a7233SJiri Slaby * Locking: none.
49e60a7233SJiri Slaby * Interrupts: caller dependent.
50e60a7233SJiri Slaby * This call must not sleep
51e60a7233SJiri Slaby *
52e60a7233SJiri Slaby * @set_mctrl: ``void ()(struct uart_port *port, unsigned int mctrl)``
53e60a7233SJiri Slaby *
54e60a7233SJiri Slaby * This function sets the modem control lines for @port to the state
55e60a7233SJiri Slaby * described by @mctrl. The relevant bits of @mctrl are:
56e60a7233SJiri Slaby *
57e60a7233SJiri Slaby * - %TIOCM_RTS RTS signal.
58e60a7233SJiri Slaby * - %TIOCM_DTR DTR signal.
59e60a7233SJiri Slaby * - %TIOCM_OUT1 OUT1 signal.
60e60a7233SJiri Slaby * - %TIOCM_OUT2 OUT2 signal.
61e60a7233SJiri Slaby * - %TIOCM_LOOP Set the port into loopback mode.
62e60a7233SJiri Slaby *
63e60a7233SJiri Slaby * If the appropriate bit is set, the signal should be driven
64e60a7233SJiri Slaby * active. If the bit is clear, the signal should be driven
65e60a7233SJiri Slaby * inactive.
66e60a7233SJiri Slaby *
67e60a7233SJiri Slaby * Locking: @port->lock taken.
68e60a7233SJiri Slaby * Interrupts: locally disabled.
69e60a7233SJiri Slaby * This call must not sleep
70e60a7233SJiri Slaby *
71e60a7233SJiri Slaby * @get_mctrl: ``unsigned int ()(struct uart_port *port)``
72e60a7233SJiri Slaby *
73e60a7233SJiri Slaby * Returns the current state of modem control inputs of @port. The state
74e60a7233SJiri Slaby * of the outputs should not be returned, since the core keeps track of
75e60a7233SJiri Slaby * their state. The state information should include:
76e60a7233SJiri Slaby *
77e60a7233SJiri Slaby * - %TIOCM_CAR state of DCD signal
78e60a7233SJiri Slaby * - %TIOCM_CTS state of CTS signal
79e60a7233SJiri Slaby * - %TIOCM_DSR state of DSR signal
80e60a7233SJiri Slaby * - %TIOCM_RI state of RI signal
81e60a7233SJiri Slaby *
82e60a7233SJiri Slaby * The bit is set if the signal is currently driven active. If
83e60a7233SJiri Slaby * the port does not support CTS, DCD or DSR, the driver should
84e60a7233SJiri Slaby * indicate that the signal is permanently active. If RI is
85e60a7233SJiri Slaby * not available, the signal should not be indicated as active.
86e60a7233SJiri Slaby *
87e60a7233SJiri Slaby * Locking: @port->lock taken.
88e60a7233SJiri Slaby * Interrupts: locally disabled.
89e60a7233SJiri Slaby * This call must not sleep
90e60a7233SJiri Slaby *
91e60a7233SJiri Slaby * @stop_tx: ``void ()(struct uart_port *port)``
92e60a7233SJiri Slaby *
93e60a7233SJiri Slaby * Stop transmitting characters. This might be due to the CTS line
94e60a7233SJiri Slaby * becoming inactive or the tty layer indicating we want to stop
95e60a7233SJiri Slaby * transmission due to an %XOFF character.
96e60a7233SJiri Slaby *
97e60a7233SJiri Slaby * The driver should stop transmitting characters as soon as possible.
98e60a7233SJiri Slaby *
99e60a7233SJiri Slaby * Locking: @port->lock taken.
100e60a7233SJiri Slaby * Interrupts: locally disabled.
101e60a7233SJiri Slaby * This call must not sleep
102e60a7233SJiri Slaby *
103e60a7233SJiri Slaby * @start_tx: ``void ()(struct uart_port *port)``
104e60a7233SJiri Slaby *
105e60a7233SJiri Slaby * Start transmitting characters.
106e60a7233SJiri Slaby *
107e60a7233SJiri Slaby * Locking: @port->lock taken.
108e60a7233SJiri Slaby * Interrupts: locally disabled.
109e60a7233SJiri Slaby * This call must not sleep
110e60a7233SJiri Slaby *
111e60a7233SJiri Slaby * @throttle: ``void ()(struct uart_port *port)``
112e60a7233SJiri Slaby *
113e60a7233SJiri Slaby * Notify the serial driver that input buffers for the line discipline are
114e60a7233SJiri Slaby * close to full, and it should somehow signal that no more characters
115e60a7233SJiri Slaby * should be sent to the serial port.
116e60a7233SJiri Slaby * This will be called only if hardware assisted flow control is enabled.
117e60a7233SJiri Slaby *
118e60a7233SJiri Slaby * Locking: serialized with @unthrottle() and termios modification by the
119e60a7233SJiri Slaby * tty layer.
120e60a7233SJiri Slaby *
121e60a7233SJiri Slaby * @unthrottle: ``void ()(struct uart_port *port)``
122e60a7233SJiri Slaby *
123e60a7233SJiri Slaby * Notify the serial driver that characters can now be sent to the serial
124e60a7233SJiri Slaby * port without fear of overrunning the input buffers of the line
125e60a7233SJiri Slaby * disciplines.
126e60a7233SJiri Slaby *
127e60a7233SJiri Slaby * This will be called only if hardware assisted flow control is enabled.
128e60a7233SJiri Slaby *
129e60a7233SJiri Slaby * Locking: serialized with @throttle() and termios modification by the
130e60a7233SJiri Slaby * tty layer.
131e60a7233SJiri Slaby *
132e60a7233SJiri Slaby * @send_xchar: ``void ()(struct uart_port *port, char ch)``
133e60a7233SJiri Slaby *
134e60a7233SJiri Slaby * Transmit a high priority character, even if the port is stopped. This
135e60a7233SJiri Slaby * is used to implement XON/XOFF flow control and tcflow(). If the serial
136e60a7233SJiri Slaby * driver does not implement this function, the tty core will append the
137e60a7233SJiri Slaby * character to the circular buffer and then call start_tx() / stop_tx()
138e60a7233SJiri Slaby * to flush the data out.
139e60a7233SJiri Slaby *
140e60a7233SJiri Slaby * Do not transmit if @ch == '\0' (%__DISABLED_CHAR).
141e60a7233SJiri Slaby *
142e60a7233SJiri Slaby * Locking: none.
143e60a7233SJiri Slaby * Interrupts: caller dependent.
144e60a7233SJiri Slaby *
145b5a5b9d5SMauro Carvalho Chehab * @start_rx: ``void ()(struct uart_port *port)``
146b5a5b9d5SMauro Carvalho Chehab *
147b5a5b9d5SMauro Carvalho Chehab * Start receiving characters.
148b5a5b9d5SMauro Carvalho Chehab *
149b5a5b9d5SMauro Carvalho Chehab * Locking: @port->lock taken.
150b5a5b9d5SMauro Carvalho Chehab * Interrupts: locally disabled.
151b5a5b9d5SMauro Carvalho Chehab * This call must not sleep
152b5a5b9d5SMauro Carvalho Chehab *
153e60a7233SJiri Slaby * @stop_rx: ``void ()(struct uart_port *port)``
154e60a7233SJiri Slaby *
155e60a7233SJiri Slaby * Stop receiving characters; the @port is in the process of being closed.
156e60a7233SJiri Slaby *
157e60a7233SJiri Slaby * Locking: @port->lock taken.
158e60a7233SJiri Slaby * Interrupts: locally disabled.
159e60a7233SJiri Slaby * This call must not sleep
160e60a7233SJiri Slaby *
161e60a7233SJiri Slaby * @enable_ms: ``void ()(struct uart_port *port)``
162e60a7233SJiri Slaby *
163e60a7233SJiri Slaby * Enable the modem status interrupts.
164e60a7233SJiri Slaby *
165e60a7233SJiri Slaby * This method may be called multiple times. Modem status interrupts
166e60a7233SJiri Slaby * should be disabled when the @shutdown() method is called.
167e60a7233SJiri Slaby *
168e60a7233SJiri Slaby * Locking: @port->lock taken.
169e60a7233SJiri Slaby * Interrupts: locally disabled.
170e60a7233SJiri Slaby * This call must not sleep
171e60a7233SJiri Slaby *
172e60a7233SJiri Slaby * @break_ctl: ``void ()(struct uart_port *port, int ctl)``
173e60a7233SJiri Slaby *
174e60a7233SJiri Slaby * Control the transmission of a break signal. If @ctl is nonzero, the
175e60a7233SJiri Slaby * break signal should be transmitted. The signal should be terminated
176e60a7233SJiri Slaby * when another call is made with a zero @ctl.
177e60a7233SJiri Slaby *
178e60a7233SJiri Slaby * Locking: caller holds tty_port->mutex
179e60a7233SJiri Slaby *
180e60a7233SJiri Slaby * @startup: ``int ()(struct uart_port *port)``
181e60a7233SJiri Slaby *
182e60a7233SJiri Slaby * Grab any interrupt resources and initialise any low level driver state.
183e60a7233SJiri Slaby * Enable the port for reception. It should not activate RTS nor DTR;
184e60a7233SJiri Slaby * this will be done via a separate call to @set_mctrl().
185e60a7233SJiri Slaby *
186e60a7233SJiri Slaby * This method will only be called when the port is initially opened.
187e60a7233SJiri Slaby *
188e60a7233SJiri Slaby * Locking: port_sem taken.
189e60a7233SJiri Slaby * Interrupts: globally disabled.
190e60a7233SJiri Slaby *
191e60a7233SJiri Slaby * @shutdown: ``void ()(struct uart_port *port)``
192e60a7233SJiri Slaby *
193e60a7233SJiri Slaby * Disable the @port, disable any break condition that may be in effect,
194e60a7233SJiri Slaby * and free any interrupt resources. It should not disable RTS nor DTR;
195e60a7233SJiri Slaby * this will have already been done via a separate call to @set_mctrl().
196e60a7233SJiri Slaby *
197e60a7233SJiri Slaby * Drivers must not access @port->state once this call has completed.
198e60a7233SJiri Slaby *
199e60a7233SJiri Slaby * This method will only be called when there are no more users of this
200e60a7233SJiri Slaby * @port.
201e60a7233SJiri Slaby *
202e60a7233SJiri Slaby * Locking: port_sem taken.
203e60a7233SJiri Slaby * Interrupts: caller dependent.
204e60a7233SJiri Slaby *
205e60a7233SJiri Slaby * @flush_buffer: ``void ()(struct uart_port *port)``
206e60a7233SJiri Slaby *
207e60a7233SJiri Slaby * Flush any write buffers, reset any DMA state and stop any ongoing DMA
208e60a7233SJiri Slaby * transfers.
209e60a7233SJiri Slaby *
210e60a7233SJiri Slaby * This will be called whenever the @port->state->xmit circular buffer is
211e60a7233SJiri Slaby * cleared.
212e60a7233SJiri Slaby *
213e60a7233SJiri Slaby * Locking: @port->lock taken.
214e60a7233SJiri Slaby * Interrupts: locally disabled.
215e60a7233SJiri Slaby * This call must not sleep
216e60a7233SJiri Slaby *
217e60a7233SJiri Slaby * @set_termios: ``void ()(struct uart_port *port, struct ktermios *new,
218e60a7233SJiri Slaby * struct ktermios *old)``
219e60a7233SJiri Slaby *
220e60a7233SJiri Slaby * Change the @port parameters, including word length, parity, stop bits.
221e60a7233SJiri Slaby * Update @port->read_status_mask and @port->ignore_status_mask to
222e60a7233SJiri Slaby * indicate the types of events we are interested in receiving. Relevant
223e60a7233SJiri Slaby * ktermios::c_cflag bits are:
224e60a7233SJiri Slaby *
225e60a7233SJiri Slaby * - %CSIZE - word size
226e60a7233SJiri Slaby * - %CSTOPB - 2 stop bits
227e60a7233SJiri Slaby * - %PARENB - parity enable
228e60a7233SJiri Slaby * - %PARODD - odd parity (when %PARENB is in force)
229e60a7233SJiri Slaby * - %ADDRB - address bit (changed through uart_port::rs485_config()).
230e60a7233SJiri Slaby * - %CREAD - enable reception of characters (if not set, still receive
231e60a7233SJiri Slaby * characters from the port, but throw them away).
232e60a7233SJiri Slaby * - %CRTSCTS - if set, enable CTS status change reporting.
233e60a7233SJiri Slaby * - %CLOCAL - if not set, enable modem status change reporting.
234e60a7233SJiri Slaby *
235e60a7233SJiri Slaby * Relevant ktermios::c_iflag bits are:
236e60a7233SJiri Slaby *
237e60a7233SJiri Slaby * - %INPCK - enable frame and parity error events to be passed to the TTY
238e60a7233SJiri Slaby * layer.
239e60a7233SJiri Slaby * - %BRKINT / %PARMRK - both of these enable break events to be passed to
240e60a7233SJiri Slaby * the TTY layer.
241e60a7233SJiri Slaby * - %IGNPAR - ignore parity and framing errors.
242e60a7233SJiri Slaby * - %IGNBRK - ignore break errors. If %IGNPAR is also set, ignore overrun
243e60a7233SJiri Slaby * errors as well.
244e60a7233SJiri Slaby *
245e60a7233SJiri Slaby * The interaction of the ktermios::c_iflag bits is as follows (parity
246e60a7233SJiri Slaby * error given as an example):
247e60a7233SJiri Slaby *
248e60a7233SJiri Slaby * ============ ======= ======= =========================================
249e60a7233SJiri Slaby * Parity error INPCK IGNPAR
250e60a7233SJiri Slaby * ============ ======= ======= =========================================
251e60a7233SJiri Slaby * n/a 0 n/a character received, marked as %TTY_NORMAL
252e60a7233SJiri Slaby * None 1 n/a character received, marked as %TTY_NORMAL
253e60a7233SJiri Slaby * Yes 1 0 character received, marked as %TTY_PARITY
254e60a7233SJiri Slaby * Yes 1 1 character discarded
255e60a7233SJiri Slaby * ============ ======= ======= =========================================
256e60a7233SJiri Slaby *
257e60a7233SJiri Slaby * Other flags may be used (eg, xon/xoff characters) if your hardware
258e60a7233SJiri Slaby * supports hardware "soft" flow control.
259e60a7233SJiri Slaby *
260e60a7233SJiri Slaby * Locking: caller holds tty_port->mutex
261e60a7233SJiri Slaby * Interrupts: caller dependent.
262e60a7233SJiri Slaby * This call must not sleep
263e60a7233SJiri Slaby *
264e60a7233SJiri Slaby * @set_ldisc: ``void ()(struct uart_port *port, struct ktermios *termios)``
265e60a7233SJiri Slaby *
266e60a7233SJiri Slaby * Notifier for discipline change. See
267e60a7233SJiri Slaby * Documentation/driver-api/tty/tty_ldisc.rst.
268e60a7233SJiri Slaby *
269e60a7233SJiri Slaby * Locking: caller holds tty_port->mutex
270e60a7233SJiri Slaby *
271e60a7233SJiri Slaby * @pm: ``void ()(struct uart_port *port, unsigned int state,
272e60a7233SJiri Slaby * unsigned int oldstate)``
273e60a7233SJiri Slaby *
274e60a7233SJiri Slaby * Perform any power management related activities on the specified @port.
275e60a7233SJiri Slaby * @state indicates the new state (defined by enum uart_pm_state),
276e60a7233SJiri Slaby * @oldstate indicates the previous state.
277e60a7233SJiri Slaby *
278e60a7233SJiri Slaby * This function should not be used to grab any resources.
279e60a7233SJiri Slaby *
280e60a7233SJiri Slaby * This will be called when the @port is initially opened and finally
281e60a7233SJiri Slaby * closed, except when the @port is also the system console. This will
282e60a7233SJiri Slaby * occur even if %CONFIG_PM is not set.
283e60a7233SJiri Slaby *
284e60a7233SJiri Slaby * Locking: none.
285e60a7233SJiri Slaby * Interrupts: caller dependent.
286e60a7233SJiri Slaby *
287e60a7233SJiri Slaby * @type: ``const char *()(struct uart_port *port)``
288e60a7233SJiri Slaby *
289e60a7233SJiri Slaby * Return a pointer to a string constant describing the specified @port,
290e60a7233SJiri Slaby * or return %NULL, in which case the string 'unknown' is substituted.
291e60a7233SJiri Slaby *
292e60a7233SJiri Slaby * Locking: none.
293e60a7233SJiri Slaby * Interrupts: caller dependent.
294e60a7233SJiri Slaby *
295e60a7233SJiri Slaby * @release_port: ``void ()(struct uart_port *port)``
296e60a7233SJiri Slaby *
297e60a7233SJiri Slaby * Release any memory and IO region resources currently in use by the
298e60a7233SJiri Slaby * @port.
299e60a7233SJiri Slaby *
300e60a7233SJiri Slaby * Locking: none.
301e60a7233SJiri Slaby * Interrupts: caller dependent.
302e60a7233SJiri Slaby *
303e60a7233SJiri Slaby * @request_port: ``int ()(struct uart_port *port)``
304e60a7233SJiri Slaby *
305e60a7233SJiri Slaby * Request any memory and IO region resources required by the port. If any
306e60a7233SJiri Slaby * fail, no resources should be registered when this function returns, and
307e60a7233SJiri Slaby * it should return -%EBUSY on failure.
308e60a7233SJiri Slaby *
309e60a7233SJiri Slaby * Locking: none.
310e60a7233SJiri Slaby * Interrupts: caller dependent.
311e60a7233SJiri Slaby *
312e60a7233SJiri Slaby * @config_port: ``void ()(struct uart_port *port, int type)``
313e60a7233SJiri Slaby *
314e60a7233SJiri Slaby * Perform any autoconfiguration steps required for the @port. @type
315e60a7233SJiri Slaby * contains a bit mask of the required configuration. %UART_CONFIG_TYPE
316e60a7233SJiri Slaby * indicates that the port requires detection and identification.
317e60a7233SJiri Slaby * @port->type should be set to the type found, or %PORT_UNKNOWN if no
318e60a7233SJiri Slaby * port was detected.
319e60a7233SJiri Slaby *
320e60a7233SJiri Slaby * %UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
321e60a7233SJiri Slaby * which should be probed using standard kernel autoprobing techniques.
322e60a7233SJiri Slaby * This is not necessary on platforms where ports have interrupts
323e60a7233SJiri Slaby * internally hard wired (eg, system on a chip implementations).
324e60a7233SJiri Slaby *
325e60a7233SJiri Slaby * Locking: none.
326e60a7233SJiri Slaby * Interrupts: caller dependent.
327e60a7233SJiri Slaby *
328e60a7233SJiri Slaby * @verify_port: ``int ()(struct uart_port *port,
329e60a7233SJiri Slaby * struct serial_struct *serinfo)``
330e60a7233SJiri Slaby *
331e60a7233SJiri Slaby * Verify the new serial port information contained within @serinfo is
332e60a7233SJiri Slaby * suitable for this port type.
333e60a7233SJiri Slaby *
334e60a7233SJiri Slaby * Locking: none.
335e60a7233SJiri Slaby * Interrupts: caller dependent.
336e60a7233SJiri Slaby *
337e60a7233SJiri Slaby * @ioctl: ``int ()(struct uart_port *port, unsigned int cmd,
338e60a7233SJiri Slaby * unsigned long arg)``
339e60a7233SJiri Slaby *
340e60a7233SJiri Slaby * Perform any port specific IOCTLs. IOCTL commands must be defined using
341e60a7233SJiri Slaby * the standard numbering system found in <asm/ioctl.h>.
342e60a7233SJiri Slaby *
343e60a7233SJiri Slaby * Locking: none.
344e60a7233SJiri Slaby * Interrupts: caller dependent.
345e60a7233SJiri Slaby *
346e60a7233SJiri Slaby * @poll_init: ``int ()(struct uart_port *port)``
347e60a7233SJiri Slaby *
348e60a7233SJiri Slaby * Called by kgdb to perform the minimal hardware initialization needed to
349e60a7233SJiri Slaby * support @poll_put_char() and @poll_get_char(). Unlike @startup(), this
350e60a7233SJiri Slaby * should not request interrupts.
351e60a7233SJiri Slaby *
352e60a7233SJiri Slaby * Locking: %tty_mutex and tty_port->mutex taken.
353e60a7233SJiri Slaby * Interrupts: n/a.
354e60a7233SJiri Slaby *
355e60a7233SJiri Slaby * @poll_put_char: ``void ()(struct uart_port *port, unsigned char ch)``
356e60a7233SJiri Slaby *
357e60a7233SJiri Slaby * Called by kgdb to write a single character @ch directly to the serial
358e60a7233SJiri Slaby * @port. It can and should block until there is space in the TX FIFO.
359e60a7233SJiri Slaby *
360e60a7233SJiri Slaby * Locking: none.
361e60a7233SJiri Slaby * Interrupts: caller dependent.
362e60a7233SJiri Slaby * This call must not sleep
363e60a7233SJiri Slaby *
364e60a7233SJiri Slaby * @poll_get_char: ``int ()(struct uart_port *port)``
365e60a7233SJiri Slaby *
366e60a7233SJiri Slaby * Called by kgdb to read a single character directly from the serial
367e60a7233SJiri Slaby * port. If data is available, it should be returned; otherwise the
368e60a7233SJiri Slaby * function should return %NO_POLL_CHAR immediately.
369e60a7233SJiri Slaby *
370e60a7233SJiri Slaby * Locking: none.
371e60a7233SJiri Slaby * Interrupts: caller dependent.
372e60a7233SJiri Slaby * This call must not sleep
3731da177e4SLinus Torvalds */
3741da177e4SLinus Torvalds struct uart_ops {
3751da177e4SLinus Torvalds unsigned int (*tx_empty)(struct uart_port *);
3761da177e4SLinus Torvalds void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
3771da177e4SLinus Torvalds unsigned int (*get_mctrl)(struct uart_port *);
378b129a8ccSRussell King void (*stop_tx)(struct uart_port *);
379b129a8ccSRussell King void (*start_tx)(struct uart_port *);
3809aba8d5bSRussell King void (*throttle)(struct uart_port *);
3819aba8d5bSRussell King void (*unthrottle)(struct uart_port *);
3821da177e4SLinus Torvalds void (*send_xchar)(struct uart_port *, char ch);
3831da177e4SLinus Torvalds void (*stop_rx)(struct uart_port *);
384cfab87c2SVijaya Krishna Nivarthi void (*start_rx)(struct uart_port *);
3851da177e4SLinus Torvalds void (*enable_ms)(struct uart_port *);
3861da177e4SLinus Torvalds void (*break_ctl)(struct uart_port *, int ctl);
3871da177e4SLinus Torvalds int (*startup)(struct uart_port *);
3881da177e4SLinus Torvalds void (*shutdown)(struct uart_port *);
3896bb0e3a5SHaavard Skinnemoen void (*flush_buffer)(struct uart_port *);
390606d099cSAlan Cox void (*set_termios)(struct uart_port *, struct ktermios *new,
391bec5b814SIlpo Järvinen const struct ktermios *old);
392732a84a0SPeter Hurley void (*set_ldisc)(struct uart_port *, struct ktermios *);
3931da177e4SLinus Torvalds void (*pm)(struct uart_port *, unsigned int state,
3941da177e4SLinus Torvalds unsigned int oldstate);
3951da177e4SLinus Torvalds const char *(*type)(struct uart_port *);
3961da177e4SLinus Torvalds void (*release_port)(struct uart_port *);
3971da177e4SLinus Torvalds int (*request_port)(struct uart_port *);
3981da177e4SLinus Torvalds void (*config_port)(struct uart_port *, int);
3991da177e4SLinus Torvalds int (*verify_port)(struct uart_port *, struct serial_struct *);
4001da177e4SLinus Torvalds int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
401f2d937f3SJason Wessel #ifdef CONFIG_CONSOLE_POLL
402c7f3e708SAnton Vorontsov int (*poll_init)(struct uart_port *);
403f2d937f3SJason Wessel void (*poll_put_char)(struct uart_port *, unsigned char);
404f2d937f3SJason Wessel int (*poll_get_char)(struct uart_port *);
405f2d937f3SJason Wessel #endif
4061da177e4SLinus Torvalds };
4071da177e4SLinus Torvalds
408f5316b4aSJason Wessel #define NO_POLL_CHAR 0x00ff0000
4091da177e4SLinus Torvalds #define UART_CONFIG_TYPE (1 << 0)
4101da177e4SLinus Torvalds #define UART_CONFIG_IRQ (1 << 1)
4111da177e4SLinus Torvalds
4121da177e4SLinus Torvalds struct uart_icount {
4131da177e4SLinus Torvalds __u32 cts;
4141da177e4SLinus Torvalds __u32 dsr;
4151da177e4SLinus Torvalds __u32 rng;
4161da177e4SLinus Torvalds __u32 dcd;
4171da177e4SLinus Torvalds __u32 rx;
4181da177e4SLinus Torvalds __u32 tx;
4191da177e4SLinus Torvalds __u32 frame;
4201da177e4SLinus Torvalds __u32 overrun;
4211da177e4SLinus Torvalds __u32 parity;
4221da177e4SLinus Torvalds __u32 brk;
4231da177e4SLinus Torvalds __u32 buf_overrun;
4241da177e4SLinus Torvalds };
4251da177e4SLinus Torvalds
4269906890cSMaciej W. Rozycki typedef u64 __bitwise upf_t;
4279efeccacSMichael S. Tsirkin typedef unsigned int __bitwise upstat_t;
4280077d45eSRussell King
4291da177e4SLinus Torvalds struct uart_port {
4301da177e4SLinus Torvalds spinlock_t lock; /* port lock */
4310c8946d9SDavid Miller unsigned long iobase; /* in/out[bwl] */
4321da177e4SLinus Torvalds unsigned char __iomem *membase; /* read/write[bwl] */
4337d6a07d1SDavid Daney unsigned int (*serial_in)(struct uart_port *, int);
4347d6a07d1SDavid Daney void (*serial_out)(struct uart_port *, int, int);
435235dae5dSPhilippe Langlais void (*set_termios)(struct uart_port *,
436235dae5dSPhilippe Langlais struct ktermios *new,
437bec5b814SIlpo Järvinen const struct ktermios *old);
438db405a8fSEd Blake void (*set_ldisc)(struct uart_port *,
439db405a8fSEd Blake struct ktermios *);
440144ef5c2SWan Ahmad Zainie unsigned int (*get_mctrl)(struct uart_port *);
4414bf4ea9dSPeter Hurley void (*set_mctrl)(struct uart_port *, unsigned int);
4420238d2b4SJisheng Zhang unsigned int (*get_divisor)(struct uart_port *,
4430238d2b4SJisheng Zhang unsigned int baud,
4440238d2b4SJisheng Zhang unsigned int *frac);
4450238d2b4SJisheng Zhang void (*set_divisor)(struct uart_port *,
4460238d2b4SJisheng Zhang unsigned int baud,
4470238d2b4SJisheng Zhang unsigned int quot,
4480238d2b4SJisheng Zhang unsigned int quot_frac);
449b99b121bSSebastian Andrzej Siewior int (*startup)(struct uart_port *port);
450b99b121bSSebastian Andrzej Siewior void (*shutdown)(struct uart_port *port);
451234abab1SSebastian Andrzej Siewior void (*throttle)(struct uart_port *port);
452234abab1SSebastian Andrzej Siewior void (*unthrottle)(struct uart_port *port);
453a74036f5SJamie Iles int (*handle_irq)(struct uart_port *);
454c161afe9SManuel Lauss void (*pm)(struct uart_port *, unsigned int state,
455c161afe9SManuel Lauss unsigned int old);
456bf03f65bSDan Williams void (*handle_break)(struct uart_port *);
457a5f276f1SRicardo Ribalda Delgado int (*rs485_config)(struct uart_port *,
458ae50bb27SIlpo Järvinen struct ktermios *termios,
459a5f276f1SRicardo Ribalda Delgado struct serial_rs485 *rs485);
460ad8c0eaaSNicolas Ferre int (*iso7816_config)(struct uart_port *,
461ad8c0eaaSNicolas Ferre struct serial_iso7816 *iso7816);
46283c35180STony Lindgren unsigned int ctrl_id; /* optional serial core controller id */
463d962de6aSTony Lindgren unsigned int port_id; /* optional serial core port id */
4641da177e4SLinus Torvalds unsigned int irq; /* irq number */
4651c2f0493SVikram Pandita unsigned long irqflags; /* irq flags */
4661da177e4SLinus Torvalds unsigned int uartclk; /* base uart clock */
467947deee8SRussell King unsigned int fifosize; /* tx fifo size */
4681da177e4SLinus Torvalds unsigned char x_char; /* xon/xoff char */
4691da177e4SLinus Torvalds unsigned char regshift; /* reg offset shift */
4701da177e4SLinus Torvalds unsigned char iotype; /* io access style */
471c7ac15ceSAndy Shevchenko unsigned char quirks; /* internal quirks */
4721da177e4SLinus Torvalds
473647f162bSPeter Hurley #define UPIO_PORT (SERIAL_IO_PORT) /* 8b I/O port access */
474647f162bSPeter Hurley #define UPIO_HUB6 (SERIAL_IO_HUB6) /* Hub6 ISA card */
475858965d9SPeter Hurley #define UPIO_MEM (SERIAL_IO_MEM) /* driver-specific */
476647f162bSPeter Hurley #define UPIO_MEM32 (SERIAL_IO_MEM32) /* 32b little endian */
477647f162bSPeter Hurley #define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
478647f162bSPeter Hurley #define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
479647f162bSPeter Hurley #define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
480bd94c407SMasahiro Yamada #define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */
4811da177e4SLinus Torvalds
482c7ac15ceSAndy Shevchenko /* quirks must be updated while holding port mutex */
483c7ac15ceSAndy Shevchenko #define UPQ_NO_TXEN_TEST BIT(0)
484c7ac15ceSAndy Shevchenko
4851da177e4SLinus Torvalds unsigned int read_status_mask; /* driver specific */
4861da177e4SLinus Torvalds unsigned int ignore_status_mask; /* driver specific */
487ebd2c8f6SAlan Cox struct uart_state *state; /* pointer to parent state */
4881da177e4SLinus Torvalds struct uart_icount icount; /* statistics */
4891da177e4SLinus Torvalds
4901da177e4SLinus Torvalds struct console *cons; /* struct console, if any */
4918a949b07SPeter Hurley /* flags must be updated while holding port mutex */
4920077d45eSRussell King upf_t flags;
4931da177e4SLinus Torvalds
494904326ecSPeter Hurley /*
495904326ecSPeter Hurley * These flags must be equivalent to the flags defined in
496904326ecSPeter Hurley * include/uapi/linux/tty_flags.h which are the userspace definitions
497904326ecSPeter Hurley * assigned from the serial_struct flags in uart_set_info()
498904326ecSPeter Hurley * [for bit definitions in the UPF_CHANGE_MASK]
499904326ecSPeter Hurley *
500916acbf6SAndy Shevchenko * Bits [0..ASYNCB_LAST_USER] are userspace defined/visible/changeable
501904326ecSPeter Hurley * The remaining bits are serial-core specific and not modifiable by
502904326ecSPeter Hurley * userspace.
503904326ecSPeter Hurley */
504904326ecSPeter Hurley #define UPF_FOURPORT ((__force upf_t) ASYNC_FOURPORT /* 1 */ )
505904326ecSPeter Hurley #define UPF_SAK ((__force upf_t) ASYNC_SAK /* 2 */ )
506904326ecSPeter Hurley #define UPF_SPD_HI ((__force upf_t) ASYNC_SPD_HI /* 4 */ )
507904326ecSPeter Hurley #define UPF_SPD_VHI ((__force upf_t) ASYNC_SPD_VHI /* 5 */ )
508904326ecSPeter Hurley #define UPF_SPD_CUST ((__force upf_t) ASYNC_SPD_CUST /* 0x0030 */ )
509904326ecSPeter Hurley #define UPF_SPD_WARP ((__force upf_t) ASYNC_SPD_WARP /* 0x1010 */ )
510904326ecSPeter Hurley #define UPF_SPD_MASK ((__force upf_t) ASYNC_SPD_MASK /* 0x1030 */ )
511904326ecSPeter Hurley #define UPF_SKIP_TEST ((__force upf_t) ASYNC_SKIP_TEST /* 6 */ )
512904326ecSPeter Hurley #define UPF_AUTO_IRQ ((__force upf_t) ASYNC_AUTO_IRQ /* 7 */ )
513904326ecSPeter Hurley #define UPF_HARDPPS_CD ((__force upf_t) ASYNC_HARDPPS_CD /* 11 */ )
514904326ecSPeter Hurley #define UPF_SPD_SHI ((__force upf_t) ASYNC_SPD_SHI /* 12 */ )
515904326ecSPeter Hurley #define UPF_LOW_LATENCY ((__force upf_t) ASYNC_LOW_LATENCY /* 13 */ )
516904326ecSPeter Hurley #define UPF_BUGGY_UART ((__force upf_t) ASYNC_BUGGY_UART /* 14 */ )
517904326ecSPeter Hurley #define UPF_MAGIC_MULTIPLIER ((__force upf_t) ASYNC_MAGIC_MULTIPLIER /* 16 */ )
518904326ecSPeter Hurley
51946a8973cSMaciej W. Rozycki #define UPF_NO_THRE_TEST ((__force upf_t) BIT_ULL(19))
520391f93f2SPeter Hurley /* Port has hardware-assisted h/w flow control */
52146a8973cSMaciej W. Rozycki #define UPF_AUTO_CTS ((__force upf_t) BIT_ULL(20))
52246a8973cSMaciej W. Rozycki #define UPF_AUTO_RTS ((__force upf_t) BIT_ULL(21))
523391f93f2SPeter Hurley #define UPF_HARD_FLOW ((__force upf_t) (UPF_AUTO_CTS | UPF_AUTO_RTS))
5242cbacafdSRussell King /* Port has hardware-assisted s/w flow control */
52546a8973cSMaciej W. Rozycki #define UPF_SOFT_FLOW ((__force upf_t) BIT_ULL(22))
52646a8973cSMaciej W. Rozycki #define UPF_CONS_FLOW ((__force upf_t) BIT_ULL(23))
52746a8973cSMaciej W. Rozycki #define UPF_SHARE_IRQ ((__force upf_t) BIT_ULL(24))
52846a8973cSMaciej W. Rozycki #define UPF_EXAR_EFR ((__force upf_t) BIT_ULL(25))
52946a8973cSMaciej W. Rozycki #define UPF_BUG_THRE ((__force upf_t) BIT_ULL(26))
5308e23fcc8SDavid Daney /* The exact UART type is known and should not be probed. */
53146a8973cSMaciej W. Rozycki #define UPF_FIXED_TYPE ((__force upf_t) BIT_ULL(27))
53246a8973cSMaciej W. Rozycki #define UPF_BOOT_AUTOCONF ((__force upf_t) BIT_ULL(28))
53346a8973cSMaciej W. Rozycki #define UPF_FIXED_PORT ((__force upf_t) BIT_ULL(29))
53446a8973cSMaciej W. Rozycki #define UPF_DEAD ((__force upf_t) BIT_ULL(30))
53546a8973cSMaciej W. Rozycki #define UPF_IOREMAP ((__force upf_t) BIT_ULL(31))
53646a8973cSMaciej W. Rozycki #define UPF_FULL_PROBE ((__force upf_t) BIT_ULL(32))
5371da177e4SLinus Torvalds
538904326ecSPeter Hurley #define __UPF_CHANGE_MASK 0x17fff
539904326ecSPeter Hurley #define UPF_CHANGE_MASK ((__force upf_t) __UPF_CHANGE_MASK)
5400077d45eSRussell King #define UPF_USR_MASK ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
5411da177e4SLinus Torvalds
542904326ecSPeter Hurley #if __UPF_CHANGE_MASK > ASYNC_FLAGS
543904326ecSPeter Hurley #error Change mask not equivalent to userspace-visible bit defines
544904326ecSPeter Hurley #endif
545904326ecSPeter Hurley
546391f93f2SPeter Hurley /*
547391f93f2SPeter Hurley * Must hold termios_rwsem, port mutex and port lock to change;
548391f93f2SPeter Hurley * can hold any one lock to read.
549391f93f2SPeter Hurley */
550299245a1SPeter Hurley upstat_t status;
551299245a1SPeter Hurley
552299245a1SPeter Hurley #define UPSTAT_CTS_ENABLE ((__force upstat_t) (1 << 0))
553299245a1SPeter Hurley #define UPSTAT_DCD_ENABLE ((__force upstat_t) (1 << 1))
554391f93f2SPeter Hurley #define UPSTAT_AUTORTS ((__force upstat_t) (1 << 2))
555391f93f2SPeter Hurley #define UPSTAT_AUTOCTS ((__force upstat_t) (1 << 3))
556391f93f2SPeter Hurley #define UPSTAT_AUTOXOFF ((__force upstat_t) (1 << 4))
557c5f78b1fSJeremy Kerr #define UPSTAT_SYNC_FIFO ((__force upstat_t) (1 << 5))
558299245a1SPeter Hurley
559b5def43aSIlpo Järvinen bool hw_stopped; /* sw-assisted CTS flow state */
5601da177e4SLinus Torvalds unsigned int mctrl; /* current modem ctrl settings */
56131f6bd7fSIlpo Järvinen unsigned int frame_time; /* frame timing in ns */
5621da177e4SLinus Torvalds unsigned int type; /* port type */
563ba899dbcSRussell King const struct uart_ops *ops;
5641da177e4SLinus Torvalds unsigned int custom_divisor;
5651da177e4SLinus Torvalds unsigned int line; /* port index */
566959801feSPeter Hurley unsigned int minor;
5674f640efbSJosh Boyer resource_size_t mapbase; /* for ioremap */
568ee97d0e3SMans Rullgard resource_size_t mapsize;
56984a9582fSTony Lindgren struct device *dev; /* serial port physical parent device */
57084a9582fSTony Lindgren struct serial_port_device *port_dev; /* serial core port device */
5717e5ed9f5SDmitry Safonov
5727e5ed9f5SDmitry Safonov unsigned long sysrq; /* sysrq timeout */
57312ae2359SJiri Slaby u8 sysrq_ch; /* char for sysrq */
5741997e9dfSDmitry Safonov unsigned char has_sysrq;
57568af4317SDmitry Safonov unsigned char sysrq_seq; /* index in sysrq_toggle_seq */
5767e5ed9f5SDmitry Safonov
5771da177e4SLinus Torvalds unsigned char hub6; /* this should be in the 8250 driver */
578b3b708faSGuennadi Liakhovetski unsigned char suspended;
579e0830dbfSJohan Hovold unsigned char console_reinit;
5802e94d5aeSAndy Shevchenko const char *name; /* port name */
581266dcff0SGreg Kroah-Hartman struct attribute_group *attr_group; /* port specific attributes */
582266dcff0SGreg Kroah-Hartman const struct attribute_group **tty_groups; /* all attributes (serial core use only) */
583a5f276f1SRicardo Ribalda Delgado struct serial_rs485 rs485;
5840139da50SIlpo Järvinen struct serial_rs485 rs485_supported; /* Supported mask for serial_rs485 */
585d58a2df3SLukas Wunner struct gpio_desc *rs485_term_gpio; /* enable RS485 bus termination */
586163f080eSChristoph Niedermaier struct gpio_desc *rs485_rx_during_tx_gpio; /* Output GPIO that sets the state of RS485 RX during TX */
587ad8c0eaaSNicolas Ferre struct serial_iso7816 iso7816;
588beab697aSMarc St-Jean void *private_data; /* generic platform data pointer */
5891da177e4SLinus Torvalds };
5901da177e4SLinus Torvalds
591984095adSThomas Gleixner /**
592984095adSThomas Gleixner * uart_port_lock - Lock the UART port
593984095adSThomas Gleixner * @up: Pointer to UART port structure
594984095adSThomas Gleixner */
uart_port_lock(struct uart_port * up)595984095adSThomas Gleixner static inline void uart_port_lock(struct uart_port *up)
596984095adSThomas Gleixner {
597984095adSThomas Gleixner spin_lock(&up->lock);
598984095adSThomas Gleixner }
599984095adSThomas Gleixner
600984095adSThomas Gleixner /**
601984095adSThomas Gleixner * uart_port_lock_irq - Lock the UART port and disable interrupts
602984095adSThomas Gleixner * @up: Pointer to UART port structure
603984095adSThomas Gleixner */
uart_port_lock_irq(struct uart_port * up)604984095adSThomas Gleixner static inline void uart_port_lock_irq(struct uart_port *up)
605984095adSThomas Gleixner {
606984095adSThomas Gleixner spin_lock_irq(&up->lock);
607984095adSThomas Gleixner }
608984095adSThomas Gleixner
609984095adSThomas Gleixner /**
610984095adSThomas Gleixner * uart_port_lock_irqsave - Lock the UART port, save and disable interrupts
611984095adSThomas Gleixner * @up: Pointer to UART port structure
612984095adSThomas Gleixner * @flags: Pointer to interrupt flags storage
613984095adSThomas Gleixner */
uart_port_lock_irqsave(struct uart_port * up,unsigned long * flags)614984095adSThomas Gleixner static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags)
615984095adSThomas Gleixner {
616984095adSThomas Gleixner spin_lock_irqsave(&up->lock, *flags);
617984095adSThomas Gleixner }
618984095adSThomas Gleixner
619984095adSThomas Gleixner /**
620984095adSThomas Gleixner * uart_port_trylock - Try to lock the UART port
621984095adSThomas Gleixner * @up: Pointer to UART port structure
622984095adSThomas Gleixner *
623984095adSThomas Gleixner * Returns: True if lock was acquired, false otherwise
624984095adSThomas Gleixner */
uart_port_trylock(struct uart_port * up)625984095adSThomas Gleixner static inline bool uart_port_trylock(struct uart_port *up)
626984095adSThomas Gleixner {
627984095adSThomas Gleixner return spin_trylock(&up->lock);
628984095adSThomas Gleixner }
629984095adSThomas Gleixner
630984095adSThomas Gleixner /**
631984095adSThomas Gleixner * uart_port_trylock_irqsave - Try to lock the UART port, save and disable interrupts
632984095adSThomas Gleixner * @up: Pointer to UART port structure
633984095adSThomas Gleixner * @flags: Pointer to interrupt flags storage
634984095adSThomas Gleixner *
635984095adSThomas Gleixner * Returns: True if lock was acquired, false otherwise
636984095adSThomas Gleixner */
uart_port_trylock_irqsave(struct uart_port * up,unsigned long * flags)637984095adSThomas Gleixner static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags)
638984095adSThomas Gleixner {
639984095adSThomas Gleixner return spin_trylock_irqsave(&up->lock, *flags);
640984095adSThomas Gleixner }
641984095adSThomas Gleixner
642984095adSThomas Gleixner /**
643984095adSThomas Gleixner * uart_port_unlock - Unlock the UART port
644984095adSThomas Gleixner * @up: Pointer to UART port structure
645984095adSThomas Gleixner */
uart_port_unlock(struct uart_port * up)646984095adSThomas Gleixner static inline void uart_port_unlock(struct uart_port *up)
647984095adSThomas Gleixner {
648984095adSThomas Gleixner spin_unlock(&up->lock);
649984095adSThomas Gleixner }
650984095adSThomas Gleixner
651984095adSThomas Gleixner /**
652984095adSThomas Gleixner * uart_port_unlock_irq - Unlock the UART port and re-enable interrupts
653984095adSThomas Gleixner * @up: Pointer to UART port structure
654984095adSThomas Gleixner */
uart_port_unlock_irq(struct uart_port * up)655984095adSThomas Gleixner static inline void uart_port_unlock_irq(struct uart_port *up)
656984095adSThomas Gleixner {
657984095adSThomas Gleixner spin_unlock_irq(&up->lock);
658984095adSThomas Gleixner }
659984095adSThomas Gleixner
660984095adSThomas Gleixner /**
6610e999966SRandy Dunlap * uart_port_unlock_irqrestore - Unlock the UART port, restore interrupts
662984095adSThomas Gleixner * @up: Pointer to UART port structure
663984095adSThomas Gleixner * @flags: The saved interrupt flags for restore
664984095adSThomas Gleixner */
uart_port_unlock_irqrestore(struct uart_port * up,unsigned long flags)665984095adSThomas Gleixner static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags)
666984095adSThomas Gleixner {
667984095adSThomas Gleixner spin_unlock_irqrestore(&up->lock, flags);
668984095adSThomas Gleixner }
669984095adSThomas Gleixner
serial_port_in(struct uart_port * up,int offset)670927353a7SPaul Gortmaker static inline int serial_port_in(struct uart_port *up, int offset)
671927353a7SPaul Gortmaker {
672927353a7SPaul Gortmaker return up->serial_in(up, offset);
673927353a7SPaul Gortmaker }
674927353a7SPaul Gortmaker
serial_port_out(struct uart_port * up,int offset,int value)675927353a7SPaul Gortmaker static inline void serial_port_out(struct uart_port *up, int offset, int value)
676927353a7SPaul Gortmaker {
677927353a7SPaul Gortmaker up->serial_out(up, offset, value);
678927353a7SPaul Gortmaker }
679927353a7SPaul Gortmaker
6806f538fe3SLinus Walleij /**
6816f538fe3SLinus Walleij * enum uart_pm_state - power states for UARTs
6826f538fe3SLinus Walleij * @UART_PM_STATE_ON: UART is powered, up and operational
6836f538fe3SLinus Walleij * @UART_PM_STATE_OFF: UART is powered off
6846f538fe3SLinus Walleij * @UART_PM_STATE_UNDEFINED: sentinel
6856f538fe3SLinus Walleij */
6866f538fe3SLinus Walleij enum uart_pm_state {
6876f538fe3SLinus Walleij UART_PM_STATE_ON = 0,
6886f538fe3SLinus Walleij UART_PM_STATE_OFF = 3, /* number taken from ACPI */
6896f538fe3SLinus Walleij UART_PM_STATE_UNDEFINED,
6906f538fe3SLinus Walleij };
6916f538fe3SLinus Walleij
6921da177e4SLinus Torvalds /*
693ebd2c8f6SAlan Cox * This is the state information which is persistent across opens.
694ebd2c8f6SAlan Cox */
695ebd2c8f6SAlan Cox struct uart_state {
696df4f4dd4SAlan Cox struct tty_port port;
697ebd2c8f6SAlan Cox
6986f538fe3SLinus Walleij enum uart_pm_state pm_state;
6991da177e4SLinus Torvalds struct circ_buf xmit;
7001da177e4SLinus Torvalds
7019ed19428SPeter Hurley atomic_t refcount;
7029ed19428SPeter Hurley wait_queue_head_t remove_wait;
703ebd2c8f6SAlan Cox struct uart_port *uart_port;
704f751928eSAlan Cox };
705f751928eSAlan Cox
706f751928eSAlan Cox #define UART_XMIT_SIZE PAGE_SIZE
707f751928eSAlan Cox
708f751928eSAlan Cox
7091da177e4SLinus Torvalds /* number of characters left in xmit buffer before we ask for more */
7101da177e4SLinus Torvalds #define WAKEUP_CHARS 256
7111da177e4SLinus Torvalds
712e77cab77SIlpo Järvinen /**
713e77cab77SIlpo Järvinen * uart_xmit_advance - Advance xmit buffer and account Tx'ed chars
714e77cab77SIlpo Järvinen * @up: uart_port structure describing the port
715e77cab77SIlpo Järvinen * @chars: number of characters sent
716e77cab77SIlpo Järvinen *
717e77cab77SIlpo Järvinen * This function advances the tail of circular xmit buffer by the number of
718e77cab77SIlpo Järvinen * @chars transmitted and handles accounting of transmitted bytes (into
719e77cab77SIlpo Järvinen * @up's icount.tx).
720e77cab77SIlpo Järvinen */
uart_xmit_advance(struct uart_port * up,unsigned int chars)721e77cab77SIlpo Järvinen static inline void uart_xmit_advance(struct uart_port *up, unsigned int chars)
722e77cab77SIlpo Järvinen {
723e77cab77SIlpo Järvinen struct circ_buf *xmit = &up->state->xmit;
724e77cab77SIlpo Järvinen
725e77cab77SIlpo Järvinen xmit->tail = (xmit->tail + chars) & (UART_XMIT_SIZE - 1);
726e77cab77SIlpo Järvinen up->icount.tx += chars;
727e77cab77SIlpo Järvinen }
728e77cab77SIlpo Järvinen
7291da177e4SLinus Torvalds struct module;
7301da177e4SLinus Torvalds struct tty_driver;
7311da177e4SLinus Torvalds
7321da177e4SLinus Torvalds struct uart_driver {
7331da177e4SLinus Torvalds struct module *owner;
7341da177e4SLinus Torvalds const char *driver_name;
7351da177e4SLinus Torvalds const char *dev_name;
7361da177e4SLinus Torvalds int major;
7371da177e4SLinus Torvalds int minor;
7381da177e4SLinus Torvalds int nr;
7391da177e4SLinus Torvalds struct console *cons;
7401da177e4SLinus Torvalds
7411da177e4SLinus Torvalds /*
7421da177e4SLinus Torvalds * these are private; the low level driver should not
7431da177e4SLinus Torvalds * touch these; they should be initialised to NULL
7441da177e4SLinus Torvalds */
7451da177e4SLinus Torvalds struct uart_state *state;
7461da177e4SLinus Torvalds struct tty_driver *tty_driver;
7471da177e4SLinus Torvalds };
7481da177e4SLinus Torvalds
7491da177e4SLinus Torvalds void uart_write_wakeup(struct uart_port *port);
7501da177e4SLinus Torvalds
751ab288bbaSJiri Slaby (SUSE) /**
752ab288bbaSJiri Slaby (SUSE) * enum UART_TX_FLAGS -- flags for uart_port_tx_flags()
753ab288bbaSJiri Slaby (SUSE) *
754ab288bbaSJiri Slaby (SUSE) * @UART_TX_NOSTOP: don't call port->ops->stop_tx() on empty buffer
755ab288bbaSJiri Slaby (SUSE) */
756ab288bbaSJiri Slaby (SUSE) enum UART_TX_FLAGS {
757ab288bbaSJiri Slaby (SUSE) UART_TX_NOSTOP = BIT(0),
758ab288bbaSJiri Slaby (SUSE) };
759ab288bbaSJiri Slaby (SUSE)
760ab288bbaSJiri Slaby (SUSE) #define __uart_port_tx(uport, ch, flags, tx_ready, put_char, tx_done, \
761ab288bbaSJiri Slaby (SUSE) for_test, for_post) \
7628275b48bSJiri Slaby (SUSE) ({ \
7638275b48bSJiri Slaby (SUSE) struct uart_port *__port = (uport); \
7648275b48bSJiri Slaby (SUSE) struct circ_buf *xmit = &__port->state->xmit; \
7658275b48bSJiri Slaby (SUSE) unsigned int pending; \
7668275b48bSJiri Slaby (SUSE) \
7678275b48bSJiri Slaby (SUSE) for (; (for_test) && (tx_ready); (for_post), __port->icount.tx++) { \
7688275b48bSJiri Slaby (SUSE) if (__port->x_char) { \
7698275b48bSJiri Slaby (SUSE) (ch) = __port->x_char; \
7708275b48bSJiri Slaby (SUSE) (put_char); \
7718275b48bSJiri Slaby (SUSE) __port->x_char = 0; \
7728275b48bSJiri Slaby (SUSE) continue; \
7738275b48bSJiri Slaby (SUSE) } \
7748275b48bSJiri Slaby (SUSE) \
7758275b48bSJiri Slaby (SUSE) if (uart_circ_empty(xmit) || uart_tx_stopped(__port)) \
7768275b48bSJiri Slaby (SUSE) break; \
7778275b48bSJiri Slaby (SUSE) \
7788275b48bSJiri Slaby (SUSE) (ch) = xmit->buf[xmit->tail]; \
7798275b48bSJiri Slaby (SUSE) (put_char); \
7808275b48bSJiri Slaby (SUSE) xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE; \
7818275b48bSJiri Slaby (SUSE) } \
7828275b48bSJiri Slaby (SUSE) \
7838275b48bSJiri Slaby (SUSE) (tx_done); \
7848275b48bSJiri Slaby (SUSE) \
7858275b48bSJiri Slaby (SUSE) pending = uart_circ_chars_pending(xmit); \
7868275b48bSJiri Slaby (SUSE) if (pending < WAKEUP_CHARS) { \
7878275b48bSJiri Slaby (SUSE) uart_write_wakeup(__port); \
7888275b48bSJiri Slaby (SUSE) \
7896f12c54fSJonas Gorski if (!((flags) & UART_TX_NOSTOP) && pending == 0 && \
7906f12c54fSJonas Gorski __port->ops->tx_empty(__port)) \
7918275b48bSJiri Slaby (SUSE) __port->ops->stop_tx(__port); \
7928275b48bSJiri Slaby (SUSE) } \
7938275b48bSJiri Slaby (SUSE) \
7948275b48bSJiri Slaby (SUSE) pending; \
7958275b48bSJiri Slaby (SUSE) })
7968275b48bSJiri Slaby (SUSE)
7978275b48bSJiri Slaby (SUSE) /**
7988275b48bSJiri Slaby (SUSE) * uart_port_tx_limited -- transmit helper for uart_port with count limiting
7998275b48bSJiri Slaby (SUSE) * @port: uart port
8008275b48bSJiri Slaby (SUSE) * @ch: variable to store a character to be written to the HW
8018275b48bSJiri Slaby (SUSE) * @count: a limit of characters to send
8028275b48bSJiri Slaby (SUSE) * @tx_ready: can HW accept more data function
8038275b48bSJiri Slaby (SUSE) * @put_char: function to write a character
8048275b48bSJiri Slaby (SUSE) * @tx_done: function to call after the loop is done
8058275b48bSJiri Slaby (SUSE) *
8068275b48bSJiri Slaby (SUSE) * This helper transmits characters from the xmit buffer to the hardware using
8078275b48bSJiri Slaby (SUSE) * @put_char(). It does so until @count characters are sent and while @tx_ready
8088275b48bSJiri Slaby (SUSE) * evaluates to true.
8098275b48bSJiri Slaby (SUSE) *
8108275b48bSJiri Slaby (SUSE) * Returns: the number of characters in the xmit buffer when done.
8118275b48bSJiri Slaby (SUSE) *
8128275b48bSJiri Slaby (SUSE) * The expression in macro parameters shall be designed as follows:
8138275b48bSJiri Slaby (SUSE) * * **tx_ready:** should evaluate to true if the HW can accept more data to
8148275b48bSJiri Slaby (SUSE) * be sent. This parameter can be %true, which means the HW is always ready.
8158275b48bSJiri Slaby (SUSE) * * **put_char:** shall write @ch to the device of @port.
8168275b48bSJiri Slaby (SUSE) * * **tx_done:** when the write loop is done, this can perform arbitrary
8178275b48bSJiri Slaby (SUSE) * action before potential invocation of ops->stop_tx() happens. If the
8188275b48bSJiri Slaby (SUSE) * driver does not need to do anything, use e.g. ({}).
8198275b48bSJiri Slaby (SUSE) *
8208275b48bSJiri Slaby (SUSE) * For all of them, @port->lock is held, interrupts are locally disabled and
8218275b48bSJiri Slaby (SUSE) * the expressions must not sleep.
8228275b48bSJiri Slaby (SUSE) */
8238275b48bSJiri Slaby (SUSE) #define uart_port_tx_limited(port, ch, count, tx_ready, put_char, tx_done) ({ \
8248275b48bSJiri Slaby (SUSE) unsigned int __count = (count); \
825ab288bbaSJiri Slaby (SUSE) __uart_port_tx(port, ch, 0, tx_ready, put_char, tx_done, __count, \
8268275b48bSJiri Slaby (SUSE) __count--); \
8278275b48bSJiri Slaby (SUSE) })
8288275b48bSJiri Slaby (SUSE)
8298275b48bSJiri Slaby (SUSE) /**
8308275b48bSJiri Slaby (SUSE) * uart_port_tx -- transmit helper for uart_port
8318275b48bSJiri Slaby (SUSE) * @port: uart port
8328275b48bSJiri Slaby (SUSE) * @ch: variable to store a character to be written to the HW
8338275b48bSJiri Slaby (SUSE) * @tx_ready: can HW accept more data function
8348275b48bSJiri Slaby (SUSE) * @put_char: function to write a character
8358275b48bSJiri Slaby (SUSE) *
8368275b48bSJiri Slaby (SUSE) * See uart_port_tx_limited() for more details.
8378275b48bSJiri Slaby (SUSE) */
8388275b48bSJiri Slaby (SUSE) #define uart_port_tx(port, ch, tx_ready, put_char) \
839ab288bbaSJiri Slaby (SUSE) __uart_port_tx(port, ch, 0, tx_ready, put_char, ({}), true, ({}))
8408275b48bSJiri Slaby (SUSE)
841ab288bbaSJiri Slaby (SUSE)
842ab288bbaSJiri Slaby (SUSE) /**
843ab288bbaSJiri Slaby (SUSE) * uart_port_tx_flags -- transmit helper for uart_port with flags
844ab288bbaSJiri Slaby (SUSE) * @port: uart port
845ab288bbaSJiri Slaby (SUSE) * @ch: variable to store a character to be written to the HW
846ab288bbaSJiri Slaby (SUSE) * @flags: %UART_TX_NOSTOP or similar
847ab288bbaSJiri Slaby (SUSE) * @tx_ready: can HW accept more data function
848ab288bbaSJiri Slaby (SUSE) * @put_char: function to write a character
849ab288bbaSJiri Slaby (SUSE) *
850ab288bbaSJiri Slaby (SUSE) * See uart_port_tx_limited() for more details.
851ab288bbaSJiri Slaby (SUSE) */
852ab288bbaSJiri Slaby (SUSE) #define uart_port_tx_flags(port, ch, flags, tx_ready, put_char) \
853ab288bbaSJiri Slaby (SUSE) __uart_port_tx(port, ch, flags, tx_ready, put_char, ({}), true, ({}))
8541da177e4SLinus Torvalds /*
8551da177e4SLinus Torvalds * Baud rate helpers.
8561da177e4SLinus Torvalds */
8571da177e4SLinus Torvalds void uart_update_timeout(struct uart_port *port, unsigned int cflag,
8581da177e4SLinus Torvalds unsigned int baud);
859606d099cSAlan Cox unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
860bec5b814SIlpo Järvinen const struct ktermios *old, unsigned int min,
8611da177e4SLinus Torvalds unsigned int max);
8621da177e4SLinus Torvalds unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud);
8631da177e4SLinus Torvalds
864f9008285SIlpo Järvinen /*
865f9008285SIlpo Järvinen * Calculates FIFO drain time.
866f9008285SIlpo Järvinen */
uart_fifo_timeout(struct uart_port * port)867f9008285SIlpo Järvinen static inline unsigned long uart_fifo_timeout(struct uart_port *port)
868f9008285SIlpo Järvinen {
869f9008285SIlpo Järvinen u64 fifo_timeout = (u64)READ_ONCE(port->frame_time) * port->fifosize;
870f9008285SIlpo Järvinen
871f9008285SIlpo Järvinen /* Add .02 seconds of slop */
872f9008285SIlpo Järvinen fifo_timeout += 20 * NSEC_PER_MSEC;
873f9008285SIlpo Järvinen
874f9008285SIlpo Järvinen return max(nsecs_to_jiffies(fifo_timeout), 1UL);
875f9008285SIlpo Järvinen }
876f9008285SIlpo Järvinen
87754381067SAnton Vorontsov /* Base timer interval for polling */
uart_poll_timeout(struct uart_port * port)87854381067SAnton Vorontsov static inline int uart_poll_timeout(struct uart_port *port)
87954381067SAnton Vorontsov {
880f9008285SIlpo Järvinen int timeout = uart_fifo_timeout(port);
88154381067SAnton Vorontsov
88254381067SAnton Vorontsov return timeout > 6 ? (timeout / 2 - 2) : 1;
88354381067SAnton Vorontsov }
88454381067SAnton Vorontsov
8851da177e4SLinus Torvalds /*
8861da177e4SLinus Torvalds * Console helpers.
8871da177e4SLinus Torvalds */
8889aac5887SRob Herring struct earlycon_device {
8899aac5887SRob Herring struct console *con;
8909aac5887SRob Herring struct uart_port port;
89141000b03SRicardo Ribalda char options[32]; /* e.g., 115200n8 */
8929aac5887SRob Herring unsigned int baud;
8939aac5887SRob Herring };
8949aac5887SRob Herring
895470ca0deSPeter Hurley struct earlycon_id {
896c1c734cbSDouglas Anderson char name[15];
897c1c734cbSDouglas Anderson char name_term; /* In case compiler didn't '\0' term name */
8982eaa7909SPeter Hurley char compatible[128];
899470ca0deSPeter Hurley int (*setup)(struct earlycon_device *, const char *options);
900dd709e72SDaniel Kurtz };
901470ca0deSPeter Hurley
90262dcd9c5SJohan Hovold extern const struct earlycon_id __earlycon_table[];
90362dcd9c5SJohan Hovold extern const struct earlycon_id __earlycon_table_end[];
9042eaa7909SPeter Hurley
905f8ba3647SMasahiro Yamada #if defined(CONFIG_SERIAL_EARLYCON) && !defined(MODULE)
906f8ba3647SMasahiro Yamada #define EARLYCON_USED_OR_UNUSED __used
907f8ba3647SMasahiro Yamada #else
908f8ba3647SMasahiro Yamada #define EARLYCON_USED_OR_UNUSED __maybe_unused
909f8ba3647SMasahiro Yamada #endif
910f8ba3647SMasahiro Yamada
91162dcd9c5SJohan Hovold #define OF_EARLYCON_DECLARE(_name, compat, fn) \
91262dcd9c5SJohan Hovold static const struct earlycon_id __UNIQUE_ID(__earlycon_##_name) \
91362dcd9c5SJohan Hovold EARLYCON_USED_OR_UNUSED __section("__earlycon_table") \
91462dcd9c5SJohan Hovold __aligned(__alignof__(struct earlycon_id)) \
9152eaa7909SPeter Hurley = { .name = __stringify(_name), \
9162eaa7909SPeter Hurley .compatible = compat, \
91776437b34SJohan Hovold .setup = fn }
9182eaa7909SPeter Hurley
9192eaa7909SPeter Hurley #define EARLYCON_DECLARE(_name, fn) OF_EARLYCON_DECLARE(_name, "", fn)
9202eaa7909SPeter Hurley
9216229ad99SIlpo Järvinen int of_setup_earlycon(const struct earlycon_id *match, unsigned long node,
9224d118c9aSPeter Hurley const char *options);
923b0b6abd3SRob Herring
924ad1696f6SAleksey Makarov #ifdef CONFIG_SERIAL_EARLYCON
9250231d000SPrarit Bhargava extern bool earlycon_acpi_spcr_enable __initdata;
926ad1696f6SAleksey Makarov int setup_earlycon(char *buf);
927ad1696f6SAleksey Makarov #else
928219c7b06SMathieu Malaterre static const bool earlycon_acpi_spcr_enable EARLYCON_USED_OR_UNUSED;
setup_earlycon(char * buf)929ad1696f6SAleksey Makarov static inline int setup_earlycon(char *buf) { return 0; }
930ad1696f6SAleksey Makarov #endif
931ad1696f6SAleksey Makarov
932452b9b24SJohn Ogness /* Variant of uart_console_registered() when the console_list_lock is held. */
uart_console_registered_locked(struct uart_port * port)933452b9b24SJohn Ogness static inline bool uart_console_registered_locked(struct uart_port *port)
934f9b11229SIlpo Järvinen {
935452b9b24SJohn Ogness return uart_console(port) && console_is_registered_locked(port->cons);
936452b9b24SJohn Ogness }
937452b9b24SJohn Ogness
uart_console_registered(struct uart_port * port)938452b9b24SJohn Ogness static inline bool uart_console_registered(struct uart_port *port)
939452b9b24SJohn Ogness {
940452b9b24SJohn Ogness return uart_console(port) && console_is_registered(port->cons);
941f9b11229SIlpo Järvinen }
942f9b11229SIlpo Järvinen
9431da177e4SLinus Torvalds struct uart_port *uart_get_console(struct uart_port *ports, int nr,
9441da177e4SLinus Torvalds struct console *c);
94546e36683SAlexander Sverdlin int uart_parse_earlycon(char *p, unsigned char *iotype, resource_size_t *addr,
94673abaf87SPeter Hurley char **options);
9470f646b63SPaul Cercueil void uart_parse_options(const char *options, int *baud, int *parity, int *bits,
9481da177e4SLinus Torvalds int *flow);
9491da177e4SLinus Torvalds int uart_set_options(struct uart_port *port, struct console *co, int baud,
9501da177e4SLinus Torvalds int parity, int bits, int flow);
9511da177e4SLinus Torvalds struct tty_driver *uart_console_device(struct console *co, int *index);
952d358788fSRussell King void uart_console_write(struct uart_port *port, const char *s,
953d358788fSRussell King unsigned int count,
9543f8bab17SJiri Slaby void (*putchar)(struct uart_port *, unsigned char));
9551da177e4SLinus Torvalds
9561da177e4SLinus Torvalds /*
9571da177e4SLinus Torvalds * Port/driver registration/removal
9581da177e4SLinus Torvalds */
9591da177e4SLinus Torvalds int uart_register_driver(struct uart_driver *uart);
9601da177e4SLinus Torvalds void uart_unregister_driver(struct uart_driver *uart);
9611da177e4SLinus Torvalds int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
962d5b3d02dSUwe Kleine-König void uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
963b8be5db5SJiri Slaby bool uart_match_port(const struct uart_port *port1,
964b8be5db5SJiri Slaby const struct uart_port *port2);
9651da177e4SLinus Torvalds
9661da177e4SLinus Torvalds /*
9671da177e4SLinus Torvalds * Power Management
9681da177e4SLinus Torvalds */
9691da177e4SLinus Torvalds int uart_suspend_port(struct uart_driver *reg, struct uart_port *port);
9701da177e4SLinus Torvalds int uart_resume_port(struct uart_driver *reg, struct uart_port *port);
9711da177e4SLinus Torvalds
9721da177e4SLinus Torvalds #define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
9731da177e4SLinus Torvalds #define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
9741da177e4SLinus Torvalds
9751da177e4SLinus Torvalds #define uart_circ_chars_pending(circ) \
9761da177e4SLinus Torvalds (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
9771da177e4SLinus Torvalds
9781da177e4SLinus Torvalds #define uart_circ_chars_free(circ) \
9791da177e4SLinus Torvalds (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
9801da177e4SLinus Torvalds
uart_tx_stopped(struct uart_port * port)981f751928eSAlan Cox static inline int uart_tx_stopped(struct uart_port *port)
982f751928eSAlan Cox {
983ebd2c8f6SAlan Cox struct tty_struct *tty = port->state->port.tty;
9846e94dbc7SJiri Slaby if ((tty && tty->flow.stopped) || port->hw_stopped)
985f751928eSAlan Cox return 1;
986f751928eSAlan Cox return 0;
987f751928eSAlan Cox }
9881da177e4SLinus Torvalds
uart_cts_enabled(struct uart_port * uport)989299245a1SPeter Hurley static inline bool uart_cts_enabled(struct uart_port *uport)
990299245a1SPeter Hurley {
991d4260b51SPeter Hurley return !!(uport->status & UPSTAT_CTS_ENABLE);
992299245a1SPeter Hurley }
993299245a1SPeter Hurley
uart_softcts_mode(struct uart_port * uport)994391f93f2SPeter Hurley static inline bool uart_softcts_mode(struct uart_port *uport)
995391f93f2SPeter Hurley {
996391f93f2SPeter Hurley upstat_t mask = UPSTAT_CTS_ENABLE | UPSTAT_AUTOCTS;
997391f93f2SPeter Hurley
998391f93f2SPeter Hurley return ((uport->status & mask) == UPSTAT_CTS_ENABLE);
999391f93f2SPeter Hurley }
1000391f93f2SPeter Hurley
10011da177e4SLinus Torvalds /*
10021da177e4SLinus Torvalds * The following are helper functions for the low level drivers.
10031da177e4SLinus Torvalds */
1004027d7dacSJiri Slaby
10056229ad99SIlpo Järvinen void uart_handle_dcd_change(struct uart_port *uport, bool active);
10066229ad99SIlpo Järvinen void uart_handle_cts_change(struct uart_port *uport, bool active);
1007027d7dacSJiri Slaby
10086229ad99SIlpo Järvinen void uart_insert_char(struct uart_port *port, unsigned int status,
1009df007fa0SJiri Slaby unsigned int overrun, u8 ch, u8 flag);
1010027d7dacSJiri Slaby
1011f58c252eSIlpo Järvinen void uart_xchar_out(struct uart_port *uport, int offset);
1012f58c252eSIlpo Järvinen
101308d54703SJohan Hovold #ifdef CONFIG_MAGIC_SYSRQ_SERIAL
101408d54703SJohan Hovold #define SYSRQ_TIMEOUT (HZ * 5)
101508d54703SJohan Hovold
101612ae2359SJiri Slaby bool uart_try_toggle_sysrq(struct uart_port *port, u8 ch);
101708d54703SJohan Hovold
uart_handle_sysrq_char(struct uart_port * port,u8 ch)101812ae2359SJiri Slaby static inline int uart_handle_sysrq_char(struct uart_port *port, u8 ch)
101908d54703SJohan Hovold {
102022538565SJohan Hovold if (!port->sysrq)
102108d54703SJohan Hovold return 0;
102208d54703SJohan Hovold
102308d54703SJohan Hovold if (ch && time_before(jiffies, port->sysrq)) {
102408d54703SJohan Hovold if (sysrq_mask()) {
102508d54703SJohan Hovold handle_sysrq(ch);
102608d54703SJohan Hovold port->sysrq = 0;
102708d54703SJohan Hovold return 1;
102808d54703SJohan Hovold }
102908d54703SJohan Hovold if (uart_try_toggle_sysrq(port, ch))
103008d54703SJohan Hovold return 1;
103108d54703SJohan Hovold }
103208d54703SJohan Hovold port->sysrq = 0;
103308d54703SJohan Hovold
103408d54703SJohan Hovold return 0;
103508d54703SJohan Hovold }
103608d54703SJohan Hovold
uart_prepare_sysrq_char(struct uart_port * port,u8 ch)103712ae2359SJiri Slaby static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch)
103808d54703SJohan Hovold {
103922538565SJohan Hovold if (!port->sysrq)
104008d54703SJohan Hovold return 0;
104108d54703SJohan Hovold
104208d54703SJohan Hovold if (ch && time_before(jiffies, port->sysrq)) {
104308d54703SJohan Hovold if (sysrq_mask()) {
104408d54703SJohan Hovold port->sysrq_ch = ch;
104508d54703SJohan Hovold port->sysrq = 0;
104608d54703SJohan Hovold return 1;
104708d54703SJohan Hovold }
104808d54703SJohan Hovold if (uart_try_toggle_sysrq(port, ch))
104908d54703SJohan Hovold return 1;
105008d54703SJohan Hovold }
105108d54703SJohan Hovold port->sysrq = 0;
105208d54703SJohan Hovold
105308d54703SJohan Hovold return 0;
105408d54703SJohan Hovold }
105508d54703SJohan Hovold
uart_unlock_and_check_sysrq(struct uart_port * port)105675f4e830SJohan Hovold static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
105708d54703SJohan Hovold {
105812ae2359SJiri Slaby u8 sysrq_ch;
105908d54703SJohan Hovold
106008d54703SJohan Hovold if (!port->has_sysrq) {
106175f4e830SJohan Hovold spin_unlock(&port->lock);
106208d54703SJohan Hovold return;
106308d54703SJohan Hovold }
106408d54703SJohan Hovold
106508d54703SJohan Hovold sysrq_ch = port->sysrq_ch;
106608d54703SJohan Hovold port->sysrq_ch = 0;
106708d54703SJohan Hovold
106875f4e830SJohan Hovold spin_unlock(&port->lock);
106908d54703SJohan Hovold
107008d54703SJohan Hovold if (sysrq_ch)
107108d54703SJohan Hovold handle_sysrq(sysrq_ch);
107208d54703SJohan Hovold }
1073853a9ae2SJohan Hovold
uart_unlock_and_check_sysrq_irqrestore(struct uart_port * port,unsigned long flags)1074853a9ae2SJohan Hovold static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
1075853a9ae2SJohan Hovold unsigned long flags)
1076853a9ae2SJohan Hovold {
107712ae2359SJiri Slaby u8 sysrq_ch;
1078853a9ae2SJohan Hovold
1079853a9ae2SJohan Hovold if (!port->has_sysrq) {
1080853a9ae2SJohan Hovold spin_unlock_irqrestore(&port->lock, flags);
1081853a9ae2SJohan Hovold return;
1082853a9ae2SJohan Hovold }
1083853a9ae2SJohan Hovold
1084853a9ae2SJohan Hovold sysrq_ch = port->sysrq_ch;
1085853a9ae2SJohan Hovold port->sysrq_ch = 0;
1086853a9ae2SJohan Hovold
1087853a9ae2SJohan Hovold spin_unlock_irqrestore(&port->lock, flags);
1088853a9ae2SJohan Hovold
1089853a9ae2SJohan Hovold if (sysrq_ch)
1090853a9ae2SJohan Hovold handle_sysrq(sysrq_ch);
1091853a9ae2SJohan Hovold }
109208d54703SJohan Hovold #else /* CONFIG_MAGIC_SYSRQ_SERIAL */
uart_handle_sysrq_char(struct uart_port * port,u8 ch)109312ae2359SJiri Slaby static inline int uart_handle_sysrq_char(struct uart_port *port, u8 ch)
109408d54703SJohan Hovold {
109508d54703SJohan Hovold return 0;
109608d54703SJohan Hovold }
uart_prepare_sysrq_char(struct uart_port * port,u8 ch)109712ae2359SJiri Slaby static inline int uart_prepare_sysrq_char(struct uart_port *port, u8 ch)
109808d54703SJohan Hovold {
109908d54703SJohan Hovold return 0;
110008d54703SJohan Hovold }
uart_unlock_and_check_sysrq(struct uart_port * port)110175f4e830SJohan Hovold static inline void uart_unlock_and_check_sysrq(struct uart_port *port)
110208d54703SJohan Hovold {
110375f4e830SJohan Hovold spin_unlock(&port->lock);
110408d54703SJohan Hovold }
uart_unlock_and_check_sysrq_irqrestore(struct uart_port * port,unsigned long flags)1105853a9ae2SJohan Hovold static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port,
1106853a9ae2SJohan Hovold unsigned long flags)
1107853a9ae2SJohan Hovold {
1108853a9ae2SJohan Hovold spin_unlock_irqrestore(&port->lock, flags);
1109853a9ae2SJohan Hovold }
111008d54703SJohan Hovold #endif /* CONFIG_MAGIC_SYSRQ_SERIAL */
111108d54703SJohan Hovold
111208d54703SJohan Hovold /*
111308d54703SJohan Hovold * We do the SysRQ and SAK checking like this...
111408d54703SJohan Hovold */
uart_handle_break(struct uart_port * port)111508d54703SJohan Hovold static inline int uart_handle_break(struct uart_port *port)
111608d54703SJohan Hovold {
111708d54703SJohan Hovold struct uart_state *state = port->state;
111808d54703SJohan Hovold
111908d54703SJohan Hovold if (port->handle_break)
112008d54703SJohan Hovold port->handle_break(port);
112108d54703SJohan Hovold
112208d54703SJohan Hovold #ifdef CONFIG_MAGIC_SYSRQ_SERIAL
112308d54703SJohan Hovold if (port->has_sysrq && uart_console(port)) {
112408d54703SJohan Hovold if (!port->sysrq) {
112508d54703SJohan Hovold port->sysrq = jiffies + SYSRQ_TIMEOUT;
112608d54703SJohan Hovold return 1;
112708d54703SJohan Hovold }
112808d54703SJohan Hovold port->sysrq = 0;
112908d54703SJohan Hovold }
113008d54703SJohan Hovold #endif
113108d54703SJohan Hovold if (port->flags & UPF_SAK)
113208d54703SJohan Hovold do_SAK(state->port.tty);
113308d54703SJohan Hovold return 0;
113408d54703SJohan Hovold }
11351da177e4SLinus Torvalds
11361da177e4SLinus Torvalds /*
11371da177e4SLinus Torvalds * UART_ENABLE_MS - determine if port should enable modem status irqs
11381da177e4SLinus Torvalds */
11391da177e4SLinus Torvalds #define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \
11401da177e4SLinus Torvalds (cflag) & CRTSCTS || \
11411da177e4SLinus Torvalds !((cflag) & CLOCAL))
11421da177e4SLinus Torvalds
1143c150c0f3SLukas Wunner int uart_get_rs485_mode(struct uart_port *port);
11441da177e4SLinus Torvalds #endif /* LINUX_SERIAL_CORE_H */
1145