diff options
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/8250.c | 2 | ||||
-rw-r--r-- | drivers/tty/serial/Kconfig | 15 | ||||
-rw-r--r-- | drivers/tty/serial/s5pv210.c | 14 | ||||
-rw-r--r-- | drivers/tty/serial/samsung.c | 99 | ||||
-rw-r--r-- | drivers/tty/serial/samsung.h | 19 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 22 | ||||
-rw-r--r-- | drivers/tty/sysrq.c | 3 | ||||
-rw-r--r-- | drivers/tty/vt/.gitignore | 2 |
8 files changed, 124 insertions, 52 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 762ce72..d1ccd3a 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -1772,7 +1772,7 @@ static int serial_link_irq_chain(struct uart_8250_port *up) static void serial_unlink_irq_chain(struct uart_8250_port *up) { - struct irq_info *i; + struct irq_info *i = NULL; struct hlist_node *n; struct hlist_head *h; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9789293..3577377 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -489,6 +489,17 @@ config SERIAL_SAMSUNG_CONSOLE your boot loader about how to pass options to the kernel at boot time.) +config SERIAL_SAMSUNG_CONSOLE_SWITCH + bool "Support for console switch on Samsung SoC serial port" + depends on SERIAL_SAMSUNG_CONSOLE=y + default n + help + Allow kernel cmdline to switch Samsung Soc serial ports for use as + an virtual console or not. This may serve a port usage selection. + + Even if you say Y here, you should add samsung.uart_debug=1 + into kernel cmdline to enable virtual console. + config SERIAL_S3C2400 tristate "Samsung S3C2410 Serial port support" depends on ARM && SERIAL_SAMSUNG && CPU_S3C2400 @@ -537,8 +548,8 @@ config SERIAL_S3C6400 config SERIAL_S5PV210 tristate "Samsung S5PV210 Serial port support" - depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210) - select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210) + depends on SERIAL_SAMSUNG && (CPU_S5PV210 || ARCH_EXYNOS) + select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || ARCH_EXYNOS) default y help Serial port support for Samsung's S5P Family of SoC's diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index dd194dc..ce7a077 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -18,6 +18,7 @@ #include <linux/init.h> #include <linux/serial_core.h> #include <linux/serial.h> +#include <linux/delay.h> #include <asm/irq.h> #include <mach/hardware.h> @@ -83,6 +84,12 @@ static int s5pv210_serial_resetport(struct uart_port *port, wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH); wr_regl(port, S3C2410_UFCON, cfg->ufcon); + wr_regl(port, S3C64XX_UINTM, 0xf); + wr_regl(port, S3C64XX_UINTP, 0xf); + + /* It is need to delay when reset FIFO register */ + udelay(1); + return 0; } @@ -135,13 +142,6 @@ static struct platform_driver s5p_serial_driver = { }, }; -static int __init s5pv210_serial_console_init(void) -{ - return s3c24xx_serial_initconsole(&s5p_serial_driver, s5p_uart_inf); -} - -console_initcall(s5pv210_serial_console_init); - static int __init s5p_serial_init(void) { return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf); diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index f66f648..2468df0 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -66,6 +66,18 @@ /* flag to ignore all characters coming in */ #define RXSTAT_DUMMY_READ (0x10000000) +#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \ + defined(CONFIG_MACH_SLP_PQ)||defined(CONFIG_MACH_P10) +/* Devices */ +#define CONFIG_BT_S3C_UART 0 +#define CONFIG_GPS_S3C_UART 1 +#endif + +#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH +static unsigned uart_debug; /* Initialized automatically with 0 by compiler */ +module_param_named(uart_debug, uart_debug, uint, 0644); +#endif + static inline struct s3c24xx_uart_port *to_ourport(struct uart_port *port) { return container_of(port, struct s3c24xx_uart_port, port); @@ -351,6 +363,28 @@ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) { /* todo - possibly remove AFC and do manual CTS */ + +#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \ + defined(CONFIG_MACH_SLP_PQ) || defined(CONFIG_MACH_P10) || \ + defined(CONFIG_MACH_U1CAMERA_BD) + unsigned int umcon = 0; + umcon = rd_regl(port, S3C2410_UMCON); + + if (port->line == CONFIG_BT_S3C_UART) { + if (mctrl & TIOCM_RTS) { + umcon |= S3C2410_UMCOM_AFC; + } else { + umcon &= ~S3C2410_UMCOM_AFC; + } + + } else if (port->line == CONFIG_GPS_S3C_UART) { + umcon |= S3C2410_UMCOM_AFC; + } else { + umcon &= ~S3C2410_UMCOM_AFC; + } + + wr_regl(port, S3C2410_UMCON, umcon); +#endif } static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) @@ -375,29 +409,40 @@ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state) static void s3c24xx_serial_shutdown(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); + struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); if (ourport->tx_claimed) { + disable_irq(ourport->tx_irq); free_irq(ourport->tx_irq, ourport); tx_enabled(port) = 0; ourport->tx_claimed = 0; } if (ourport->rx_claimed) { + disable_irq(ourport->rx_irq); free_irq(ourport->rx_irq, ourport); ourport->rx_claimed = 0; rx_enabled(port) = 0; } + + if (cfg->set_runstate) + cfg->set_runstate(0); } static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); + struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); + /* runstate should be 1 before request_irq is called */ + if (cfg->set_runstate) + cfg->set_runstate(1); + rx_enabled(port) = 1; ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0, @@ -405,7 +450,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); - return ret; + goto err; } ourport->rx_claimed = 1; @@ -574,7 +619,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port, */ if (strcmp(clkp->name, "fclk") == 0) { - struct s3c24xx_uart_clksrc src; + struct s3c24xx_uart_clksrc src = { "", 0, }; s3c24xx_serial_getsource(port, &src); @@ -596,6 +641,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port, } else { resptr = res; + best = res; for (i = 0; i < cfg->clocks_size; i++, clkp++) { if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud)) resptr++; @@ -608,6 +654,7 @@ static unsigned int s3c24xx_serial_getclk(struct uart_port *port, unsigned int deviation = (1<<30)|((1<<30)-1); int calc_deviation; + best = res; for (sptr = res; sptr < resptr; sptr++) { calc_deviation = baud - sptr->calc; if (calc_deviation < 0) @@ -675,9 +722,12 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, /* * Ask the core to calculate the divisor for us. */ - - baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); - +#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_MIDAS) || \ + defined(CONFIG_MACH_SLP_PQ)||defined(CONFIG_MACH_P10) + baud = uart_get_baud_rate(port, termios, old, 0, 4000000); // 4Mbps +#else + baud = uart_get_baud_rate(port, termios, old, 0, 3000000); +#endif if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) quot = port->custom_divisor; else @@ -849,6 +899,14 @@ s3c24xx_serial_verify_port(struct uart_port *port, struct serial_struct *ser) return 0; } +static void +s3c24xx_serial_wake_peer(struct uart_port *port) +{ + struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); + + if(cfg->wake_peer) + cfg->wake_peer(port); +} #ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE @@ -877,6 +935,7 @@ static struct uart_ops s3c24xx_serial_ops = { .request_port = s3c24xx_serial_request_port, .config_port = s3c24xx_serial_config_port, .verify_port = s3c24xx_serial_verify_port, + .wake_peer = s3c24xx_serial_wake_peer, }; @@ -884,7 +943,11 @@ static struct uart_driver s3c24xx_uart_drv = { .owner = THIS_MODULE, .driver_name = "s3c2410_serial", .nr = CONFIG_SERIAL_SAMSUNG_UARTS, +#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH + .cons = NULL, +#else .cons = S3C24XX_SERIAL_CONSOLE, +#endif .dev_name = S3C24XX_SERIAL_NAME, .major = S3C24XX_SERIAL_MAJOR, .minor = S3C24XX_SERIAL_MINOR, @@ -982,10 +1045,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, * a disturbance in the clock-rate over the change. */ - if (IS_ERR(port->clk)) + if (IS_ERR_OR_NULL(port->baudclk)) goto exit; - if (port->baudclk_rate == clk_get_rate(port->clk)) + if (port->baudclk_rate == clk_get_rate(port->baudclk)) goto exit; if (val == CPUFREQ_PRECHANGE) { @@ -1109,7 +1172,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, ourport->rx_irq = ret; ourport->tx_irq = ret + 1; } - + ret = platform_get_irq(platdev, 1); if (ret > 0) ourport->tx_irq = ret; @@ -1132,7 +1195,8 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, struct uart_port *port = s3c24xx_dev_to_port(dev); struct s3c24xx_uart_port *ourport = to_ourport(port); - return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name); + return snprintf(buf, PAGE_SIZE, "* %s\n", + ourport->clksrc ? ourport->clksrc->name : "(null)"); } static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); @@ -1244,7 +1308,10 @@ EXPORT_SYMBOL_GPL(s3c24xx_serial_init); static int __init s3c24xx_serial_modinit(void) { int ret; - +#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH + if (uart_debug) + s3c24xx_uart_drv.cons = S3C24XX_SERIAL_CONSOLE; +#endif ret = uart_register_driver(&s3c24xx_uart_drv); if (ret < 0) { printk(KERN_ERR "failed to register UART driver\n"); @@ -1307,7 +1374,7 @@ static void __init s3c24xx_serial_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { - struct s3c24xx_uart_clksrc clksrc; + struct s3c24xx_uart_clksrc clksrc = { "", 0, }; struct clk *clk; unsigned int ulcon; unsigned int ucon; @@ -1365,7 +1432,6 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, else rate = 1; - *baud = rate / (16 * (ubrdiv + 1)); dbg("calculated baud %d\n", *baud); } @@ -1416,10 +1482,8 @@ s3c24xx_serial_console_setup(struct console *co, char *options) /* is the port configured? */ - if (port->mapbase == 0x0) { - co->index = 0; - port = &s3c24xx_serial_ports[co->index].port; - } + if (port->mapbase == 0x0) + return -ENODEV; cons_uart = port; @@ -1451,7 +1515,8 @@ static struct console s3c24xx_serial_console = { .flags = CON_PRINTBUFFER, .index = -1, .write = s3c24xx_serial_console_write, - .setup = s3c24xx_serial_console_setup + .setup = s3c24xx_serial_console_setup, + .data = &s3c24xx_uart_drv, }; int s3c24xx_serial_initconsole(struct platform_driver *drv, diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h index 5b098cd..a69d9a5 100644 --- a/drivers/tty/serial/samsung.h +++ b/drivers/tty/serial/samsung.h @@ -79,25 +79,6 @@ extern int s3c24xx_serial_initconsole(struct platform_driver *drv, extern int s3c24xx_serial_init(struct platform_driver *drv, struct s3c24xx_uart_info *info); -#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE - -#define s3c24xx_console_init(__drv, __inf) \ -static int __init s3c_serial_console_init(void) \ -{ \ - struct s3c24xx_uart_info *uinfo[CONFIG_SERIAL_SAMSUNG_UARTS]; \ - int i; \ - \ - for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++) \ - uinfo[i] = __inf; \ - return s3c24xx_serial_initconsole(__drv, uinfo); \ -} \ - \ -console_initcall(s3c_serial_console_init) - -#else -#define s3c24xx_console_init(drv, inf) extern void no_console(void) -#endif - #ifdef CONFIG_SERIAL_SAMSUNG_DEBUG extern void printascii(const char *); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 6bc20d7..65db939 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -91,6 +91,9 @@ static void __uart_start(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; + if (port->ops->wake_peer) + port->ops->wake_peer(port); + if (!uart_circ_empty(&state->xmit) && state->xmit.buf && !tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); @@ -159,13 +162,17 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in * buffer. */ if (!state->xmit.buf) { + unsigned long flags; + /* This is protected by the per port mutex */ page = get_zeroed_page(GFP_KERNEL); if (!page) return -ENOMEM; + spin_lock_irqsave(&uport->lock, flags); state->xmit.buf = (unsigned char *) page; uart_circ_clear(&state->xmit); + spin_unlock_irqrestore(&uport->lock, flags); } retval = uport->ops->startup(uport); @@ -258,8 +265,11 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) * Free the transmit buffer page. */ if (state->xmit.buf) { + unsigned long flags; + spin_lock_irqsave(&uport->lock, flags); free_page((unsigned long)state->xmit.buf); state->xmit.buf = NULL; + spin_unlock_irqrestore(&uport->lock, flags); } } @@ -468,10 +478,12 @@ static inline int __uart_put_char(struct uart_port *port, unsigned long flags; int ret = 0; - if (!circ->buf) + spin_lock_irqsave(&port->lock, flags); + if (!circ->buf) { + spin_unlock_irqrestore(&port->lock, flags); return 0; + } - spin_lock_irqsave(&port->lock, flags); if (uart_circ_chars_free(circ) != 0) { circ->buf[circ->head] = c; circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1); @@ -514,10 +526,12 @@ static int uart_write(struct tty_struct *tty, port = state->uart_port; circ = &state->xmit; - if (!circ->buf) + spin_lock_irqsave(&port->lock, flags); + if (!circ->buf) { + spin_unlock_irqrestore(&port->lock, flags); return 0; + } - spin_lock_irqsave(&port->lock, flags); while (1) { c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE); if (count < c) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 43db715..b74b08f 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -142,6 +142,9 @@ static struct sysrq_key_op sysrq_crash_op = { static void sysrq_handle_reboot(int key) { +#ifdef COFIG_SEC_DEBUG_SYSRQ_B + BUG(); +#endif lockdep_off(); local_irq_enable(); emergency_restart(); diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore deleted file mode 100644 index 83683a2..0000000 --- a/drivers/tty/vt/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -consolemap_deftbl.c -defkeymap.c |