⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ep93xx_amba.c

📁 Cirrus logic ep9302 本机串口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
}static unsigned int csambauart_get_mctrl(struct uart_port *port){	unsigned int result = 0;	unsigned int status;	status = UART_GET_FR(port);	if (status & AMBA_UARTFR_DCD)		result |= TIOCM_CAR;	if (status & AMBA_UARTFR_DSR)		result |= TIOCM_DSR;	if (status & AMBA_UARTFR_CTS)		result |= TIOCM_CTS;	return result;}static void csambauart_set_mctrl(struct uart_port *port, unsigned int mctrl){	struct uart_amba_port *uap = (struct uart_amba_port *)port;	unsigned int ctrl = 0;		/* If there's no RTS and DTR for this UART, do nothing here */	if(	(uap->rts_mask == 0) && (uap->dtr_mask == 0) )		return;      if ((mctrl & TIOCM_RTS) == 0)		ctrl |= uap->rts_mask;	    if ((mctrl & TIOCM_DTR) == 0)		ctrl |= uap->dtr_mask;    	UART_PUT_MCR(ctrl, port);}static void csambauart_break_ctl(struct uart_port *port, int break_state){	unsigned long flags;	unsigned int lcr_h;	spin_lock_irqsave(&port->lock, flags);	lcr_h = UART_GET_LCRH(port);	if (break_state == -1)		lcr_h |= AMBA_UARTLCR_H_BRK;	else		lcr_h &= ~AMBA_UARTLCR_H_BRK;	UART_PUT_LCRH(port, lcr_h);	spin_unlock_irqrestore(&port->lock, flags);}static int csambauart_startup(struct uart_port *port){	struct uart_amba_port *uap = (struct uart_amba_port *)port;    int retval;    csambauart_enable_clocks(port);	/*	 * Allocate the IRQ	 */	retval = request_irq(port->irq, csambauart_int, 0, "amba", port);	if (retval)		return retval;	/*	 * initialise the old status of the modem signals	 */	uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;	/*	 * Finally, enable interrupts	 */	UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |			  AMBA_UARTCR_RTIE);	return 0;}static void csambauart_shutdown(struct uart_port *port){	/*	 * Free the interrupt	 */	free_irq(port->irq, port);	/*	 * disable all interrupts, disable the port	 */	UART_PUT_CR(port, 0);	/* disable break condition and fifos */	UART_PUT_LCRH(port, UART_GET_LCRH(port) &		~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));	csambauart_disable_clocks( port );}static void csambauart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot){	unsigned int lcr_h, old_cr;	unsigned long flags;	/*	 * Before we change speed, check to see if this UART is currently in use.	 * If it is, wait for the fifo to empty out before changing speed.	 */	if( csambauart_is_port_enabled( port ) )	{		do{			flags = UART_GET_FR(port);		} while( flags & UARTFR_BUSY );	}	else	{		csambauart_enable_clocks( port );	}	#if DEBUG	printk("ambauart_set_cflag(0x%x) called\n", cflag);#endif	/* byte size and parity */	switch (cflag & CSIZE) {	case CS5:		lcr_h = AMBA_UARTLCR_H_WLEN_5;		break;	case CS6:		lcr_h = AMBA_UARTLCR_H_WLEN_6;		break;	case CS7:		lcr_h = AMBA_UARTLCR_H_WLEN_7;		break;	default: // CS8		lcr_h = AMBA_UARTLCR_H_WLEN_8;		break;	}	if (cflag & CSTOPB)		lcr_h |= AMBA_UARTLCR_H_STP2;	if (cflag & PARENB) {		lcr_h |= AMBA_UARTLCR_H_PEN;		if (!(cflag & PARODD))			lcr_h |= AMBA_UARTLCR_H_EPS;	}	if (port->fifosize > 1)		lcr_h |= AMBA_UARTLCR_H_FEN;	spin_lock_irqsave(&port->lock, flags);	port->read_status_mask = AMBA_UARTRSR_OE;	if (iflag & INPCK)		port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;	if (iflag & (BRKINT | PARMRK))		port->read_status_mask |= AMBA_UARTRSR_BE;	/*	 * Characters to ignore	 */	port->ignore_status_mask = 0;	if (iflag & IGNPAR)		port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;	if (iflag & IGNBRK) {		port->ignore_status_mask |= AMBA_UARTRSR_BE;		/*		 * If we're ignoring parity and break indicators,		 * ignore overruns too (for real raw support).		 */		if (iflag & IGNPAR)			port->ignore_status_mask |= AMBA_UARTRSR_OE;	}	/*	 * Ignore all characters if CREAD is not set.	 */	if ((cflag & CREAD) == 0)		port->ignore_status_mask |= UART_DUMMY_RSR_RX;	old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;	if (UART_ENABLE_MS(port, cflag))		old_cr |= AMBA_UARTCR_MSIE;	UART_PUT_CR(port, 0);	UART_PUT_LCRM(port, 0 );	UART_PUT_LCRL(port, 0 );	UART_PUT_LCRH(port, 0 );	UART_CLEAR_ECR(port);	/* Set baud rate */	quot -= 1;	UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));	UART_PUT_LCRL(port, (quot & 0xff));	/*	 * ----------v----------v----------v----------v-----	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L	 * ----------^----------^----------^----------^-----	 */	UART_PUT_LCRH(port, lcr_h);	UART_PUT_CR(port, old_cr);	spin_unlock_irqrestore(&port->lock, flags);}static const char *csambauart_type(struct uart_port *port){	return port->type == PORT_AMBA ? "AMBA" : NULL;}/* * Release the memory region(s) being used by 'port' */static void csambauart_release_port(struct uart_port *port){	release_mem_region(port->mapbase, UART_PORT_SIZE);}/* * Request the memory region(s) being used by 'port' */static int csambauart_request_port(struct uart_port *port){	return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")			!= NULL ? 0 : -EBUSY;}/* * Configure/autoconfigure the port. */static void csambauart_config_port(struct uart_port *port, int flags){	if (flags & UART_CONFIG_TYPE) {		port->type = PORT_AMBA;		csambauart_request_port(port);	}}/* * verify the new serial_struct (for TIOCSSERIAL). */static int csambauart_verify_port(struct uart_port *port, struct serial_struct *ser){	int ret = 0;	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)		ret = -EINVAL;	if (ser->irq < 0 || ser->irq >= NR_IRQS)		ret = -EINVAL;	if (ser->baud_base < 9600)		ret = -EINVAL;	return ret;}static struct uart_ops amba_pops = {	.tx_empty	= csambauart_tx_empty,	.set_mctrl	= csambauart_set_mctrl,	.get_mctrl	= csambauart_get_mctrl,	.stop_tx	= csambauart_stop_tx,	.start_tx	= csambauart_start_tx,	.stop_rx	= csambauart_stop_rx,	.enable_ms	= csambauart_enable_ms,	.break_ctl	= csambauart_break_ctl,	.startup	= csambauart_startup,	.shutdown	= csambauart_shutdown,	.change_speed	= csambauart_change_speed,	.type		= csambauart_type,	.release_port	= csambauart_release_port,	.request_port	= csambauart_request_port,	.config_port	= csambauart_config_port,	.verify_port	= csambauart_verify_port,};static struct uart_amba_port amba_ports[UART_NR] = {	{		.port	= {			.membase	= (void *)IO_ADDRESS(UART1_BASE),			.mapbase	= UART1_BASE,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART1,			.uartclk	= 14745600,			.fifosize	= 8,		    .ops		= &amba_pops,		    .flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,        	},		.dtr_mask	= 1 << 0,		.rts_mask	= 1 << 1,	},#if !defined(CONFIG_EP93XX_IRDA)		{		.port	= {			.membase	= (void *)IO_ADDRESS(UART2_BASE),			.mapbase	= UART2_BASE,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART2,			.uartclk	= 14745600,			.fifosize	= 8,			.ops		= &amba_pops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.dtr_mask	= 0,		.rts_mask	= 0,	},#endif		{		.port	= {			.membase	= (void *)IO_ADDRESS(UART3_BASE),			.mapbase	= UART3_BASE,			.iotype		= SERIAL_IO_MEM,			.irq		= IRQ_UART3,			.uartclk	= 14745600,			.fifosize	= 8,			.ops		= &amba_pops,			.flags		= ASYNC_BOOT_AUTOCONF,#if !defined(CONFIG_EP93XX_IRDA)						.line		= 2,#else			.line		= 1,#endif					},		.dtr_mask	= 0,		.rts_mask	= 0,	}};static struct uart_driver amba_reg = {	.owner			= THIS_MODULE,	.normal_major		= SERIAL_AMBA_MAJOR,#ifdef CONFIG_DEVFS_FS	.normal_name		= "ttyAM%d",	.callout_name		= "cuaam%d",#else	.normal_name		= "ttyAM",	.callout_name		= "cuaam",#endif	.normal_driver		= &normal,	.callout_major		= CALLOUT_AMBA_MAJOR,	.callout_driver		= &callout,	.table			= cs_amba_table,	.termios		= cs_amba_termios,	.termios_locked	= cs_amba_termios_locked,	.minor			= SERIAL_AMBA_MINOR,	.nr				= UART_NR,	.cons			= AMBA_CONSOLE,};static int __init csambauart_init(void){	int ret;	ret = uart_register_driver(&amba_reg);	if (ret == 0) {		int i;		for (i = 0; i < UART_NR; i++)			uart_add_one_port(&amba_reg, &amba_ports[i].port);	}	return ret;}static void __exit csambauart_exit(void){	int i;	for (i = 0; i < UART_NR; i++)		uart_remove_one_port(&amba_reg, &amba_ports[i].port);	uart_unregister_driver(&amba_reg);}module_init(csambauart_init);module_exit(csambauart_exit);EXPORT_NO_SYMBOLS;MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd/Cirrus Logic, Inc.");MODULE_DESCRIPTION("EP9312 ARM AMBA serial port driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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