aboutsummaryrefslogtreecommitdiff
path: root/Documentation/serial/driver
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/serial/driver')
-rw-r--r--Documentation/serial/driver186
1 files changed, 156 insertions, 30 deletions
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
index ac7eabbf662..3bba1aeb799 100644
--- a/Documentation/serial/driver
+++ b/Documentation/serial/driver
@@ -3,14 +3,11 @@
--------------------
- $Id: driver,v 1.10 2002/07/22 15:27:30 rmk Exp $
-
-
This document is meant as a brief overview of some aspects of the new serial
driver. It is not complete, any questions you have should be directed to
<rmk@arm.linux.org.uk>
-The reference implementation is contained within serial_amba.c.
+The reference implementation is contained within amba_pl011.c.
@@ -31,6 +28,11 @@ The serial core provides a few helper functions. This includes identifing
the correct port structure (via uart_get_console) and decoding command line
arguments (uart_parse_options).
+There is also a helper function (uart_write_console) which performs a
+character by character write, translating newlines to CRLF sequences.
+Driver writers are recommended to use this function rather than implementing
+their own version.
+
Locking
-------
@@ -86,6 +88,7 @@ hardware.
- TIOCM_DTR DTR signal.
- TIOCM_OUT1 OUT1 signal.
- TIOCM_OUT2 OUT2 signal.
+ - TIOCM_LOOP Set the port into loopback mode.
If the appropriate bit is set, the signal should be driven
active. If the bit is clear, the signal should be driven
inactive.
@@ -98,7 +101,7 @@ hardware.
Returns the current state of modem control inputs. The state
of the outputs should not be returned, since the core keeps
track of their state. The state information should include:
- - TIOCM_DCD state of DCD signal
+ - TIOCM_CAR state of DCD signal
- TIOCM_CTS state of CTS signal
- TIOCM_DSR state of DSR signal
- TIOCM_RI state of RI signal
@@ -111,29 +114,35 @@ hardware.
Interrupts: locally disabled.
This call must not sleep
- stop_tx(port,tty_stop)
+ stop_tx(port)
Stop transmitting characters. This might be due to the CTS
line becoming inactive or the tty layer indicating we want
- to stop transmission.
+ to stop transmission due to an XOFF character.
- tty_stop: 1 if this call is due to the TTY layer issuing a
- TTY stop to the driver (equiv to rs_stop).
+ The driver should stop transmitting characters as soon as
+ possible.
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
- start_tx(port,tty_start)
- start transmitting characters. (incidentally, nonempty will
- always be nonzero, and shouldn't be used - it will be dropped).
-
- tty_start: 1 if this call was due to the TTY layer issuing
- a TTY start to the driver (equiv to rs_start)
+ start_tx(port)
+ Start transmitting characters.
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
+ send_xchar(port,ch)
+ Transmit a high priority character, even if the port is stopped.
+ This is used to implement XON/XOFF flow control and tcflow(). If
+ the serial driver does not implement this function, the tty core
+ will append the character to the circular buffer and then call
+ start_tx() / stop_tx() to flush the data out.
+
+ Locking: none.
+ Interrupts: caller dependent.
+
stop_rx(port)
Stop receiving characters; the port is in the process of
being closed.
@@ -145,6 +154,10 @@ hardware.
enable_ms(port)
Enable the modem status interrupts.
+ This method may be called multiple times. Modem status
+ interrupts should be disabled when the shutdown method is
+ called.
+
Locking: port->lock taken.
Interrupts: locally disabled.
This call must not sleep
@@ -164,6 +177,8 @@ hardware.
state. Enable the port for reception. It should not activate
RTS nor DTR; this will be done via a separate call to set_mctrl.
+ This method will only be called when the port is initially opened.
+
Locking: port_sem taken.
Interrupts: globally disabled.
@@ -173,9 +188,25 @@ hardware.
RTS nor DTR; this will have already been done via a separate
call to set_mctrl.
+ Drivers must not access port->info once this call has completed.
+
+ This method will only be called when there are no more users of
+ this port.
+
Locking: port_sem taken.
Interrupts: caller dependent.
+ flush_buffer(port)
+ Flush any write buffers, reset any DMA state and stop any
+ ongoing DMA transfers.
+
+ This will be called whenever the port->info->xmit circular
+ buffer is cleared.
+
+ Locking: port->lock taken.
+ Interrupts: locally disabled.
+ This call must not sleep
+
set_termios(port,termios,oldtermios)
Change the port parameters, including word length, parity, stop
bits. Update read_status_mask and ignore_status_mask to indicate
@@ -204,12 +235,13 @@ hardware.
The interaction of the iflag bits is as follows (parity error
given as an example):
Parity error INPCK IGNPAR
- None n/a n/a character received
- Yes n/a 0 character discarded
- Yes 0 1 character received, marked as
+ n/a 0 n/a character received, marked as
TTY_NORMAL
- Yes 1 1 character received, marked as
+ None 1 n/a character received, marked as
+ TTY_NORMAL
+ Yes 1 0 character received, marked as
TTY_PARITY
+ Yes 1 1 character discarded
Other flags may be used (eg, xon/xoff characters) if your
hardware supports hardware "soft" flow control.
@@ -220,9 +252,8 @@ hardware.
pm(port,state,oldstate)
Perform any power management related activities on the specified
- port. State indicates the new state (defined by ACPI D0-D3),
- oldstate indicates the previous state. Essentially, D0 means
- fully on, D3 means powered down.
+ port. State indicates the new state (defined by
+ enum uart_pm_state), oldstate indicates the previous state.
This function should not be used to grab any resources.
@@ -285,29 +316,59 @@ hardware.
Locking: none.
Interrupts: caller dependent.
+ poll_init(port)
+ Called by kgdb to perform the minimal hardware initialization needed
+ to support poll_put_char() and poll_get_char(). Unlike ->startup()
+ this should not request interrupts.
+
+ Locking: tty_mutex and tty_port->mutex taken.
+ Interrupts: n/a.
+
+ poll_put_char(port,ch)
+ Called by kgdb to write a single character directly to the serial
+ port. It can and should block until there is space in the TX FIFO.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
+ poll_get_char(port)
+ Called by kgdb to read a single character directly from the serial
+ port. If data is available, it should be returned; otherwise
+ the function should return NO_POLL_CHAR immediately.
+
+ Locking: none.
+ Interrupts: caller dependent.
+ This call must not sleep
+
Other functions
---------------
-uart_update_timeout(port,cflag,quot)
+uart_update_timeout(port,cflag,baud)
Update the FIFO drain timeout, port->timeout, according to the
- number of bits, parity, stop bits and quotient.
+ number of bits, parity, stop bits and baud rate.
Locking: caller is expected to take port->lock
Interrupts: n/a
-uart_get_baud_rate(port,termios)
+uart_get_baud_rate(port,termios,old,min,max)
Return the numeric baud rate for the specified termios, taking
account of the special 38400 baud "kludge". The B0 baud rate
is mapped to 9600 baud.
+ If the baud rate is not within min..max, then if old is non-NULL,
+ the original baud rate will be tried. If that exceeds the
+ min..max constraint, 9600 baud will be returned. termios will
+ be updated to the baud rate in use.
+
+ Note: min..max must always allow 9600 baud to be selected.
+
Locking: caller dependent.
Interrupts: n/a
-uart_get_divisor(port,termios,oldtermios)
- Return the divsor (baud_base / baud) for the selected baud rate
- specified by termios. If the baud rate is out of range, try
- the original baud rate specified by oldtermios (if non-NULL).
- If that fails, try 9600 baud.
+uart_get_divisor(port,baud)
+ Return the divsor (baud_base / baud) for the specified baud
+ rate, appropriately rounded.
If 38400 baud and custom divisor is selected, return the
custom divisor instead.
@@ -315,6 +376,46 @@ uart_get_divisor(port,termios,oldtermios)
Locking: caller dependent.
Interrupts: n/a
+uart_match_port(port1,port2)
+ This utility function can be used to determine whether two
+ uart_port structures describe the same port.
+
+ Locking: n/a
+ Interrupts: n/a
+
+uart_write_wakeup(port)
+ A driver is expected to call this function when the number of
+ characters in the transmit buffer have dropped below a threshold.
+
+ Locking: port->lock should be held.
+ Interrupts: n/a
+
+uart_register_driver(drv)
+ Register a uart driver with the core driver. We in turn register
+ with the tty layer, and initialise the core driver per-port state.
+
+ drv->port should be NULL, and the per-port structures should be
+ registered using uart_add_one_port after this call has succeeded.
+
+ Locking: none
+ Interrupts: enabled
+
+uart_unregister_driver()
+ Remove all references to a driver from the core driver. The low
+ level driver must have removed all its ports via the
+ uart_remove_one_port() if it registered them with uart_add_one_port().
+
+ Locking: none
+ Interrupts: enabled
+
+uart_suspend_port()
+
+uart_resume_port()
+
+uart_add_one_port()
+
+uart_remove_one_port()
+
Other notes
-----------
@@ -328,3 +429,28 @@ thus:
struct uart_port port;
int my_stuff;
};
+
+Modem control lines via GPIO
+----------------------------
+
+Some helpers are provided in order to set/get modem control lines via GPIO.
+
+mctrl_gpio_init(dev, idx):
+ This will get the {cts,rts,...}-gpios from device tree if they are
+ present and request them, set direction etc, and return an
+ allocated structure. devm_* functions are used, so there's no need
+ to call mctrl_gpio_free().
+
+mctrl_gpio_free(dev, gpios):
+ This will free the requested gpios in mctrl_gpio_init().
+ As devm_* function are used, there's generally no need to call
+ this function.
+
+mctrl_gpio_to_gpiod(gpios, gidx)
+ This returns the gpio structure associated to the modem line index.
+
+mctrl_gpio_set(gpios, mctrl):
+ This will sets the gpios according to the mctrl state.
+
+mctrl_gpio_get(gpios, mctrl):
+ This will update mctrl with the gpios values.