Transferred from: http://blog.csdn.net/laoliu_lcl/article/details/39967225
English document address: Myandroid/kernel_imx/documentation/serialg/driver. The translation is as follows:
The underlying serial port API
This document introduces a brief overview of some aspects of the new serial port driver. The introduction is not complete and there are any issues that can be accessed <[email protected]>.
The reference implementation is contained within the amba_pl011.c.
The underlying serial hardware driver
--------------------------------
The underlying serial hardware driver provides port information (defined in Uart_port) and a series of control methods (defined in Uart_ops) to the core serial driver. The underlying driver can also handle the broken port and provide any console support.
Console support
--------------------------------
The serial core provides some help functions, including determining the correct port structure (via Uart_get_console) and decoding the command-line parameters (Uart_parse_options).
There is also a helper function (Uart_write_console) that performs each character write function, and the newline character is translated into the CRLF sequence. Driver developers recommend using this function instead of implementing their own version.
Lock
--------------------------------
The underlying hardware driver uses Port->lock to perform the required locking function. There are some exceptions (described in the uart_ops listed below).
There are 3 locks, each with a spin lock, a tmpbuf signal per port and an overall signal.
From the core driver, Port->lock locks the following data:
Port->mctrl
Port->icount
Info->xmit.head (Circ->head)
Info->xmit.tail (Circ->tail)
The underlying driver can use the lock at any time to provide any additional locking.
The core driver uses the Info->tmpbuf_sem lock to prevent multithreaded access to the port that is written by using the Info->tmpbuf bounce buffer.
Port_sem signals are used to prevent the addition/deletion or reconfiguration of ports at inappropriate times.
Uart_ops
--------------------------------
The UART_OPS structure is an important interface between serial_core and hardware-specific drivers. Contains all the methods that control the hardware.
Tx_empty (Port)
This function checks whether the send FIFO and the shift are empty by the port described in "port". If it is empty, the function should return TIOCSER_TEMT, otherwise return 0. If the port does not support this operation, return TIOCSER_TEMT.
Lock: None
Interrupt: Depends on the caller;
This call does not hibernate.
Set_mctrl (port, Mctrl)
This function sets the serial modem control mode. Mctrl related bits are:
-Tiocm_rts RTS signal.
-TIOCM_DTR DTR signal.
-TIOCM_OUT1 OUT1 signal.
-Tiocm_out2 OUT2 signal.
-Tiocm_loop set port to loopback mode
If the corresponding bit is set, the signal should be driven to be valid, and if the bit is emptied, the signal should be driven to be invalid.
Lock: With Port->lock
Interrupt: Local Disable
This call does not hibernate.
Get_mctrl (Port)
Returns the current state of the modem control input. The output state should not be returned because the core driver tracks their state. The status information should contain:
-TIOCM_DCD State of DCD signal
-tiocm_cts State of CTS signal
-TIOCM_DSR State of the DSR signal
-tiocm_ri State of RI signal
If the signal is currently valid, the bit is set. If the port does not support CTS, DCD, or DSR, the driver should indicate that the signal is continuing to be valid. If RI is not available, the signal should not be represented as valid.
Lock: With Port->lock
Interrupt: Local Disable
This call must not hibernate.
STOP_TX (Port)
Stops sending characters. This may be due to the CTS line becoming inactive, or the TTY layer indicates that we want to stop the transmission because of the Xoff character.
The driver should stop transmitting characters as soon as possible.
Lock: With Port->lock
Interrupt: Local Disable
This call does not hibernate.
START_TX (Port)
Begins the transfer of characters.
Lock: With Port->lock
Interrupt: Local Disable
This call does not hibernate.
STOP_RX (Port)
Stops receiving characters. The port is in the process that is about to close.
Lock: With Port->lock
Interrupt: Local Disable
This call does not hibernate.
Enable_ms (Port)
Enable modem state to interrupt.
This method can be called multiple times, and modem state interrupts are disabled when the shutdown method is called.
Lock: With Port->lock
Interrupt: Local Disable
This call does not hibernate.
Break_ctl (PORT,CTL)
Control the transmission of interrupt signals. If the CTL is nonzero, the interrupt signal should be transmitted. When another call is made as a 0 CTL, this signal should be terminated.
Lock: None
Interrupt: Depends on caller
This call does not hibernate.
Startup (Port)
Crawl any interrupt resource and initialize any underlying drive state. Enable the receive port. RTS and DTR should not be enabled, and can be done by a separate call to Set_mctrl.
This method is called only when the port is initially opened.
Lock: With Port_sem
Interrupt: Global disabled.
Shutdown (port)
Disable the port, disable any potentially effective interrupt conditions, and release any interrupt resources. RTS and DTR should not be disabled; it can be done by a separate call to Set_mctrl.
Once the call is complete, the driver cannot access the port->info.
This method is called only if there are no more user ports.
Lock: With Port_sem
Interrupt: Depends on caller
Flush_buffer (Port)
Refreshes any write buffers, resets all DMA states, and stops the DMA transfer in progress.
Every time the Port->info->xmit loop buffer is cleared, it is called.
Lock: With Port->lock
Interrupt: Local Disable
This call cannot hibernate.
Set_termios (Port,termios,oldtermios)
Change the port parameters, including: Word length, parity, stop bit. Update Read_status_mask and ignore the status mask, which indicates the type of event we are interested in receiving. The corresponding Termios->c_cflag bits are:
Csize-word size
CSTOPB-2 Stop Bits
Parenb-parity Enable
Parodd-oddparity (when Parenb was in force)
Cread-enable Reception of characters (if not set,
Still receive characters from the port, but
Throwthem away.
Crtscts-if set, enable CTS status changereporting
Clocal-if not set, enable modem status change
Reporting.
The corresponding 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
Passedto 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 bit is as follows (for example, parity error):
Parity Error INPCK Ignpar
N/A 0 N/a character received, marked as
Tty_normal
None 1 N/A character received, marked as
Tty_normal
Yes 1 0 Character received,marked as
Tty_parity
Yes 1 1 character discarded
If your hardware supports hardware "soft" traffic control, other flags can be used (for example, Xon/xoff characters).
Lock: None
Interrupt: Depends on caller
This call cannot hibernate.
PM (port,state,oldstate)
Performs any power management-related activity on the specified port. The status represents the new state (defined as ACPI D0-D3), and the old State represents the previous state. Essentially, D0 represents full power, and D3 refers to power outages.
This function should not be used to crawl any resources.
This is called when the port is initially opened and eventually closed, unless the port is also the system console. This can happen even if the config_pm is not set.
Lock: None
Interrupt: Depends on the caller.
Type (port)
Returns a pointer to a string constant, describes a specified port, or returns NULL, in which case the string "Unknow" is replaced.
Lock: None
Interrupt: Depends on the caller.
Release_port (Port)
Frees any memory and IO zone resources currently in use on this port.
Lock: None
Interrupt: Depends on the caller.
Request_port (Port)
Any memory and IO zone resources required by the request port. If there is any failure, when the function returns, no resources are registered, it should return-ebusy failure.
Lock: None
Interrupt: Depends on the caller.
Config_port (Port,type)
Perform the automatic configuration steps for the required ports. ' type ' includes a bitmask of the desired configuration. Uart_config_type indicates that the port needs to be probed and identified. If the type of the port is not detected, the Port->type should be set to an established type or Port_unknown.
UART_CONFIG_IRQ indicates that the automatic configuration of interrupt signals detected by the standard kernel automatic detection technology should be used. The internal hard-connect platform with interrupts on the port is necessary within (for example, the implementation of on-chip systems).
Lock: None
Interrupt: Depends on the caller.
Verify_port (Port,serinfo)
Verify that the new serial port information contained in the Serinfo is suitable for this port type.
Lock: None
Interrupt: Depends on the caller.
IOCTL (PORT,CMD,ARG)
Executes the IOCTLs of any particular port. The IOCTL command uses the standard numbering system definition, see <asm/ioctl.h>.
Lock: None
Interrupt: Depends on the caller.
Other functions
---------------
Uart_update_timeout (Port,cflag,baud)
The updated FIFO consumption timeout, port->timeout, depends on the number of bits, parity bit, stop bit, and baud rate.
Lock: Caller expects to Port->lock
Interrupt: N/A.
Uart_get_baud_rate (Port,termios,old,min,max)
Returns the baud rate value for the specified Termios, taking into account a specific 38400 baud rate, B0 baud rate is mapped to 9600 baud rate.
If the baud rate is not at min. Max, the old baud rate is not NULL, then the original baud rate will be affected. If Min is exceeded. Max constraint, 9600 baud will be returned. Termios Update to the baud rate being used.
Note: Min.. Max must always allow 9600 baud to be selected.
Lock: Depends on caller
Interrupt: N/A.
Uart_get_divisor (Port,baud)
Returns the divisor (baud_base/baud) for the specified baud rate, rounded appropriately.
If 38400 and the custom divisor are selected, a custom divisor is returned instead.
Lock: Depends on caller
Interrupt: N/A.
Uart_match_port (PORT1,PORT2)
The utility can be used to determine if two uart_port structures have the same port.
Lock: N/A
Interrupt: N/A.
Uart_write_wakeup (Port)
The driver calls this function when the number of characters in the send buffer has been lowered to below the threshold.
Lock: Use Port->lock.
Interrupt: N/A.
Uart_register_driver (DRV)
Register the serial driver with the core driver. We register the TTY layer in turn, initializing the state of each port of the core driver.
Drv->port should be null, after a successful call, use the Uart_add_one_port function to register each port structure.
Lock: None
Interrupt: Disabled.
Uart_unregister_driver ()
Removes all claims that are driven from the core drive. If you register with the Uart_add_one_port () function, the underlying driver must use the Uart_remove_one_port () function to remove all ports.
Lock: None
Interrupt: Disabled.
Uart_suspend_port ()
Uart_resume_port ()
Uart_add_one_port ()
Uart_remove_one_port ()
Other precautions
----------------------
It is designed to remove unused entries from Uart_port one day, and the underlying driver registers its own individual uart_port with the core driver. This will allow the driver to use Uart_port as a pointer to the extension structure containing the Uart_port entry with its own:
Structmy_port {
Structuart_port Port;
int My_stuff;
};
Linux Serial driver Understanding "turn"