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

📄 uart00.c

📁 IXP425 平台下嵌入式LINUX的串口的驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (break_state == -1)		mcr |= UART_MCR_BR_MSK;	else		mcr &= ~UART_MCR_BR_MSK;	UART_PUT_MCR(port, mcr);}static inline u_int uart_calculate_quot(struct uart_info *info, u_int baud){	u_int quot;	/* Special case: B0 rate */	if (!baud)		baud = 9600;	quot = (info->port->uartclk / (16 * baud)-1)  ;	return quot;}static void uart00_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot){	u_int uart_mc=0, old_ies;	unsigned long flags;#ifdef DEBUG	printk("uart00_set_cflag(0x%x) called\n", cflag);#endif	/* byte size and parity */	switch (cflag & CSIZE) {	case CS5: uart_mc = UART_MC_CLS_CHARLEN_5; break;	case CS6: uart_mc = UART_MC_CLS_CHARLEN_6; break;	case CS7: uart_mc = UART_MC_CLS_CHARLEN_7; break;	default:  uart_mc = UART_MC_CLS_CHARLEN_8; break; // CS8	}	if (cflag & CSTOPB)		uart_mc|= UART_MC_ST_TWO;	if (cflag & PARENB) {		uart_mc |= UART_MC_PE_MSK;		if (!(cflag & PARODD))			uart_mc |= UART_MC_EP_MSK;	}	port->read_status_mask = UART_RDS_OE_MSK;	if (iflag & INPCK)		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;	if (iflag & (BRKINT | PARMRK))		port->read_status_mask |= UART_RDS_BI_MSK;	/*	 * Characters to ignore	 */	port->ignore_status_mask = 0;	if (iflag & IGNPAR)		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;	if (iflag & IGNBRK) {		port->ignore_status_mask |= UART_RDS_BI_MSK;		/*		 * If we're ignoring parity and break indicators,		 * ignore overruns to (for real raw support).		 */		if (iflag & IGNPAR)			port->ignore_status_mask |= UART_RDS_OE_MSK;	}	/* first, disable everything */	save_flags(flags); cli();	old_ies = UART_GET_IES(port); 	if ((port->flags & ASYNC_HARDPPS_CD) ||	    (cflag & CRTSCTS) || !(cflag & CLOCAL))		old_ies |= UART_IES_ME_MSK;	/* Set baud rate */	UART_PUT_DIV_LO(port, (quot & 0xff));	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));   	UART_PUT_MC(port, uart_mc);	UART_PUT_IES(port, old_ies);	restore_flags(flags);}static int uart00_startup(struct uart_port *port, struct uart_info *info){	int retval;	/* 	 * Use iobase to store a pointer to info. We need this to start a 	 * transmission as the tranmittr interrupt is only generated on	 * the transition to the idle state 	 */	port->iobase=(u_int)info;		/*	 * Allocate the IRQ	 */	retval = request_irq(port->irq, uart00_int, 0, "uart00", info);	if (retval)		return retval;	/*	 * Finally, enable interrupts. Use the TII interrupt to minimise 	 * the number of interrupts generated. If higher performance is 	 * needed, consider using the TI interrupt with a suitable FIFO	 * threshold	 */	UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);	return 0;}static void uart00_shutdown(struct uart_port *port, struct uart_info *info){	/*	 * disable all interrupts, disable the port	 */	UART_PUT_IEC(port, 0xff);	/* disable break condition and fifos */	UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);	/*	 * Free the interrupt	 */	free_irq(port->irq, info);}static const char *uart00_type(struct uart_port *port){	return port->type == PORT_UART00 ? "UART00" : NULL;}/* * Release the memory region(s) being used by 'port' */static void uart00_release_port(struct uart_port *port){	release_mem_region(port->mapbase, UART_PORT_SIZE);#ifdef CONFIG_ARCH_CAMELOT	if(port->membase!=(void*)IO_ADDRESS(EXC_UART00_BASE)){		iounmap(port->membase);	}#endif}/* * Request the memory region(s) being used by 'port' */static int uart00_request_port(struct uart_port *port){	int result;	result = request_mem_region(port->mapbase, UART_PORT_SIZE,				    "serial_uart00") != NULL ? 0 : -EBUSY;	if (result)		return result;	port->membase = ioremap(port->mapbase, SZ_4K);	if (!port->membase) {		printk(KERN_ERR "serial00: cannot map io memory\n");		release_mem_region(port->mapbase, UART_PORT_SIZE);	}	return port->membase ? 0 : -ENOMEM;}/* * Configure/autoconfigure the port. */static void uart00_config_port(struct uart_port *port, int flags){	if (flags & UART_CONFIG_TYPE) {		if (uart00_request_port(port) == 0)			port->type = PORT_UART00;	}}/* * verify the new serial_struct (for TIOCSSERIAL). */static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser){	int ret = 0;	if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)		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 uart00_pops = {	tx_empty:	uart00_tx_empty,	set_mctrl:	uart00_set_mctrl_null,	get_mctrl:	uart00_get_mctrl,	stop_tx:	uart00_stop_tx,	start_tx:	uart00_start_tx,	stop_rx:	uart00_stop_rx,	enable_ms:	uart00_enable_ms,	break_ctl:	uart00_break_ctl,	startup:	uart00_startup,	shutdown:	uart00_shutdown,	change_speed:	uart00_change_speed,	type:		uart00_type,	release_port:	uart00_release_port,	request_port:	uart00_request_port,	config_port:	uart00_config_port,	verify_port:	uart00_verify_port,};#ifdef CONFIG_ARCH_CAMELOTstatic struct uart_port epxa10db_port = {	membase:	(void*)IO_ADDRESS(EXC_UART00_BASE),	mapbase:        EXC_UART00_BASE,	iotype:		SERIAL_IO_MEM,	irq:		IRQ_UART,	uartclk:	EXC_AHB2_CLK_FREQUENCY,	fifosize:	16,	ops:		&uart00_pops,	flags:          ASYNC_BOOT_AUTOCONF,};#endif#ifdef CONFIG_SERIAL_UART00_CONSOLEstatic void uart00_console_write(struct console *co, const char *s, unsigned count){#ifdef CONFIG_ARCH_CAMELOT	struct uart_port *port = &epxa10db_port;	unsigned int status, old_ies;	int i;	/*	 *	First save the CR then disable the interrupts	 */	old_ies = UART_GET_IES(port);	UART_PUT_IEC(port,0xff);	/*	 *	Now, do each character	 */	for (i = 0; i < count; i++) {		do {			status = UART_GET_TSR(port);		} while (!UART_TX_READY(status));		UART_PUT_CHAR(port, s[i]);		if (s[i] == '\n') {			do {				status = UART_GET_TSR(port);			} while (!UART_TX_READY(status));			UART_PUT_CHAR(port, '\r');		}	}	/*	 *	Finally, wait for transmitter to become empty	 *	and restore the IES	 */	do {		status = UART_GET_TSR(port);	} while (status & UART_TSR_TX_LEVEL_MSK);	UART_PUT_IES(port, old_ies);#endif}static kdev_t uart00_console_device(struct console *co){	return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index);}static void /*__init*/ uart00_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits){	u_int uart_mc, quot;	uart_mc= UART_GET_MC(port);	*parity = 'n';	if (uart_mc & UART_MC_PE_MSK) {		if (uart_mc & UART_MC_EP_MSK)			*parity = 'e';		else			*parity = 'o';	}	switch (uart_mc & UART_MC_CLS_MSK){	case UART_MC_CLS_CHARLEN_5:		*bits = 5;		break;	case UART_MC_CLS_CHARLEN_6:		*bits = 6;		break;	case UART_MC_CLS_CHARLEN_7:		*bits = 7;		break;	case UART_MC_CLS_CHARLEN_8:		*bits = 8;		break;	}	quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);	*baud = port->uartclk / (16 *quot );}static int __init uart00_console_setup(struct console *co, char *options){	struct uart_port *port;	int baud = 38400;	int bits = 8;	int parity = 'n';	int flow= 'n';#ifdef CONFIG_ARCH_CAMELOT	/*	 * Check whether an invalid uart number has been specified, and	 * if so, search for the first available port that does have	 * console support.	 */	port = &epxa10db_port;	co->index = 0;#else	return -ENODEV;#endif	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	else		uart00_console_get_options(port, &baud, &parity, &bits);	return uart_set_options(port, co, baud, parity, bits, flow);}static struct console uart00_console = {	name:           SERIAL_UART00_NAME,	write:		uart00_console_write,	device:		uart00_console_device,	setup:		uart00_console_setup,	flags:		CON_PRINTBUFFER,	index:		0,};void __init uart00_console_init(void){	register_console(&uart00_console);}#define UART00_CONSOLE	&uart00_console#else#define UART00_CONSOLE	NULL#endifstatic struct uart_driver uart00_reg = {	owner:                  NULL,	normal_major:		SERIAL_UART00_MAJOR,	normal_name:		SERIAL_UART00_NAME,	normal_driver:		&normal,	callout_major:		CALLOUT_UART00_MAJOR,	callout_name:		CALLOUT_UART00_NAME,	callout_driver:		&callout,	table:			uart00_table,	termios:		uart00_termios,	termios_locked:		uart00_termios_locked,	minor:			SERIAL_UART00_MINOR,	nr:			UART_NR,#ifdef CONFIG_ARCH_CAMELOT	port:			&epxa10db_port,#endif	state:			NULL,	cons:			UART00_CONSOLE,};static int __init uart00_init(void){	printk(KERN_WARNING "serial_uart00:Using temporary major/minor pairs - these WILL change in the future\n");	return uart_register_driver(&uart00_reg);}__initcall(uart00_init);

⌨️ 快捷键说明

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