drivers/tty/serial/8250/8250_dw.c

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

File Facts

System
Linux kernel
Corpus path
drivers/tty/serial/8250/8250_dw.c
Extension
.c
Size
27207 bytes
Lines
1017
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct dw8250_platform_data {
	u8 usr_reg;
	u32 cpr_value;
	unsigned int quirks;
};

struct dw8250_data {
	struct dw8250_port_data	data;
	const struct dw8250_platform_data *pdata;

	u32			msr_mask_on;
	u32			msr_mask_off;
	struct clk		*clk;
	struct clk		*pclk;
	struct notifier_block	clk_notifier;
	struct work_struct	clk_work;
	struct reset_control	*rst;

	unsigned int		skip_autocfg:1;
	unsigned int		uart_16550_compatible:1;
	unsigned int		in_idle:1;

	u8			no_int_count;
};

static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
{
	return container_of(data, struct dw8250_data, data);
}

static inline struct dw8250_data *clk_to_dw8250_data(struct notifier_block *nb)
{
	return container_of(nb, struct dw8250_data, clk_notifier);
}

static inline struct dw8250_data *work_to_dw8250_data(struct work_struct *work)
{
	return container_of(work, struct dw8250_data, clk_work);
}

static inline u32 dw8250_modify_msr(struct uart_port *p, unsigned int offset, u32 value)
{
	struct dw8250_data *d = to_dw8250_data(p->private_data);

	/* Override any modem control signals if needed */
	if (offset == UART_MSR) {
		value |= d->msr_mask_on;
		value &= ~d->msr_mask_off;
	}

	return value;
}

static void dw8250_idle_exit(struct uart_port *p)
{
	struct dw8250_data *d = to_dw8250_data(p->private_data);
	struct uart_8250_port *up = up_to_u8250p(p);

	if (d->uart_16550_compatible)
		return;

	if (up->capabilities & UART_CAP_FIFO)
		serial_port_out(p, UART_FCR, up->fcr);
	serial_port_out(p, UART_MCR, up->mcr);
	serial_port_out(p, UART_IER, up->ier);

	/* DMA Rx is restarted by IRQ handler as needed. */
	if (up->dma)
		serial8250_tx_dma_resume(up);

	d->in_idle = 0;
}

/*
 * Ensure BUSY is not asserted. If DW UART is configured with
 * !uart_16550_compatible, the writes to LCR, DLL, and DLH fail while
 * BUSY is asserted.
 *
 * Context: port's lock must be held
 */
static int dw8250_idle_enter(struct uart_port *p)
{
	struct dw8250_data *d = to_dw8250_data(p->private_data);
	unsigned int usr_reg = d->pdata ? d->pdata->usr_reg : DW_UART_USR;
	struct uart_8250_port *up = up_to_u8250p(p);
	int retries;
	u32 lsr;

	lockdep_assert_held_once(&p->lock);

Annotation

Implementation Notes