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 + -
显示快捷键?