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

📄 ip22zilog.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	up->curregs[3] &= ~RxN_MASK;	up->curregs[5] &= ~TxN_MASK;	switch (cflag & CSIZE) {	case CS5:		up->curregs[3] |= Rx5;		up->curregs[5] |= Tx5;		up->parity_mask = 0x1f;		break;	case CS6:		up->curregs[3] |= Rx6;		up->curregs[5] |= Tx6;		up->parity_mask = 0x3f;		break;	case CS7:		up->curregs[3] |= Rx7;		up->curregs[5] |= Tx7;		up->parity_mask = 0x7f;		break;	case CS8:	default:		up->curregs[3] |= Rx8;		up->curregs[5] |= Tx8;		up->parity_mask = 0xff;		break;	};	up->curregs[4] &= ~0x0c;	if (cflag & CSTOPB)		up->curregs[4] |= SB2;	else		up->curregs[4] |= SB1;	if (cflag & PARENB)		up->curregs[4] |= PAR_ENAB;	else		up->curregs[4] &= ~PAR_ENAB;	if (!(cflag & PARODD))		up->curregs[4] |= PAR_EVEN;	else		up->curregs[4] &= ~PAR_EVEN;	up->port.read_status_mask = Rx_OVR;	if (iflag & INPCK)		up->port.read_status_mask |= CRC_ERR | PAR_ERR;	if (iflag & (BRKINT | PARMRK))		up->port.read_status_mask |= BRK_ABRT;	up->port.ignore_status_mask = 0;	if (iflag & IGNPAR)		up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;	if (iflag & IGNBRK) {		up->port.ignore_status_mask |= BRK_ABRT;		if (iflag & IGNPAR)			up->port.ignore_status_mask |= Rx_OVR;	}	if ((cflag & CREAD) == 0)		up->port.ignore_status_mask = 0xff;}/* The port lock is not held.  */static voidip22zilog_set_termios(struct uart_port *port, struct ktermios *termios,		      struct ktermios *old){	struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port;	unsigned long flags;	int baud, brg;	baud = uart_get_baud_rate(port, termios, old, 1200, 76800);	spin_lock_irqsave(&up->port.lock, flags);	brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);	ip22zilog_convert_to_zs(up, termios->c_cflag, termios->c_iflag, brg);	if (UART_ENABLE_MS(&up->port, termios->c_cflag))		up->flags |= IP22ZILOG_FLAG_MODEM_STATUS;	else		up->flags &= ~IP22ZILOG_FLAG_MODEM_STATUS;	ip22zilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));	uart_update_timeout(port, termios->c_cflag, baud);	spin_unlock_irqrestore(&up->port.lock, flags);}static const char *ip22zilog_type(struct uart_port *port){	return "IP22-Zilog";}/* We do not request/release mappings of the registers here, this * happens at early serial probe time. */static void ip22zilog_release_port(struct uart_port *port){}static int ip22zilog_request_port(struct uart_port *port){	return 0;}/* These do not need to do anything interesting either.  */static void ip22zilog_config_port(struct uart_port *port, int flags){}/* We do not support letting the user mess with the divisor, IRQ, etc. */static int ip22zilog_verify_port(struct uart_port *port, struct serial_struct *ser){	return -EINVAL;}static struct uart_ops ip22zilog_pops = {	.tx_empty	=	ip22zilog_tx_empty,	.set_mctrl	=	ip22zilog_set_mctrl,	.get_mctrl	=	ip22zilog_get_mctrl,	.stop_tx	=	ip22zilog_stop_tx,	.start_tx	=	ip22zilog_start_tx,	.stop_rx	=	ip22zilog_stop_rx,	.enable_ms	=	ip22zilog_enable_ms,	.break_ctl	=	ip22zilog_break_ctl,	.startup	=	ip22zilog_startup,	.shutdown	=	ip22zilog_shutdown,	.set_termios	=	ip22zilog_set_termios,	.type		=	ip22zilog_type,	.release_port	=	ip22zilog_release_port,	.request_port	=	ip22zilog_request_port,	.config_port	=	ip22zilog_config_port,	.verify_port	=	ip22zilog_verify_port,};static struct uart_ip22zilog_port *ip22zilog_port_table;static struct zilog_layout **ip22zilog_chip_regs;static struct uart_ip22zilog_port *ip22zilog_irq_chain;static int zilog_irq = -1;static void * __init alloc_one_table(unsigned long size){	return kzalloc(size, GFP_KERNEL);}static void __init ip22zilog_alloc_tables(void){	ip22zilog_port_table = (struct uart_ip22zilog_port *)		alloc_one_table(NUM_CHANNELS * sizeof(struct uart_ip22zilog_port));	ip22zilog_chip_regs = (struct zilog_layout **)		alloc_one_table(NUM_IP22ZILOG * sizeof(struct zilog_layout *));	if (ip22zilog_port_table == NULL || ip22zilog_chip_regs == NULL) {		panic("IP22-Zilog: Cannot allocate IP22-Zilog tables.");	}}/* Get the address of the registers for IP22-Zilog instance CHIP.  */static struct zilog_layout * __init get_zs(int chip){	unsigned long base;	if (chip < 0 || chip >= NUM_IP22ZILOG) {		panic("IP22-Zilog: Illegal chip number %d in get_zs.", chip);	}	/* Not probe-able, hard code it. */	base = (unsigned long) &sgioc->uart;	zilog_irq = SGI_SERIAL_IRQ;	request_mem_region(base, 8, "IP22-Zilog");	return (struct zilog_layout *) base;}#define ZS_PUT_CHAR_MAX_DELAY	2000	/* 10 ms */#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLEstatic void ip22zilog_put_char(struct uart_port *port, int ch){	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);	int loops = ZS_PUT_CHAR_MAX_DELAY;	/* This is a timed polling loop so do not switch the explicit	 * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM	 */	do {		unsigned char val = readb(&channel->control);		if (val & Tx_BUF_EMP) {			ZSDELAY();			break;		}		udelay(5);	} while (--loops);	writeb(ch, &channel->data);	ZSDELAY();	ZS_WSYNC(channel);}static voidip22zilog_console_write(struct console *con, const char *s, unsigned int count){	struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];	unsigned long flags;	spin_lock_irqsave(&up->port.lock, flags);	uart_console_write(&up->port, s, count, ip22zilog_put_char);	udelay(2);	spin_unlock_irqrestore(&up->port.lock, flags);}static int __init ip22zilog_console_setup(struct console *con, char *options){	struct uart_ip22zilog_port *up = &ip22zilog_port_table[con->index];	unsigned long flags;	int baud = 9600, bits = 8;	int parity = 'n';	int flow = 'n';	up->flags |= IP22ZILOG_FLAG_IS_CONS;	printk(KERN_INFO "Console: ttyS%d (IP22-Zilog)\n", con->index);	spin_lock_irqsave(&up->port.lock, flags);	up->curregs[R15] |= BRKIE;	__ip22zilog_startup(up);	spin_unlock_irqrestore(&up->port.lock, flags);	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	return uart_set_options(&up->port, con, baud, parity, bits, flow);}static struct uart_driver ip22zilog_reg;static struct console ip22zilog_console = {	.name	=	"ttyS",	.write	=	ip22zilog_console_write,	.device	=	uart_console_device,	.setup	=	ip22zilog_console_setup,	.flags	=	CON_PRINTBUFFER,	.index	=	-1,	.data	=	&ip22zilog_reg,};#endif /* CONFIG_SERIAL_IP22_ZILOG_CONSOLE */static struct uart_driver ip22zilog_reg = {	.owner		= THIS_MODULE,	.driver_name	= "serial",	.dev_name	= "ttyS",	.major		= TTY_MAJOR,	.minor		= 64,	.nr		= NUM_CHANNELS,#ifdef CONFIG_SERIAL_IP22_ZILOG_CONSOLE	.cons		= &ip22zilog_console,#endif};static void __init ip22zilog_prepare(void){	struct uart_ip22zilog_port *up;	struct zilog_layout *rp;	int channel, chip;	/*	 * Temporary fix.	 */	for (channel = 0; channel < NUM_CHANNELS; channel++)		spin_lock_init(&ip22zilog_port_table[channel].port.lock);	ip22zilog_irq_chain = &ip22zilog_port_table[NUM_CHANNELS - 1];        up = &ip22zilog_port_table[0];	for (channel = NUM_CHANNELS - 1 ; channel > 0; channel--)		up[channel].next = &up[channel - 1];	up[channel].next = NULL;	for (chip = 0; chip < NUM_IP22ZILOG; chip++) {		if (!ip22zilog_chip_regs[chip]) {			ip22zilog_chip_regs[chip] = rp = get_zs(chip);			up[(chip * 2) + 0].port.membase = (char *) &rp->channelB;			up[(chip * 2) + 1].port.membase = (char *) &rp->channelA;			/* In theory mapbase is the physical address ...  */			up[(chip * 2) + 0].port.mapbase =				(unsigned long) ioremap((unsigned long) &rp->channelB, 8);			up[(chip * 2) + 1].port.mapbase =				(unsigned long) ioremap((unsigned long) &rp->channelA, 8);		}		/* Channel A */		up[(chip * 2) + 0].port.iotype = UPIO_MEM;		up[(chip * 2) + 0].port.irq = zilog_irq;		up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;		up[(chip * 2) + 0].port.fifosize = 1;		up[(chip * 2) + 0].port.ops = &ip22zilog_pops;		up[(chip * 2) + 0].port.type = PORT_IP22ZILOG;		up[(chip * 2) + 0].port.flags = 0;		up[(chip * 2) + 0].port.line = (chip * 2) + 0;		up[(chip * 2) + 0].flags = 0;		/* Channel B */		up[(chip * 2) + 1].port.iotype = UPIO_MEM;		up[(chip * 2) + 1].port.irq = zilog_irq;		up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;		up[(chip * 2) + 1].port.fifosize = 1;		up[(chip * 2) + 1].port.ops = &ip22zilog_pops;		up[(chip * 2) + 1].port.type = PORT_IP22ZILOG;		up[(chip * 2) + 1].port.line = (chip * 2) + 1;		up[(chip * 2) + 1].flags |= IP22ZILOG_FLAG_IS_CHANNEL_A;	}	for (channel = 0; channel < NUM_CHANNELS; channel++) {		struct uart_ip22zilog_port *up = &ip22zilog_port_table[channel];		int brg;		/* Normal serial TTY. */		up->parity_mask = 0xff;		up->curregs[R1] = EXT_INT_ENAB | INT_ALL_Rx | TxINT_ENAB;		up->curregs[R4] = PAR_EVEN | X16CLK | SB1;		up->curregs[R3] = RxENAB | Rx8;		up->curregs[R5] = TxENAB | Tx8;		up->curregs[R9] = NV | MIE;		up->curregs[R10] = NRZ;		up->curregs[R11] = TCBR | RCBR;		brg = BPS_TO_BRG(9600, ZS_CLOCK / ZS_CLOCK_DIVISOR);		up->curregs[R12] = (brg & 0xff);		up->curregs[R13] = (brg >> 8) & 0xff;		up->curregs[R14] = BRENAB;	}}static int __init ip22zilog_ports_init(void){	int ret;	printk(KERN_INFO "Serial: IP22 Zilog driver (%d chips).\n", NUM_IP22ZILOG);	ip22zilog_prepare();	if (request_irq(zilog_irq, ip22zilog_interrupt, 0,			"IP22-Zilog", ip22zilog_irq_chain)) {		panic("IP22-Zilog: Unable to register zs interrupt handler.\n");	}	ret = uart_register_driver(&ip22zilog_reg);	if (ret == 0) {		int i;		for (i = 0; i < NUM_CHANNELS; i++) {			struct uart_ip22zilog_port *up = &ip22zilog_port_table[i];			uart_add_one_port(&ip22zilog_reg, &up->port);		}	}	return ret;}static int __init ip22zilog_init(void){	/* IP22 Zilog setup is hard coded, no probing to do.  */	ip22zilog_alloc_tables();	ip22zilog_ports_init();	return 0;}static void __exit ip22zilog_exit(void){	int i;	struct uart_ip22zilog_port *up;	for (i = 0; i < NUM_CHANNELS; i++) {		up = &ip22zilog_port_table[i];		uart_remove_one_port(&ip22zilog_reg, &up->port);	}	/* Free IO mem */	up = &ip22zilog_port_table[0];	for (i = 0; i < NUM_IP22ZILOG; i++) {		if (up[(i * 2) + 0].port.mapbase) {		   iounmap((void*)up[(i * 2) + 0].port.mapbase);		   up[(i * 2) + 0].port.mapbase = 0;		}		if (up[(i * 2) + 1].port.mapbase) {			iounmap((void*)up[(i * 2) + 1].port.mapbase);			up[(i * 2) + 1].port.mapbase = 0;		}	}	uart_unregister_driver(&ip22zilog_reg);}module_init(ip22zilog_init);module_exit(ip22zilog_exit);/* David wrote it but I'm to blame for the bugs ...  */MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>");MODULE_DESCRIPTION("SGI Zilog serial port driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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