drivers/tty/serial/8250/8250_ni.c
Source file repositories/reference/linux-study-clean/drivers/tty/serial/8250/8250_ni.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/tty/serial/8250/8250_ni.c- Extension
.c- Size
- 12296 bytes
- Lines
- 451
- Domain
- Driver Families
- Bucket
- drivers/tty
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/bits.hlinux/clk.hlinux/device.hlinux/io.hlinux/init.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/property.hlinux/serial_core.hlinux/types.h8250.h
Detected Declarations
struct ni16550_device_infostruct ni16550_datafunction ni16550_enable_transceiversfunction ni16550_disable_transceiversfunction ni16550_rs485_configfunction is_pmr_rs232_modefunction ni16550_config_prescalerfunction ni16550_rs485_setupfunction ni16550_port_startupfunction ni16550_port_shutdownfunction ni16550_get_regsfunction ni16550_read_fifo_sizefunction ni16550_set_mctrlfunction ni16550_probefunction PMRfunction ni16550_remove
Annotated Snippet
struct ni16550_device_info {
u32 uartclk;
u8 prescaler;
u8 flags;
};
struct ni16550_data {
int line;
struct clk *clk;
};
static int ni16550_enable_transceivers(struct uart_port *port)
{
u8 pcr;
pcr = port->serial_in(port, NI16550_PCR_OFFSET);
pcr |= NI16550_PCR_TXVR_ENABLE_BIT;
dev_dbg(port->dev, "enable transceivers: write pcr: 0x%02x\n", pcr);
port->serial_out(port, NI16550_PCR_OFFSET, pcr);
return 0;
}
static int ni16550_disable_transceivers(struct uart_port *port)
{
u8 pcr;
pcr = serial_port_in(port, NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_TXVR_ENABLE_BIT;
dev_dbg(port->dev, "disable transceivers: write pcr: 0x%02x\n", pcr);
serial_port_out(port, NI16550_PCR_OFFSET, pcr);
return 0;
}
static int ni16550_rs485_config(struct uart_port *port,
struct ktermios *termios,
struct serial_rs485 *rs485)
{
struct uart_8250_port *up = container_of(port, struct uart_8250_port, port);
u8 pcr;
pcr = serial_port_in(port, NI16550_PCR_OFFSET);
pcr &= ~NI16550_PCR_WIRE_MODE_MASK;
if ((rs485->flags & SER_RS485_MODE_RS422) ||
!(rs485->flags & SER_RS485_ENABLED)) {
/* RS-422 */
pcr |= NI16550_PCR_RS422;
up->acr &= ~NI16550_ACR_AUTO_DTR_EN;
} else {
/* RS-485 2-wire Auto */
pcr |= NI16550_PCR_AUTO_RS485;
up->acr |= NI16550_ACR_AUTO_DTR_EN;
}
dev_dbg(port->dev, "config rs485: write pcr: 0x%02x, acr: %02x\n", pcr, up->acr);
serial_port_out(port, NI16550_PCR_OFFSET, pcr);
serial_icr_write(up, UART_ACR, up->acr);
return 0;
}
static bool is_pmr_rs232_mode(struct uart_8250_port *up)
{
u8 pmr = serial_in(up, NI16550_PMR_OFFSET);
u8 pmr_mode = pmr & NI16550_PMR_MODE_MASK;
u8 pmr_cap = pmr & NI16550_PMR_CAP_MASK;
/*
* If the PMR is not implemented, then by default NI UARTs are
* connected to RS-485 transceivers
*/
if (pmr_cap == NI16550_PMR_NOT_IMPL)
return false;
if (pmr_cap == NI16550_PMR_CAP_DUAL)
/*
* If the port is dual-mode capable, then read the mode bit
* to know the current mode
*/
return pmr_mode == NI16550_PMR_MODE_RS232;
/*
* If it is not dual-mode capable, then decide based on the
* capability
*/
return pmr_cap == NI16550_PMR_CAP_RS232;
}
static void ni16550_config_prescaler(struct uart_8250_port *up,
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bits.h`, `linux/clk.h`, `linux/device.h`, `linux/io.h`, `linux/init.h`, `linux/mod_devicetable.h`, `linux/module.h`.
- Detected declarations: `struct ni16550_device_info`, `struct ni16550_data`, `function ni16550_enable_transceivers`, `function ni16550_disable_transceivers`, `function ni16550_rs485_config`, `function is_pmr_rs232_mode`, `function ni16550_config_prescaler`, `function ni16550_rs485_setup`, `function ni16550_port_startup`, `function ni16550_port_shutdown`.
- Atlas domain: Driver Families / drivers/tty.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.