sh-sci.c

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

C
1,633
字号
#endif}static int sci_verify_port(struct uart_port *port, struct serial_struct *ser){	struct sci_port *s = &sci_ports[port->line];	if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS)		return -EINVAL;	if (ser->baud_base < 2400)		/* No paper tape reader for Mitch.. */		return -EINVAL;	return 0;}static struct uart_ops sci_uart_ops = {	.tx_empty	= sci_tx_empty,	.set_mctrl	= sci_set_mctrl,	.get_mctrl	= sci_get_mctrl,	.start_tx	= sci_start_tx,	.stop_tx	= sci_stop_tx,	.stop_rx	= sci_stop_rx,	.enable_ms	= sci_enable_ms,	.break_ctl	= sci_break_ctl,	.startup	= sci_startup,	.shutdown	= sci_shutdown,	.set_termios	= sci_set_termios,	.type		= sci_type,	.release_port	= sci_release_port,	.request_port	= sci_request_port,	.config_port	= sci_config_port,	.verify_port	= sci_verify_port,};static struct sci_port sci_ports[SCI_NPORTS] = {#if defined(CONFIG_CPU_SUBTYPE_SH7708)	{		.port	= {			.membase	= (void *)0xfffffe80,			.mapbase	= 0xfffffe80,			.iotype		= SERIAL_IO_MEM,			.irq		= 25,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCI,		.irqs		= SCI_IRQS,		.init_pins	= sci_init_pins_sci,	},#elif defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709)	{		.port	= {			.membase	= (void *)0xfffffe80,			.mapbase	= 0xfffffe80,			.iotype		= SERIAL_IO_MEM,			.irq		= 25,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCI,		.irqs		= SCI_IRQS,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0xa4000150,			.mapbase	= 0xa4000150,			.iotype		= SERIAL_IO_MEM,			.irq		= 59,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCIF,		.irqs		= SH3_SCIF_IRQS,		.init_pins	= sci_init_pins_scif,	},	{		.port	= {			.membase	= (void *)0xa4000140,			.mapbase	= 0xa4000140,			.iotype		= SERIAL_IO_MEM,			.irq		= 55,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 2,		},		.type		= PORT_IRDA,		.irqs		= SH3_IRDA_IRQS,		.init_pins	= sci_init_pins_irda,	}#elif defined(CONFIG_CPU_SUBTYPE_SH7300)	{		.port	= {			.membase	= (void *)0xA4430000,			.mapbase	= 0xA4430000,			.iotype		= SERIAL_IO_MEM,			.irq		= 25,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCIF,		.irqs		= SH7300_SCIF0_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_SH_RTS7751R2D)	{		.port	= {			.membase	= (void *)0xffe80000,			.mapbase	= 0xffe80000,			.iotype		= SERIAL_IO_MEM,			.irq		= 43,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCIF,		.irqs		= SH4_SCIF_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7751)	{		.port	= {			.membase	= (void *)0xffe00000,			.mapbase	= 0xffe00000,			.iotype		= SERIAL_IO_MEM,			.irq		= 25,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCI,		.irqs		= SCI_IRQS,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0xffe80000,			.mapbase	= 0xffe80000,			.iotype		= SERIAL_IO_MEM,			.irq		= 43,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCIF,		.irqs		= SH4_SCIF_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_CPU_SUBTYPE_SH7760)	{		.port	= {			.membase	= (void *)0xfe600000,			.mapbase	= 0xfe600000,			.iotype		= SERIAL_IO_MEM,			.irq		= 55,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCIF,		.irqs		= SH7760_SCIF0_IRQS,		.init_pins	= sci_init_pins_scif,	},	{		.port	= {			.membase	= (void *)0xfe610000,			.mapbase	= 0xfe610000,			.iotype		= SERIAL_IO_MEM,			.irq		= 75,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCIF,		.irqs		= SH7760_SCIF1_IRQS,		.init_pins	= sci_init_pins_scif,	},	{		.port	= {			.membase	= (void *)0xfe620000,			.mapbase	= 0xfe620000,			.iotype		= SERIAL_IO_MEM,			.irq		= 79,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 2,		},		.type		= PORT_SCIF,		.irqs		= SH7760_SCIF2_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_CPU_SUBTYPE_ST40STB1)	{		.port	= {			.membase	= (void *)0xffe00000,			.mapbase	= 0xffe00000,			.iotype		= SERIAL_IO_MEM,			.irq		= 26,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCIF,		.irqs		= STB1_SCIF1_IRQS,		.init_pins	= sci_init_pins_scif,	},	{		.port	= {			.membase	= (void *)0xffe80000,			.mapbase	= 0xffe80000,			.iotype		= SERIAL_IO_MEM,			.irq		= 43,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCIF,		.irqs		= SH4_SCIF_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)	{		.port	= {			.iotype		= SERIAL_IO_MEM,			.irq		= 42,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCIF,		.irqs		= SH5_SCIF_IRQS,		.init_pins	= sci_init_pins_scif,	},#elif defined(CONFIG_H83007) || defined(CONFIG_H83068)	{		.port	= {			.membase	= (void *)0x00ffffb0,			.mapbase	= 0x00ffffb0,			.iotype		= SERIAL_IO_MEM,			.irq		= 54,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCI,		.irqs		= H8300H_SCI_IRQS0,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0x00ffffb8,			.mapbase	= 0x00ffffb8,			.iotype		= SERIAL_IO_MEM,			.irq		= 58,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCI,		.irqs		= H8300H_SCI_IRQS1,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0x00ffffc0,			.mapbase	= 0x00ffffc0,			.iotype		= SERIAL_IO_MEM,			.irq		= 62,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 2,		},		.type		= PORT_SCI,		.irqs		= H8300H_SCI_IRQS2,		.init_pins	= sci_init_pins_sci,	},#elif defined(CONFIG_H8S2678)	{		.port	= {			.membase	= (void *)0x00ffff78,			.mapbase	= 0x00ffff78,			.iotype		= SERIAL_IO_MEM,			.irq		= 90,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 0,		},		.type		= PORT_SCI,		.irqs		= H8S_SCI_IRQS0,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0x00ffff80,			.mapbase	= 0x00ffff80,			.iotype		= SERIAL_IO_MEM,			.irq		= 94,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 1,		},		.type		= PORT_SCI,		.irqs		= H8S_SCI_IRQS1,		.init_pins	= sci_init_pins_sci,	},	{		.port	= {			.membase	= (void *)0x00ffff88,			.mapbase	= 0x00ffff88,			.iotype		= SERIAL_IO_MEM,			.irq		= 98,			.ops		= &sci_uart_ops,			.flags		= ASYNC_BOOT_AUTOCONF,			.line		= 2,		},		.type		= PORT_SCI,		.irqs		= H8S_SCI_IRQS2,		.init_pins	= sci_init_pins_sci,	},#else#error "CPU subtype not defined"#endif};#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE/* *	Print a string to the serial port trying not to disturb *	any possible real use of the port... */static void serial_console_write(struct console *co, const char *s,				 unsigned count){	put_string(serial_console_port, s, count);}static int __init serial_console_setup(struct console *co, char *options){	struct uart_port *port;	int baud = 115200;	int bits = 8;	int parity = 'n';	int flow = 'n';	int ret;	if (co->index >= SCI_NPORTS)		co->index = 0;	serial_console_port = &sci_ports[co->index];	port = &serial_console_port->port;	port->type = serial_console_port->type;#ifdef CONFIG_SUPERH64	/* This is especially needed on sh64 to remap the SCIF */	sci_config_port(port, 0);#endif	/*	 * We need to set the initial uartclk here, since otherwise it will	 * only ever be setup at sci_init() time.	 */#if !defined(__H8300H__) && !defined(__H8300S__)	port->uartclk = current_cpu_data.module_clock * 16;#else	port->uartclk = CONFIG_CPU_CLOCK;#endif#if defined(__H8300S__)	h8300_sci_enable(port, sci_enable);#endif	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	ret = uart_set_options(port, co, baud, parity, bits, flow);#if defined(__H8300H__) || defined(__H8300S__)	/* disable rx interrupt */	if (ret == 0)		sci_stop_rx(port);#endif	return ret;}static struct console serial_console = {	.name		= "ttySC",	.device		= uart_console_device,	.write		= serial_console_write,	.setup		= serial_console_setup,	.flags		= CON_PRINTBUFFER,	.index		= -1,	.data		= &sci_uart_driver,};static int __init sci_console_init(void){	register_console(&serial_console);	return 0;}console_initcall(sci_console_init);#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */#ifdef CONFIG_SH_KGDB/* * FIXME: Most of this can go away.. at the moment, we rely on * arch/sh/kernel/setup.c to do the command line parsing for kgdb, though * most of that can easily be done here instead. * * For the time being, just accept the values that were parsed earlier.. */static void __init kgdb_console_get_options(struct uart_port *port, int *baud,					    int *parity, int *bits){	*baud = kgdb_baud;	*parity = tolower(kgdb_parity);	*bits = kgdb_bits - '0';}/* * The naming here is somewhat misleading, since kgdb_console_setup() takes * care of the early-on initialization for kgdb, regardless of whether we * actually use kgdb as a console or not. * * On the plus side, this lets us kill off the old kgdb_sci_setup() nonsense. */int __init kgdb_console_setup(struct console *co, char *options){	struct uart_port *port = &sci_ports[kgdb_portnum].port;	int baud = 38400;	int bits = 8;	int parity = 'n';	int flow = 'n';	if (co->index >= SCI_NPORTS || co->index != kgdb_portnum)		co->index = kgdb_portnum;	if (options)		uart_parse_options(options, &baud, &parity, &bits, &flow);	else		kgdb_console_get_options(port, &baud, &parity, &bits);	kgdb_getchar = kgdb_sci_getchar;	kgdb_putchar = kgdb_sci_putchar;	return uart_set_options(port, co, baud, parity, bits, flow);}#endif /* CONFIG_SH_KGDB */#ifdef CONFIG_SH_KGDB_CONSOLEstatic struct console kgdb_console = {        .name		= "ttySC",        .write		= kgdb_console_write,        .setup		= kgdb_console_setup,        .flags		= CON_PRINTBUFFER | CON_ENABLED,        .index		= -1,	.data		= &sci_uart_driver,};/* Register the KGDB console so we get messages (d'oh!) */static int __init kgdb_console_init(void){        register_console(&kgdb_console);	return 0;}console_initcall(kgdb_console_init);#endif /* CONFIG_SH_KGDB_CONSOLE */#if defined(CONFIG_SH_KGDB_CONSOLE)#define SCI_CONSOLE	&kgdb_console#elif defined(CONFIG_SERIAL_SH_SCI_CONSOLE)#define SCI_CONSOLE	&serial_console#else#define SCI_CONSOLE 	0#endifstatic char banner[] __initdata =	KERN_INFO "SuperH SCI(F) driver initialized\n";static struct uart_driver sci_uart_driver = {	.owner		= THIS_MODULE,	.driver_name	= "sci",#ifdef CONFIG_DEVFS_FS	.devfs_name	= "ttsc/",#endif	.dev_name	= "ttySC",	.major		= SCI_MAJOR,	.minor		= SCI_MINOR_START,	.nr		= SCI_NPORTS,	.cons		= SCI_CONSOLE,};static int __init sci_init(void){	int chan, ret;	printk("%s", banner);	ret = uart_register_driver(&sci_uart_driver);	if (ret == 0) {		for (chan = 0; chan < SCI_NPORTS; chan++) {			struct sci_port *sciport = &sci_ports[chan];#if !defined(__H8300H__) && !defined(__H8300S__)			sciport->port.uartclk = (current_cpu_data.module_clock * 16);#else			sciport->port.uartclk = CONFIG_CPU_CLOCK;#endif			uart_add_one_port(&sci_uart_driver, &sciport->port);			sciport->break_timer.data = (unsigned long)sciport;			sciport->break_timer.function = sci_break_timer;			init_timer(&sciport->break_timer);		}	}#ifdef CONFIG_CPU_FREQ	cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);	printk("sci: CPU frequency notifier registered\n");#endif#ifdef CONFIG_SH_STANDARD_BIOS	sh_bios_gdb_detach();#endif	return ret;}static void __exit sci_exit(void){	int chan;	for (chan = 0; chan < SCI_NPORTS; chan++)		uart_remove_one_port(&sci_uart_driver, &sci_ports[chan].port);	uart_unregister_driver(&sci_uart_driver);}module_init(sci_init);module_exit(sci_exit);

⌨️ 快捷键说明

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