xref: /openbmc/linux/include/linux/serial_core.h (revision 6f12c54f)
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