summary refs log tree commit diff
path: root/Documentation/serial
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /Documentation/serial
downloadlinux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
Diffstat (limited to 'Documentation/serial')
-rw-r--r--Documentation/serial/driver330
1 files changed, 330 insertions, 0 deletions
diff --git a/Documentation/serial/driver b/Documentation/serial/driver
new file mode 100644
index 000000000000..e9c0178cd202
--- /dev/null
+++ b/Documentation/serial/driver
@@ -0,0 +1,330 @@
+
+			Low Level Serial API
+			--------------------
+
+
+   $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.
+
+
+
+Low Level Serial Hardware Driver
+--------------------------------
+
+The low level serial hardware driver is responsible for supplying port
+information (defined by uart_port) and a set of control methods (defined
+by uart_ops) to the core serial driver.  The low level driver is also
+responsible for handling interrupts for the port, and providing any
+console support.
+
+
+Console Support
+---------------
+
+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).
+
+
+Locking
+-------
+
+It is the responsibility of the low level hardware driver to perform the
+necessary locking using port->lock.  There are some exceptions (which
+are described in the uart_ops listing below.)
+
+There are three locks.  A per-port spinlock, a per-port tmpbuf semaphore,
+and an overall semaphore.
+
+From the core driver perspective, the port->lock locks the following
+data:
+
+	port->mctrl
+	port->icount
+	info->xmit.head (circ->head)
+	info->xmit.tail (circ->tail)
+
+The low level driver is free to use this lock to provide any additional
+locking.
+
+The core driver uses the info->tmpbuf_sem lock to prevent multi-threaded
+access to the info->tmpbuf bouncebuffer used for port writes.
+
+The port_sem semaphore is used to protect against ports being added/
+removed or reconfigured at inappropriate times.
+
+
+uart_ops
+--------
+
+The uart_ops structure is the main interface between serial_core and the
+hardware specific driver.  It contains all the methods to control the
+hardware.
+
+  tx_empty(port)
+	This function tests whether the transmitter fifo and shifter
+	for the port described by 'port' is empty.  If it is empty,
+	this function should return TIOCSER_TEMT, otherwise return 0.
+	If the port does not support this operation, then it should
+	return TIOCSER_TEMT.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  set_mctrl(port, mctrl)
+	This function sets the modem control lines for port described
+	by 'port' to the state described by mctrl.  The relevant bits
+	of mctrl are:
+		- TIOCM_RTS	RTS signal.
+		- TIOCM_DTR	DTR signal.
+		- TIOCM_OUT1	OUT1 signal.
+		- TIOCM_OUT2	OUT2 signal.
+	If the appropriate bit is set, the signal should be driven
+	active.  If the bit is clear, the signal should be driven
+	inactive.
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  get_mctrl(port)
+	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_CTS	state of CTS signal
+		- TIOCM_DSR	state of DSR signal
+		- TIOCM_RI	state of RI signal
+	The bit is set if the signal is currently driven active.  If
+	the port does not support CTS, DCD or DSR, the driver should
+	indicate that the signal is permanently active.  If RI is
+	not available, the signal should not be indicated as active.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  stop_tx(port,tty_stop)
+	Stop transmitting characters.  This might be due to the CTS
+	line becoming inactive or the tty layer indicating we want
+	to stop transmission.
+
+	tty_stop: 1 if this call is due to the TTY layer issuing a
+	          TTY stop to the driver (equiv to rs_stop).
+
+	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)
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  stop_rx(port)
+	Stop receiving characters; the port is in the process of
+	being closed.
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  enable_ms(port)
+	Enable the modem status interrupts.
+
+	Locking: port->lock taken.
+	Interrupts: locally disabled.
+	This call must not sleep
+
+  break_ctl(port,ctl)
+	Control the transmission of a break signal.  If ctl is
+	nonzero, the break signal should be transmitted.  The signal
+	should be terminated when another call is made with a zero
+	ctl.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  startup(port)
+	Grab any interrupt resources and initialise any low level driver
+	state.  Enable the port for reception.  It should not activate
+	RTS nor DTR; this will be done via a separate call to set_mctrl.
+
+	Locking: port_sem taken.
+	Interrupts: globally disabled.
+
+  shutdown(port)
+	Disable the port, disable any break condition that may be in
+	effect, and free any interrupt resources.  It should not disable
+	RTS nor DTR; this will have already been done via a separate
+	call to set_mctrl.
+
+	Locking: port_sem taken.
+	Interrupts: caller dependent.
+
+  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
+	the types of events we are interested in receiving.  Relevant
+	termios->c_cflag bits are:
+		CSIZE	- word size
+		CSTOPB	- 2 stop bits
+		PARENB	- parity enable
+		PARODD	- odd parity (when PARENB is in force)
+		CREAD	- enable reception of characters (if not set,
+			  still receive characters from the port, but
+			  throw them away.
+		CRTSCTS	- if set, enable CTS status change reporting
+		CLOCAL	- if not set, enable modem status change
+			  reporting.
+	Relevant termios->c_iflag bits are:
+		INPCK	- enable frame and parity error events to be
+			  passed to the TTY layer.
+		BRKINT
+		PARMRK	- both of these enable break events to be
+			  passed to the TTY layer.
+
+		IGNPAR	- ignore parity and framing errors
+		IGNBRK	- ignore break errors,  If IGNPAR is also
+			  set, ignore overrun errors as well.
+	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
+					TTY_NORMAL
+	Yes		1	1	character received, marked as
+					TTY_PARITY
+
+	Other flags may be used (eg, xon/xoff characters) if your
+	hardware supports hardware "soft" flow control.
+
+	Locking: none.
+	Interrupts: caller dependent.
+	This call must not sleep
+
+  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.
+
+	This function should not be used to grab any resources.
+
+	This will be called when the port is initially opened and finally
+	closed, except when the port is also the system console.  This
+	will occur even if CONFIG_PM is not set.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  type(port)
+	Return a pointer to a string constant describing the specified
+	port, or return NULL, in which case the string 'unknown' is
+	substituted.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  release_port(port)
+	Release any memory and IO region resources currently in use by
+	the port.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  request_port(port)
+	Request any memory and IO region resources required by the port.
+	If any fail, no resources should be registered when this function
+	returns, and it should return -EBUSY on failure.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  config_port(port,type)
+	Perform any autoconfiguration steps required for the port.  `type`
+	contains a bit mask of the required configuration.  UART_CONFIG_TYPE
+	indicates that the port requires detection and identification.
+	port->type should be set to the type found, or PORT_UNKNOWN if
+	no port was detected.
+
+	UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
+	which should be probed using standard kernel autoprobing techniques.
+	This is not necessary on platforms where ports have interrupts
+	internally hard wired (eg, system on a chip implementations).
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  verify_port(port,serinfo)
+	Verify the new serial port information contained within serinfo is
+	suitable for this port type.
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+  ioctl(port,cmd,arg)
+	Perform any port specific IOCTLs.  IOCTL commands must be defined
+	using the standard numbering system found in <asm/ioctl.h>
+
+	Locking: none.
+	Interrupts: caller dependent.
+
+Other functions
+---------------
+
+uart_update_timeout(port,cflag,quot)
+	Update the FIFO drain timeout, port->timeout, according to the
+	number of bits, parity, stop bits and quotient.
+
+	Locking: caller is expected to take port->lock
+	Interrupts: n/a
+
+uart_get_baud_rate(port,termios)
+	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.
+
+	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.
+
+	If 38400 baud and custom divisor is selected, return the
+	custom divisor instead.
+
+	Locking: caller dependent.
+	Interrupts: n/a
+
+Other notes
+-----------
+
+It is intended some day to drop the 'unused' entries from uart_port, and
+allow low level drivers to register their own individual uart_port's with
+the core.  This will allow drivers to use uart_port as a pointer to a
+structure containing both the uart_port entry with their own extensions,
+thus:
+
+	struct my_port {
+		struct uart_port	port;
+		int			my_stuff;
+	};