drivers/tty/amiserial.c

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

File Facts

System
Linux kernel
Corpus path
drivers/tty/amiserial.c
Extension
.c
Size
41636 bytes
Lines
1666
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 serial_state {
	struct tty_port		tport;
	struct circ_buf		xmit;
	struct async_icount	icount;

	unsigned long		port;
	int			baud_base;
	int			custom_divisor;
	int			read_status_mask;
	int			ignore_status_mask;
	int			timeout;
	int			quot;
	int			IER; 	/* Interrupt Enable Register */
	int			MCR; 	/* Modem control register */
	u8			x_char;	/* xon/xoff character */
};

static struct tty_driver *serial_driver;

/* number of characters left in xmit buffer before we ask for more */
#define WAKEUP_CHARS 256

#define XMIT_FIFO_SIZE 1

static unsigned char current_ctl_bits;

static void change_speed(struct tty_struct *tty, struct serial_state *info,
			 const struct ktermios *old);
static void rs_wait_until_sent(struct tty_struct *tty, int timeout);


static struct serial_state serial_state;

/* some serial hardware definitions */
#define SDR_OVRUN   (1<<15)
#define SDR_RBF     (1<<14)
#define SDR_TBE     (1<<13)
#define SDR_TSRE    (1<<12)

#define SERPER_PARENB    (1<<15)

#define AC_SETCLR   (1<<15)
#define AC_UARTBRK  (1<<11)

#define SER_DTR     (1<<7)
#define SER_RTS     (1<<6)
#define SER_DCD     (1<<5)
#define SER_CTS     (1<<4)
#define SER_DSR     (1<<3)

static __inline__ void rtsdtr_ctrl(int bits)
{
    ciab.pra = ((bits & (SER_RTS | SER_DTR)) ^ (SER_RTS | SER_DTR)) | (ciab.pra & ~(SER_RTS | SER_DTR));
}

/*
 * ------------------------------------------------------------
 * rs_stop() and rs_start()
 *
 * This routines are called before setting or resetting tty->flow.stopped.
 * They enable or disable transmitter interrupts, as necessary.
 * ------------------------------------------------------------
 */
static void rs_stop(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;
	unsigned long flags;

	local_irq_save(flags);
	if (info->IER & UART_IER_THRI) {
		info->IER &= ~UART_IER_THRI;
		/* disable Tx interrupt and remove any pending interrupts */
		amiga_custom.intena = IF_TBE;
		mb();
		amiga_custom.intreq = IF_TBE;
		mb();
	}
	local_irq_restore(flags);
}

static void rs_start(struct tty_struct *tty)
{
	struct serial_state *info = tty->driver_data;
	unsigned long flags;

	local_irq_save(flags);
	if (info->xmit.head != info->xmit.tail
	    && info->xmit.buf
	    && !(info->IER & UART_IER_THRI)) {
		info->IER |= UART_IER_THRI;

Annotation

Implementation Notes