📄 serial_jasper.c
字号:
int retval; /* * Allocate the IRQ */ retval = request_irq(port->irq, jasperuart_int, 0, "jasper", info); if (retval) return retval; /* * initialise the old status of the modem signals */ info->drv_old_status = UART_GET_MSR(port); /* * Finally, enable interrupts * FIXME : Modem interrupt (EDSSI) */ UART_PUT_IER(port, JASPER_UART_IER_ERBFI | JASPER_UART_IER_ETBEI | JASPER_UART_IER_ELSI ); return 0;}static void jasperuart_shutdown(struct uart_port *port, struct uart_info *info){ /* * Free the interrupt */ free_irq(port->irq, info); /* * disable all interrupts, disable the port */ UART_PUT_IER(port, 0); /* disable break condition and fifos */ UART_PUT_LCR(port, UART_GET_LCR(port) & ~(JASPER_UART_LCR_SETBRK)); UART_PUT_FCR(port, UART_GET_FCR(port) & ~(JASPER_UART_FCR_FIFOENA));}static void jasperuart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot){ u_int lcr, fcr, old_ier; unsigned long flags;#if DEBUG printk("jasperuart_set_cflag(0x%x) called\n", cflag);#endif printk("jasperuart change speed %d\n",quot); /* byte size and parity */ switch (cflag & CSIZE) { case CS5: lcr = JASPER_UART_LCR_WLEN_5; break; case CS6: lcr = JASPER_UART_LCR_WLEN_6; break; case CS7: lcr = JASPER_UART_LCR_WLEN_7; break; default: lcr = JASPER_UART_LCR_WLEN_8; break; // CS8 } if (cflag & CSTOPB) lcr |= JASPER_UART_LCR_STP2; if (cflag & PARENB) { lcr |= JASPER_UART_LCR_PEN; if (!(cflag & PARODD)) lcr |= JASPER_UART_LCR_EPS; } fcr = JASPER_UART_FCR_TXRST | JASPER_UART_FCR_RXRST; if (port->fifosize > 1) fcr |= JASPER_UART_FCR_FIFOENA; // XXX: TX irq trigger UART_PUT_LCR(port, lcr); UART_PUT_FCR(port, fcr); port->read_status_mask = JASPER_UART_LSR_OE; if (iflag & INPCK) port->read_status_mask |= JASPER_UART_LSR_FE | JASPER_UART_LSR_PE; if (iflag & (BRKINT | PARMRK)) port->read_status_mask |= JASPER_UART_LSR_BI; /* * Characters to ignore */ port->ignore_status_mask = 0; if (iflag & IGNPAR) port->ignore_status_mask |= JASPER_UART_LSR_FE | JASPER_UART_LSR_PE; if (iflag & IGNBRK) { port->ignore_status_mask |= JASPER_UART_LSR_BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (iflag & IGNPAR) port->ignore_status_mask |= JASPER_UART_LSR_OE; } /* * Ignore all characters if CREAD is not set. */ if ((cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_RSR_RX; /* first, disable everything */ save_flags(flags); cli(); old_ier = UART_GET_IER(port) & ~JASPER_UART_IER_EDSSI; if ((port->flags & ASYNC_HARDPPS_CD) || (cflag & CRTSCTS) || !(cflag & CLOCAL)) old_ier |= JASPER_UART_IER_EDSSI; UART_PUT_IER(port, 0); /* Set baud rate */#ifndef CONFIG_QUICKTURN_HACKS UART_PUT_CLKDIV(port, quot);#else#warning ***** QUICKTURN HACK ***** External UART Clock selected UART_PUT_CLKSEL(port, 1);#endif UART_PUT_IER(port, old_ier); restore_flags(flags);}/* * Release the memory region(s) being used by 'port' */static void jasperuart_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 jasperuart_request_port(struct uart_port *port){ return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_jasper") != NULL ? 0 : -EBUSY;}/* * Configure/autoconfigure the port. */static void jasperuart_config_port(struct uart_port *port, int flags){ if (flags & UART_CONFIG_TYPE) { port->type = PORT_JASPER; jasperuart_request_port(port); }}/* * verify the new serial_struct (for TIOCSSERIAL). */static int jasperuart_verify_port(struct uart_port *port, struct serial_struct *ser){ int ret = 0; if (ser->type != PORT_UNKNOWN && ser->type != PORT_JASPER) 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 jasper_pops = { tx_empty: jasperuart_tx_empty, set_mctrl: jasperuart_set_mctrl, get_mctrl: jasperuart_get_mctrl, stop_tx: jasperuart_stop_tx, start_tx: jasperuart_start_tx, stop_rx: jasperuart_stop_rx, enable_ms: jasperuart_enable_ms, break_ctl: jasperuart_break_ctl, startup: jasperuart_startup, shutdown: jasperuart_shutdown, change_speed: jasperuart_change_speed, release_port: jasperuart_release_port, request_port: jasperuart_request_port, config_port: jasperuart_config_port, verify_port: jasperuart_verify_port,};static struct uart_port jasper_ports[UART_NR] = { { membase: (void *)IO_ADDRESS(JASPER_UART0_BASE), mapbase: JASPER_UART0_BASE, iotype: SERIAL_IO_MEM, irq: JASPER_UART0_IRQ, uartclk: 14745600, fifosize: 16, unused: { RX_FIFO_TRIG_DEFAULT, TX_FIFO_TRIG_DEFAULT}, ops: &jasper_pops, flags: ASYNC_BOOT_AUTOCONF, }, { membase: (void *)IO_ADDRESS(JASPER_UART1_BASE), mapbase: JASPER_UART1_BASE, iotype: SERIAL_IO_MEM, irq: JASPER_UART1_IRQ, uartclk: 14745600, fifosize: 16, unused: { RX_FIFO_TRIG_DEFAULT, TX_FIFO_TRIG_DEFAULT}, ops: &jasper_pops, flags: ASYNC_BOOT_AUTOCONF, }};#ifdef CONFIG_SERIAL_JASPER_CONSOLE#ifdef used_and_not_const_char_pointerstatic int jasperuart_console_read(struct uart_port *port, char *s, u_int count){ unsigned int status; int c;#if DEBUG printk("jasperuart_console_read() called\n");#endif c = 0; while (c < count) { status = UART_GET_LSR(port); if (UART_RX_READY(status)) { *s++ = UART_GET_CHAR(port); c++; } else { // nothing more to get, return return c; } } // return the count return c;}#endifstatic void jasperuart_console_write(struct console *co, const char *s, u_int count){ struct uart_port *port = jasper_ports + co->index; unsigned int status, old_ier; int i; /* * First save the IER then disable the interrupts */ old_ier = UART_GET_IER(port); UART_PUT_IER(port, 0); /* * Now, do each character */ for (i = 0; i < count; i++) { do { status = UART_GET_LSR(port); } while (!UART_TX_READY(status)); UART_PUT_CHAR(port, s[i]); if (s[i] == '\n') { do { status = UART_GET_LSR(port); } while (!UART_TX_READY(status)); UART_PUT_CHAR(port, '\r'); } } /* * Finally, wait for transmitter to become empty * and restore the TCR */ do { status = UART_GET_LSR(port); } while (!UART_TX_EMPTY(status)); UART_PUT_IER(port, old_ier);}static kdev_t jasperuart_console_device(struct console *co){ return MKDEV(SERIAL_JASPER_MAJOR, SERIAL_JASPER_MINOR + co->index);}static int jasperuart_console_wait_key(struct console *co){ struct uart_port *port = jasper_ports + co->index; unsigned int status; do { status = UART_GET_LSR(port); } while (!UART_RX_READY(status)); return UART_GET_CHAR(port);}/*static void __initjasperuart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits){ u_int lcr, quot; lcr = UART_GET_LCR(port); *parity = 'n'; if (lcr & JASPER_UART_LCR_PEN) { if (lcr & JASPER_UART_LCR_EPS) *parity = 'e'; else *parity = 'o'; } *bits = (lcr & JASPER_UART_LCR_WLS) + 5; quot = UART_GET_CLKDIV(port); //FIXME : "+1" is here to avoid division by 0 errors, // need to check what REALLY happens when CLKDIV is set to 0, (disabled the UART or ?) *baud = port->uartclk / (16 * quot + 1);}*/static int __init jasperuart_console_setup(struct console *co, char *options){ struct uart_port *port; int baud = CONFIG_SERIAL_JASPER_SERIAL_BAUDRATE; int bits = 8; int parity = 'n'; int flow = 'n'; /* * Check whether an invalid uart number has been specified, and * if so, search for the first available port that does have * console support. */ printk("serial_jasper: setup_console @ %d\n",baud); port = uart_get_console(jasper_ports, UART_NR, co); if (options) uart_parse_options(options, &baud, &parity, &bits, &flow);// else // jasperuart_console_get_options(port, &baud, &parity, &bits); return uart_set_options(port, co, baud, parity, bits, flow);}static struct console jasper_console = { write: jasperuart_console_write,#ifdef used_and_not_const_char_pointer read: jasperuart_console_read,#endif device: jasperuart_console_device, wait_key: jasperuart_console_wait_key, setup: jasperuart_console_setup, flags: CON_PRINTBUFFER, index: -1,};void __init jasperuart_clock_init(void){ int i; for(i=0; i< UART_NR; i++) jasper_ports[i].uartclk = __get_clock(2);}void __init jasperuart_console_init(void){ jasperuart_clock_init(); register_console(&jasper_console);}#define JASPER_CONSOLE &jasper_console#else#define JASPER_CONSOLE NULL#endifstatic struct uart_driver jasper_reg = { owner: THIS_MODULE, normal_major: SERIAL_JASPER_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_JASPER_MAJOR, callout_driver: &callout, table: jasper_table, termios: jasper_termios, termios_locked: jasper_termios_locked, minor: SERIAL_JASPER_MINOR, nr: UART_NR, port: jasper_ports, cons: JASPER_CONSOLE,};static int __init jasperuart_init(void){ jasperuart_clock_init(); return uart_register_driver(&jasper_reg);}static void __exit jasperuart_exit(void){ uart_unregister_driver(&jasper_reg);}module_init(jasperuart_init);module_exit(jasperuart_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -