serial_lh7a40x.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 709 行 · 第 1/2 页

C
709
字号
		return retval;				/* Initial modem control-line settings */	((struct uart_port_lh7a40x*) port)->statusPrev		= UR (port, UART_R_STATUS);	/* There is presently no configuration option to enable IR.	   Thus, we always disable it. */	BIT_SET (port, UART_R_CON, UARTEN | SIRDIS);	BIT_SET (port, UART_R_INTEN, RxTimeoutInt | RxInt);	return 0;}static void lh7a40xuart_shutdown (struct uart_port* port){	free_irq (port->irq, port);	BIT_CLR (port, UART_R_FCON, BRK | FEN);	BIT_CLR (port, UART_R_CON, UARTEN);}static void lh7a40xuart_set_termios (struct uart_port* port,				     struct termios* termios,				     struct termios* old){	unsigned int con;	unsigned int inten;	unsigned int fcon;	unsigned long flags;	unsigned int baud;	unsigned int quot;	baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16);	quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */	switch (termios->c_cflag & CSIZE) {	case CS5:		fcon = WLEN_5;		break;	case CS6:		fcon = WLEN_6;		break;	case CS7:		fcon = WLEN_7;		break;	case CS8:	default:		fcon = WLEN_8;		break;	}	if (termios->c_cflag & CSTOPB)		fcon |= STP2;	if (termios->c_cflag & PARENB) {		fcon |= PEN;		if (!(termios->c_cflag & PARODD))			fcon |= EPS;	}	if (port->fifosize > 1)		fcon |= FEN;	spin_lock_irqsave (&port->lock, flags);	uart_update_timeout (port, termios->c_cflag, baud);	port->read_status_mask = RxOverrunError;	if (termios->c_iflag & INPCK)		port->read_status_mask |= RxFramingError | RxParityError;	if (termios->c_iflag & (BRKINT | PARMRK))		port->read_status_mask |= RxBreak;		/* Figure mask for status we ignore */	port->ignore_status_mask = 0;	if (termios->c_iflag & IGNPAR)		port->ignore_status_mask |= RxFramingError | RxParityError;	if (termios->c_iflag & IGNBRK) {		port->ignore_status_mask |= RxBreak;		/* Ignore overrun when ignorning parity */		/* *** FIXME: is this in the right place? */		if (termios->c_iflag & IGNPAR)			port->ignore_status_mask |= RxOverrunError;	}		/* Ignore all receive errors when receive disabled */	if ((termios->c_cflag & CREAD) == 0)		port->ignore_status_mask |= RxError;	con   = UR (port, UART_R_CON);	inten = (UR (port, UART_R_INTEN) & ~ModemInt);	if (UART_ENABLE_MS (port, termios->c_cflag))		inten |= ModemInt;	BIT_CLR (port, UART_R_CON, UARTEN);	/* Disable UART */	UR (port, UART_R_INTEN) = 0;		/* Disable interrupts */	UR (port, UART_R_BRCON) = quot - 1;	/* Set baud rate divisor */	UR (port, UART_R_FCON)  = fcon;		/* Set FIFO and frame ctrl */	UR (port, UART_R_INTEN) = inten;	/* Enable interrupts */	UR (port, UART_R_CON)   = con;		/* Restore UART mode */	spin_unlock_irqrestore(&port->lock, flags);}static const char* lh7a40xuart_type (struct uart_port* port){	return port->type == PORT_LH7A40X ? "LH7A40X" : NULL;}static void lh7a40xuart_release_port (struct uart_port* port){	release_mem_region (port->mapbase, UART_REG_SIZE);}static int lh7a40xuart_request_port (struct uart_port* port){	return request_mem_region (port->mapbase, UART_REG_SIZE,				   "serial_lh7a40x") != NULL		? 0 : -EBUSY;}static void lh7a40xuart_config_port (struct uart_port* port, int flags){	if (flags & UART_CONFIG_TYPE) {		port->type = PORT_LH7A40X;		lh7a40xuart_request_port (port);	}}static int lh7a40xuart_verify_port (struct uart_port* port,				    struct serial_struct* ser){	int ret = 0;	if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)		ret = -EINVAL;	if (ser->irq < 0 || ser->irq >= NR_IRQS)		ret = -EINVAL;	if (ser->baud_base < 9600) /* *** FIXME: is this true? */		ret = -EINVAL;	return ret;}static struct uart_ops lh7a40x_uart_ops = {	.tx_empty	= lh7a40xuart_tx_empty,	.set_mctrl	= lh7a40xuart_set_mctrl,	.get_mctrl	= lh7a40xuart_get_mctrl,	.stop_tx	= lh7a40xuart_stop_tx,	.start_tx	= lh7a40xuart_start_tx,	.stop_rx	= lh7a40xuart_stop_rx,	.enable_ms	= lh7a40xuart_enable_ms,	.break_ctl	= lh7a40xuart_break_ctl,	.startup	= lh7a40xuart_startup,	.shutdown	= lh7a40xuart_shutdown,	.set_termios	= lh7a40xuart_set_termios,	.type		= lh7a40xuart_type,	.release_port	= lh7a40xuart_release_port,	.request_port	= lh7a40xuart_request_port,	.config_port	= lh7a40xuart_config_port,	.verify_port	= lh7a40xuart_verify_port,};static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = {	{		.port = {			.membase	= (void*) io_p2v (UART1_PHYS),			.mapbase	= UART1_PHYS,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART1INTR,			.uartclk	= 14745600/2,			.fifosize	= 16,			.ops		= &lh7a40x_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},	},	{		.port = {			.membase	= (void*) io_p2v (UART2_PHYS),			.mapbase	= UART2_PHYS,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART2INTR,			.uartclk	= 14745600/2,			.fifosize	= 16,			.ops		= &lh7a40x_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},	},	{		.port = {			.membase	= (void*) io_p2v (UART3_PHYS),			.mapbase	= UART3_PHYS,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART3INTR,			.uartclk	= 14745600/2,			.fifosize	= 16,			.ops		= &lh7a40x_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 2,		},	},};#ifndef CONFIG_SERIAL_LH7A40X_CONSOLE# define LH7A40X_CONSOLE NULL#else# define LH7A40X_CONSOLE &lh7a40x_consolestatic void lh7a40xuart_console_write (struct console* co,				       const char* s,				       unsigned int count){	struct uart_port* port = &lh7a40x_ports[co->index].port;	unsigned int con = UR (port, UART_R_CON);	unsigned int inten = UR (port, UART_R_INTEN);	UR (port, UART_R_INTEN) = 0;		/* Disable all interrupts */	BIT_SET (port, UART_R_CON, UARTEN | SIRDIS); /* Enable UART */	for (; count-- > 0; ++s) {		while (UR (port, UART_R_STATUS) & nTxRdy)			;		UR (port, UART_R_DATA) = *s;		if (*s == '\n') {			while ((UR (port, UART_R_STATUS) & TxBusy))				;			UR (port, UART_R_DATA) = '\r';		}	}				/* Wait until all characters are sent */	while (UR (port, UART_R_STATUS) & TxBusy)		;				/* Restore control and interrupt mask */	UR (port, UART_R_CON) = con;	UR (port, UART_R_INTEN) = inten;}static void __init lh7a40xuart_console_get_options (struct uart_port* port,						    int* baud,						    int* parity,						    int* bits){	if (UR (port, UART_R_CON) & UARTEN) {		unsigned int fcon = UR (port, UART_R_FCON);		unsigned int quot = UR (port, UART_R_BRCON) + 1;		switch (fcon & (PEN | EPS)) {		default:        *parity = 'n'; break;		case PEN:       *parity = 'o'; break;		case PEN | EPS: *parity = 'e'; break;		}		switch (fcon & WLEN) {		default:		case WLEN_8: *bits = 8; break;		case WLEN_7: *bits = 7; break;		case WLEN_6: *bits = 6; break;		case WLEN_5: *bits = 5; break;		}		*baud = port->uartclk/(16*quot);	}}static int __init lh7a40xuart_console_setup (struct console* co, char* options){	struct uart_port* port;	int baud = 38400;	int bits = 8;	int parity = 'n';	int flow = 'n';	if (co->index >= DEV_NR) /* Bounds check on device number */		co->index = 0;	port = &lh7a40x_ports[co->index].port;	if (options)		uart_parse_options (options, &baud, &parity, &bits, &flow);	else		lh7a40xuart_console_get_options (port, &baud, &parity, &bits);	return uart_set_options (port, co, baud, parity, bits, flow);}extern struct uart_driver lh7a40x_reg;static struct console lh7a40x_console = {	.name		= "ttyAM",	.write		= lh7a40xuart_console_write,	.device		= uart_console_device,	.setup		= lh7a40xuart_console_setup,	.flags		= CON_PRINTBUFFER,	.index		= -1,	.data		= &lh7a40x_reg,};static int __init lh7a40xuart_console_init(void){	register_console (&lh7a40x_console);	return 0;}console_initcall (lh7a40xuart_console_init);#endifstatic struct uart_driver lh7a40x_reg = {	.owner			= THIS_MODULE,	.driver_name		= "ttyAM",	.dev_name		= "ttyAM",	.major			= DEV_MAJOR,	.minor			= DEV_MINOR,	.nr			= DEV_NR,	.cons			= LH7A40X_CONSOLE,};static int __init lh7a40xuart_init(void){	int ret;	printk (KERN_INFO "serial: LH7A40X serial driver\n");	ret = uart_register_driver (&lh7a40x_reg);	if (ret == 0) {		int i;		for (i = 0; i < DEV_NR; i++)			uart_add_one_port (&lh7a40x_reg,					   &lh7a40x_ports[i].port);	}	return ret;}static void __exit lh7a40xuart_exit(void){	int i;	for (i = 0; i < DEV_NR; i++)		uart_remove_one_port (&lh7a40x_reg, &lh7a40x_ports[i].port);	uart_unregister_driver (&lh7a40x_reg);}module_init (lh7a40xuart_init);module_exit (lh7a40xuart_exit);MODULE_AUTHOR ("Marc Singer");MODULE_DESCRIPTION ("Sharp LH7A40X serial port driver");MODULE_LICENSE ("GPL");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?