drivers/tty/serial/samsung_tty.c

Source file repositories/reference/linux-study-clean/drivers/tty/serial/samsung_tty.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/serial/samsung_tty.c
Extension
.c
Size
72319 bytes
Lines
2858
Domain
Driver Families
Bucket
drivers/tty
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

module_init(samsung_serial_init);
module_exit(samsung_serial_exit);

#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
/*
 * Early console.
 */

static void wr_reg_barrier(const struct uart_port *port, u32 reg, u32 val)
{
	switch (port->iotype) {
	case UPIO_MEM:
		writeb(val, portaddr(port, reg));
		break;
	case UPIO_MEM32:
		writel(val, portaddr(port, reg));
		break;
	default:
		break;
	}
}

struct samsung_early_console_data {
	u32 txfull_mask;
	u32 rxfifo_mask;
};

static void samsung_early_busyuart(const struct uart_port *port)
{
	while (!(readl(port->membase + S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXFE))
		;
}

static void samsung_early_busyuart_fifo(const struct uart_port *port)
{
	const struct samsung_early_console_data *data = port->private_data;

	while (readl(port->membase + S3C2410_UFSTAT) & data->txfull_mask)
		;
}

static void samsung_early_putc(struct uart_port *port, unsigned char c)
{
	if (readl(port->membase + S3C2410_UFCON) & S3C2410_UFCON_FIFOMODE)
		samsung_early_busyuart_fifo(port);
	else
		samsung_early_busyuart(port);

	wr_reg_barrier(port, S3C2410_UTXH, c);
}

static void samsung_early_write(struct console *con, const char *s,
				unsigned int n)
{
	struct earlycon_device *dev = con->data;

	uart_console_write(&dev->port, s, n, samsung_early_putc);
}

static int samsung_early_read(struct console *con, char *s, unsigned int n)
{
	struct earlycon_device *dev = con->data;
	const struct samsung_early_console_data *data = dev->port.private_data;
	int num_read = 0;
	u32 ch, ufstat;

	while (num_read < n) {
		ufstat = rd_regl(&dev->port, S3C2410_UFSTAT);
		if (!(ufstat & data->rxfifo_mask))
			break;
		ch = rd_reg(&dev->port, S3C2410_URXH);
		if (ch == NO_POLL_CHAR)
			break;

		s[num_read++] = ch;
	}

	return num_read;
}

static int __init samsung_early_console_setup(struct earlycon_device *device,
					      const char *opt)
{
	if (!device->port.membase)
		return -ENODEV;

	device->con->write = samsung_early_write;
	device->con->read = samsung_early_read;
	return 0;
}

Annotation

Implementation Notes