diff options
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/8250.c | 58 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 3 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/amba-pl011.c | 30 | ||||
-rw-r--r-- | drivers/serial/atmel_serial.c | 1 | ||||
-rw-r--r-- | drivers/serial/bfin_5xx.c | 2 | ||||
-rw-r--r-- | drivers/serial/imx.c | 113 | ||||
-rw-r--r-- | drivers/serial/kgdboc.c | 168 | ||||
-rw-r--r-- | drivers/serial/mcf.c | 1 | ||||
-rw-r--r-- | drivers/serial/mcfserial.c | 1 | ||||
-rw-r--r-- | drivers/serial/mpc52xx_uart.c | 2 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 2 | ||||
-rw-r--r-- | drivers/serial/netx-serial.c | 2 | ||||
-rw-r--r-- | drivers/serial/pnx8xxx_uart.c | 1 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 3 | ||||
-rw-r--r-- | drivers/serial/s3c2410.c | 4 | ||||
-rw-r--r-- | drivers/serial/sa1100.c | 2 | ||||
-rw-r--r-- | drivers/serial/sc26xx.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 76 | ||||
-rw-r--r-- | drivers/serial/sh-sci.c | 8 | ||||
-rw-r--r-- | drivers/serial/sh-sci.h | 60 | ||||
-rw-r--r-- | drivers/serial/uartlite.c | 3 | ||||
-rw-r--r-- | drivers/serial/vr41xx_siu.c | 3 |
23 files changed, 465 insertions, 81 deletions
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 77f7a7f0646..96a585e1cee 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1740,6 +1740,60 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) } } +#ifdef CONFIG_CONSOLE_POLL +/* + * Console polling routines for writing and reading from the uart while + * in an interrupt or debug context. + */ + +static int serial8250_get_poll_char(struct uart_port *port) +{ + struct uart_8250_port *up = (struct uart_8250_port *)port; + unsigned char lsr = serial_inp(up, UART_LSR); + + while (!(lsr & UART_LSR_DR)) + lsr = serial_inp(up, UART_LSR); + + return serial_inp(up, UART_RX); +} + + +static void serial8250_put_poll_char(struct uart_port *port, + unsigned char c) +{ + unsigned int ier; + struct uart_8250_port *up = (struct uart_8250_port *)port; + + /* + * First save the IER then disable the interrupts + */ + ier = serial_in(up, UART_IER); + if (up->capabilities & UART_CAP_UUE) + serial_out(up, UART_IER, UART_IER_UUE); + else + serial_out(up, UART_IER, 0); + + wait_for_xmitr(up, BOTH_EMPTY); + /* + * Send the character out. + * If a LF, also do CR... + */ + serial_out(up, UART_TX, c); + if (c == 10) { + wait_for_xmitr(up, BOTH_EMPTY); + serial_out(up, UART_TX, 13); + } + + /* + * Finally, wait for transmitter to become empty + * and restore the IER + */ + wait_for_xmitr(up, BOTH_EMPTY); + serial_out(up, UART_IER, ier); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static int serial8250_startup(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; @@ -2386,6 +2440,10 @@ static struct uart_ops serial8250_pops = { .request_port = serial8250_request_port, .config_port = serial8250_config_port, .verify_port = serial8250_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = serial8250_get_poll_char, + .poll_put_char = serial8250_put_poll_char, +#endif }; static struct uart_8250_port serial8250_ports[UART_NR]; diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index cf627cd1b4c..f7cd9504d81 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -961,6 +961,9 @@ config SERIAL_CORE config SERIAL_CORE_CONSOLE bool +config CONSOLE_POLL + bool + config SERIAL_68328 bool "68328 serial support" depends on M68328 || M68EZ328 || M68VZ328 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 640cfe44a56..3cbea549472 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -66,4 +66,5 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o +obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o obj-$(CONFIG_SERIAL_QE) += ucc_uart.o diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 40604a09292..08adc1de4a7 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -314,6 +314,32 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&uap->port.lock, flags); } +#ifdef CONFIG_CONSOLE_POLL +static int pl010_get_poll_char(struct uart_port *port) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + unsigned int status; + + do { + status = readw(uap->port.membase + UART01x_FR); + } while (status & UART01x_FR_RXFE); + + return readw(uap->port.membase + UART01x_DR); +} + +static void pl010_put_poll_char(struct uart_port *port, + unsigned char ch) +{ + struct uart_amba_port *uap = (struct uart_amba_port *)port; + + while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) + barrier(); + + writew(ch, uap->port.membase + UART01x_DR); +} + +#endif /* CONFIG_CONSOLE_POLL */ + static int pl011_startup(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; @@ -572,6 +598,10 @@ static struct uart_ops amba_pl011_pops = { .request_port = pl010_request_port, .config_port = pl010_config_port, .verify_port = pl010_verify_port, +#ifdef CONFIG_CONSOLE_POLL + .poll_get_char = pl010_get_poll_char, + .poll_put_char = pl010_put_poll_char, +#endif }; static struct uart_amba_port *amba_ports[UART_NR]; diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 430997e33fc..55492fa095a 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -1577,3 +1577,4 @@ module_exit(atmel_serial_exit); MODULE_AUTHOR("Rick Bronson"); MODULE_DESCRIPTION("Atmel AT91 / AT32 serial port driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:atmel_usart"); diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c index 0aa345b9a38..46bb47f37b9 100644 --- a/drivers/serial/bfin_5xx.c +++ b/drivers/serial/bfin_5xx.c @@ -1243,6 +1243,7 @@ static struct platform_driver bfin_serial_driver = { .resume = bfin_serial_resume, .driver = { .name = "bfin-uart", + .owner = THIS_MODULE, }, }; @@ -1301,3 +1302,4 @@ MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>"); MODULE_DESCRIPTION("Blackfin generic serial port driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR); +MODULE_ALIAS("platform:bfin-uart"); diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 56af1f566a4..5a375bf0ebf 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -166,15 +166,6 @@ #define SERIAL_IMX_MAJOR 204 #define MINOR_START 41 -#define NR_PORTS 2 - -#define IMX_ISR_PASS_LIMIT 256 - -/* - * This is the size of our serial port register set. - */ -#define UART_PORT_SIZE 0x100 - /* * This determines how often we check the modem status signals * for any change. They generally aren't connected to an IRQ @@ -358,66 +349,60 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) struct tty_struct *tty = sport->port.info->tty; unsigned long flags, temp; - rx = readl(sport->port.membase + URXD0); spin_lock_irqsave(&sport->port.lock,flags); - do { + while (readl(sport->port.membase + USR2) & USR2_RDR) { flg = TTY_NORMAL; sport->port.icount.rx++; + rx = readl(sport->port.membase + URXD0); + temp = readl(sport->port.membase + USR2); - if( temp & USR2_BRCD ) { + if (temp & USR2_BRCD) { writel(temp | USR2_BRCD, sport->port.membase + USR2); - if(uart_handle_break(&sport->port)) - goto ignore_char; + if (uart_handle_break(&sport->port)) + continue; } if (uart_handle_sysrq_char (&sport->port, (unsigned char)rx)) - goto ignore_char; + continue; + + if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) { + if (rx & URXD_PRERR) + sport->port.icount.parity++; + else if (rx & URXD_FRMERR) + sport->port.icount.frame++; + if (rx & URXD_OVRRUN) + sport->port.icount.overrun++; + + if (rx & sport->port.ignore_status_mask) { + if (++ignored > 100) + goto out; + continue; + } + + rx &= sport->port.read_status_mask; + + if (rx & URXD_PRERR) + flg = TTY_PARITY; + else if (rx & URXD_FRMERR) + flg = TTY_FRAME; + if (rx & URXD_OVRRUN) + flg = TTY_OVERRUN; - if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) - goto handle_error; +#ifdef SUPPORT_SYSRQ + sport->port.sysrq = 0; +#endif + } - error_return: tty_insert_flip_char(tty, rx, flg); - - ignore_char: - rx = readl(sport->port.membase + URXD0); - } while(rx & URXD_CHARRDY); + } out: spin_unlock_irqrestore(&sport->port.lock,flags); tty_flip_buffer_push(tty); return IRQ_HANDLED; - -handle_error: - if (rx & URXD_PRERR) - sport->port.icount.parity++; - else if (rx & URXD_FRMERR) - sport->port.icount.frame++; - if (rx & URXD_OVRRUN) - sport->port.icount.overrun++; - - if (rx & sport->port.ignore_status_mask) { - if (++ignored > 100) - goto out; - goto ignore_char; - } - - rx &= sport->port.read_status_mask; - - if (rx & URXD_PRERR) - flg = TTY_PARITY; - else if (rx & URXD_FRMERR) - flg = TTY_FRAME; - if (rx & URXD_OVRRUN) - flg = TTY_OVERRUN; - -#ifdef SUPPORT_SYSRQ - sport->port.sysrq = 0; -#endif - goto error_return; } /* @@ -546,7 +531,7 @@ static int imx_startup(struct uart_port *port) writel(USR1_RTSD, sport->port.membase + USR1); temp = readl(sport->port.membase + UCR1); - temp |= (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); + temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; writel(temp, sport->port.membase + UCR1); temp = readl(sport->port.membase + UCR2); @@ -731,9 +716,11 @@ static const char *imx_type(struct uart_port *port) */ static void imx_release_port(struct uart_port *port) { - struct imx_port *sport = (struct imx_port *)port; + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *mmres; - release_mem_region(sport->port.mapbase, UART_PORT_SIZE); + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mmres->start, mmres->end - mmres->start + 1); } /* @@ -741,10 +728,18 @@ static void imx_release_port(struct uart_port *port) */ static int imx_request_port(struct uart_port *port) { - struct imx_port *sport = (struct imx_port *)port; + struct platform_device *pdev = to_platform_device(port->dev); + struct resource *mmres; + void *ret; + + mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mmres) + return -ENODEV; + + ret = request_mem_region(mmres->start, mmres->end - mmres->start + 1, + "imx-uart"); - return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, - "imx-uart") != NULL ? 0 : -EBUSY; + return ret ? 0 : -EBUSY; } /* @@ -815,7 +810,7 @@ static struct imx_port imx_ports[] = { .type = PORT_IMX, .iotype = UPIO_MEM, .membase = (void *)IMX_UART1_BASE, - .mapbase = IMX_UART1_BASE, /* FIXME */ + .mapbase = 0x00206000, .irq = UART1_MINT_RX, .uartclk = 16000000, .fifosize = 32, @@ -831,7 +826,7 @@ static struct imx_port imx_ports[] = { .type = PORT_IMX, .iotype = UPIO_MEM, .membase = (void *)IMX_UART2_BASE, - .mapbase = IMX_UART2_BASE, /* FIXME */ + .mapbase = 0x00207000, .irq = UART2_MINT_RX, .uartclk = 16000000, .fifosize = 32, @@ -1090,6 +1085,7 @@ static struct platform_driver serial_imx_driver = { .resume = serial_imx_resume, .driver = { .name = "imx-uart", + .owner = THIS_MODULE, }, }; @@ -1124,3 +1120,4 @@ module_exit(imx_serial_exit); MODULE_AUTHOR("Sascha Hauer"); MODULE_DESCRIPTION("IMX generic serial port driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imx-uart"); diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c new file mode 100644 index 00000000000..9cf03327386 --- /dev/null +++ b/drivers/serial/kgdboc.c @@ -0,0 +1,168 @@ +/* + * Based on the same principle as kgdboe using the NETPOLL api, this + * driver uses a console polling api to implement a gdb serial inteface + * which is multiplexed on a console port. + * + * Maintainer: Jason Wessel <jason.wessel@windriver.com> + * + * 2007-2008 (c) Jason Wessel - Wind River Systems, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ +#include <linux/kernel.h> +#include <linux/ctype.h> +#include <linux/kgdb.h> +#include <linux/tty.h> + +#define MAX_CONFIG_LEN 40 + +static struct kgdb_io kgdboc_io_ops; + +/* -1 = init not run yet, 0 = unconfigured, 1 = configured. */ +static int configured = -1; + +static char config[MAX_CONFIG_LEN]; +static struct kparam_string kps = { + .string = config, + .maxlen = MAX_CONFIG_LEN, +}; + +static struct tty_driver *kgdb_tty_driver; +static int kgdb_tty_line; + +static int kgdboc_option_setup(char *opt) +{ + if (strlen(opt) > MAX_CONFIG_LEN) { + printk(KERN_ERR "kgdboc: config string too long\n"); + return -ENOSPC; + } + strcpy(config, opt); + + return 0; +} + +__setup("kgdboc=", kgdboc_option_setup); + +static int configure_kgdboc(void) +{ + struct tty_driver *p; + int tty_line = 0; + int err; + + err = kgdboc_option_setup(config); + if (err || !strlen(config) || isspace(config[0])) + goto noconfig; + + err = -ENODEV; + + p = tty_find_polling_driver(config, &tty_line); + if (!p) + goto noconfig; + + kgdb_tty_driver = p; + kgdb_tty_line = tty_line; + + err = kgdb_register_io_module(&kgdboc_io_ops); + if (err) + goto noconfig; + + configured = 1; + + return 0; + +noconfig: + config[0] = 0; + configured = 0; + + return err; +} + +static int __init init_kgdboc(void) +{ + /* Already configured? */ + if (configured == 1) + return 0; + + return configure_kgdboc(); +} + +static void cleanup_kgdboc(void) +{ + if (configured == 1) + kgdb_unregister_io_module(&kgdboc_io_ops); +} + +static int kgdboc_get_char(void) +{ + return kgdb_tty_driver->poll_get_char(kgdb_tty_driver, kgdb_tty_line); +} + +static void kgdboc_put_char(u8 chr) +{ + kgdb_tty_driver->poll_put_char(kgdb_tty_driver, kgdb_tty_line, chr); +} + +static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) +{ + int len = strlen(kmessage); + + if (len >= MAX_CONFIG_LEN) { + printk(KERN_ERR "kgdboc: config string too long\n"); + return -ENOSPC; + } + + /* Only copy in the string if the init function has not run yet */ + if (configured < 0) { + strcpy(config, kmessage); + return 0; + } + + if (kgdb_connected) { + printk(KERN_ERR + "kgdboc: Cannot reconfigure while KGDB is connected.\n"); + + return -EBUSY; + } + + strcpy(config, kmessage); + /* Chop out \n char as a result of echo */ + if (config[len - 1] == '\n') + config[len - 1] = '\0'; + + if (configured == 1) + cleanup_kgdboc(); + + /* Go and configure with the new params. */ + return configure_kgdboc(); +} + +static void kgdboc_pre_exp_handler(void) +{ + /* Increment the module count when the debugger is active */ + if (!kgdb_connected) + try_module_get(THIS_MODULE); +} + +static void kgdboc_post_exp_handler(void) +{ + /* decrement the module count when the debugger detaches */ + if (!kgdb_connected) + module_put(THIS_MODULE); +} + +static struct kgdb_io kgdboc_io_ops = { + .name = "kgdboc", + .read_char = kgdboc_get_char, + .write_char = kgdboc_put_char, + .pre_exception = kgdboc_pre_exp_handler, + .post_exception = kgdboc_post_exp_handler, +}; + +module_init(init_kgdboc); +module_exit(cleanup_kgdboc); +module_param_call(kgdboc, param_set_kgdboc_var, param_get_string, &kps, 0644); +MODULE_PARM_DESC(kgdboc, "<serial_device>[,baud]"); +MODULE_DESCRIPTION("KGDB Console TTY Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c index e76fc72c9b3..7e164e0cd21 100644 --- a/drivers/serial/mcf.c +++ b/drivers/serial/mcf.c @@ -649,5 +649,6 @@ module_exit(mcf_exit); MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); MODULE_DESCRIPTION("Freescale ColdFire UART driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mcfuart"); /****************************************************************************/ diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 99af084c7ce..ddd3aa50d4a 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c @@ -40,7 +40,6 @@ #include <asm/io.h> #include <asm/irq.h> #include <asm/system.h> -#include <asm/semaphore.h> #include <asm/delay.h> #include <asm/coldfire.h> #include <asm/mcfsim.h> diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index a638f23c6c6..d93b3578c5e 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1188,6 +1188,8 @@ mpc52xx_uart_resume(struct platform_device *dev) } #endif +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:mpc52xx-psc"); static struct platform_driver mpc52xx_uart_platform_driver = { .probe = mpc52xx_uart_probe, diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index cb3a9196774..e8819c43f57 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -1964,6 +1964,7 @@ static struct platform_driver mpsc_driver = { .remove = mpsc_drv_remove, .driver = { .name = MPSC_CTLR_NAME, + .owner = THIS_MODULE, }, }; @@ -2007,3 +2008,4 @@ MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $"); MODULE_VERSION(MPSC_VERSION); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR); +MODULE_ALIAS("platform:" MPSC_CTLR_NAME); diff --git a/drivers/serial/netx-serial.c b/drivers/serial/netx-serial.c index b56f7db4503..3123ffeac8a 100644 --- a/drivers/serial/netx-serial.c +++ b/drivers/serial/netx-serial.c @@ -713,6 +713,7 @@ static struct platform_driver serial_netx_driver = { .driver = { .name = DRIVER_NAME, + .owner = THIS_MODULE, }, }; @@ -745,3 +746,4 @@ module_exit(netx_serial_exit); MODULE_AUTHOR("Sascha Hauer"); MODULE_DESCRIPTION("NetX serial port driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/serial/pnx8xxx_uart.c b/drivers/serial/pnx8xxx_uart.c index 8d01c59e8d0..d0e5a79ea63 100644 --- a/drivers/serial/pnx8xxx_uart.c +++ b/drivers/serial/pnx8xxx_uart.c @@ -850,3 +850,4 @@ MODULE_AUTHOR("Embedded Alley Solutions, Inc."); MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR); +MODULE_ALIAS("platform:pnx8xxx-uart"); diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 352fcb8926a..b4f7ffb7688 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -833,6 +833,7 @@ static struct platform_driver serial_pxa_driver = { .resume = serial_pxa_resume, .driver = { .name = "pxa2xx-uart", + .owner = THIS_MODULE, }, }; @@ -861,4 +862,4 @@ module_init(serial_pxa_init); module_exit(serial_pxa_exit); MODULE_LICENSE("GPL"); - +MODULE_ALIAS("platform:pxa2xx-uart"); diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 45de1936603..4ffa2585429 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -1935,3 +1935,7 @@ console_initcall(s3c24xx_serial_initconsole); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_DESCRIPTION("Samsung S3C2410/S3C2440/S3C2412 Serial port driver"); +MODULE_ALIAS("platform:s3c2400-uart"); +MODULE_ALIAS("platform:s3c2410-uart"); +MODULE_ALIAS("platform:s3c2412-uart"); +MODULE_ALIAS("platform:s3c2440-uart"); diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 58a83c27e14..67b2338913c 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -884,6 +884,7 @@ static struct platform_driver sa11x0_serial_driver = { .resume = sa1100_serial_resume, .driver = { .name = "sa11x0-uart", + .owner = THIS_MODULE, }, }; @@ -917,3 +918,4 @@ MODULE_AUTHOR("Deep Blue Solutions Ltd"); MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.50 $"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_SA1100_MAJOR); +MODULE_ALIAS("platform:sa11x0-uart"); diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c index a350b6d2a18..ae2a9e2df77 100644 --- a/drivers/serial/sc26xx.c +++ b/drivers/serial/sc26xx.c @@ -732,6 +732,7 @@ static struct platform_driver sc26xx_driver = { .remove = __devexit_p(sc26xx_driver_remove), .driver = { .name = "SC26xx", + .owner = THIS_MODULE, }, }; @@ -753,3 +754,4 @@ MODULE_AUTHOR("Thomas Bogendörfer"); MODULE_DESCRIPTION("SC681/SC2692 serial driver"); MODULE_VERSION("1.0"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:SC26xx"); diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 0f5a17987cc..a9ca03ead3e 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1771,7 +1771,7 @@ static int uart_read_proc(char *page, char **start, off_t off, } #endif -#ifdef CONFIG_SERIAL_CORE_CONSOLE +#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) /* * uart_console_write - write a console message to a serial port * @port: the port to write the message @@ -1827,7 +1827,7 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co) * options. The format of the string is <baud><parity><bits><flow>, * eg: 115200n8r */ -void __init +void uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow) { char *s = options; @@ -1842,6 +1842,7 @@ uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow) if (*s) *flow = *s; } +EXPORT_SYMBOL_GPL(uart_parse_options); struct baud_rates { unsigned int rate; @@ -1872,7 +1873,7 @@ static const struct baud_rates baud_rates[] = { * @bits: number of data bits * @flow: flow control character - 'r' (rts) */ -int __init +int uart_set_options(struct uart_port *port, struct console *co, int baud, int parity, int bits, int flow) { @@ -1924,10 +1925,16 @@ uart_set_options(struct uart_port *port, struct console *co, port->mctrl |= TIOCM_DTR; port->ops->set_termios(port, &termios, &dummy); - co->cflag = termios.c_cflag; + /* + * Allow the setting of the UART parameters with a NULL console + * too: + */ + if (co) + co->cflag = termios.c_cflag; return 0; } +EXPORT_SYMBOL_GPL(uart_set_options); #endif /* CONFIG_SERIAL_CORE_CONSOLE */ static void uart_change_pm(struct uart_state *state, int pm_state) @@ -2182,6 +2189,60 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, } } +#ifdef CONFIG_CONSOLE_POLL + +static int uart_poll_init(struct tty_driver *driver, int line, char *options) +{ + struct uart_driver *drv = driver->driver_state; + struct uart_state *state = drv->state + line; + struct uart_port *port; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + if (!state || !state->port) + return -1; + + port = state->port; + if (!(port->ops->poll_get_char && port->ops->poll_put_char)) + return -1; + + if (options) { + uart_parse_options(options, &baud, &parity, &bits, &flow); + return uart_set_options(port, NULL, baud, parity, bits, flow); + } + + return 0; +} + +static int uart_poll_get_char(struct tty_driver *driver, int line) +{ + struct uart_driver *drv = driver->driver_state; + struct uart_state *state = drv->state + line; + struct uart_port *port; + + if (!state || !state->port) + return -1; + + port = state->port; + return port->ops->poll_get_char(port); +} + +static void uart_poll_put_char(struct tty_driver *driver, int line, char ch) +{ + struct uart_driver *drv = driver->driver_state; + struct uart_state *state = drv->state + line; + struct uart_port *port; + + if (!state || !state->port) + return; + + port = state->port; + port->ops->poll_put_char(port, ch); +} +#endif + static const struct tty_operations uart_ops = { .open = uart_open, .close = uart_close, @@ -2206,6 +2267,11 @@ static const struct tty_operations uart_ops = { #endif .tiocmget = uart_tiocmget, .tiocmset = uart_tiocmset, +#ifdef CONFIG_CONSOLE_POLL + .poll_init = uart_poll_init, + .poll_get_char = uart_poll_get_char, + .poll_put_char = uart_poll_put_char, +#endif }; /** @@ -2356,7 +2422,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) */ tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev); if (likely(!IS_ERR(tty_dev))) { - device_can_wakeup(tty_dev) = 1; + device_init_wakeup(tty_dev, 1); device_set_wakeup_enable(tty_dev, 0); } else printk(KERN_ERR "Cannot register tty device on line %d\n", diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 9d244d1644e..c2ea5d4df44 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -333,7 +333,6 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) } sci_out(port, SCFCR, fcr_val); } - #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) @@ -384,6 +383,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) sci_out(port, SCFCR, fcr_val); } +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +{ + /* Nothing to do here.. */ + sci_out(port, SCFCR, 0); +} #else /* For SH7750 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) @@ -1552,3 +1557,4 @@ module_init(sci_init); module_exit(sci_exit); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:sh-sci"); diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 01a9dd715f5..fa8700a968f 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -1,20 +1,5 @@ -/* $Id: sh-sci.h,v 1.4 2004/02/19 16:43:56 lethal Exp $ - * - * linux/drivers/serial/sh-sci.h - * - * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) - * Copyright (C) 1999, 2000 Niibe Yutaka - * Copyright (C) 2000 Greg Banks - * Copyright (C) 2002, 2003 Paul Mundt - * Modified to support multiple serial ports. Stuart Menefy (May 2000). - * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003). - * Modified to support H8/300 Series Yoshinori Sato (Feb 2004). - * Removed SH7300 support (Jul 2007). - * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Aug 2007). - */ #include <linux/serial_core.h> #include <asm/io.h> - #include <asm/gpio.h> #if defined(CONFIG_H83007) || defined(CONFIG_H83068) @@ -102,6 +87,15 @@ # define SCSPTR0 SCPDR0 # define SCIF_ORER 0x0001 /* overrun error bit */ # define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +# define SCSPTR0 0xa4050160 +# define SCSPTR1 0xa405013e +# define SCSPTR2 0xa4050160 +# define SCSPTR3 0xa405013e +# define SCSPTR4 0xa4050128 +# define SCSPTR5 0xa4050128 +# define SCIF_ORER 0x0001 /* overrun error bit */ +# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ # define SCIF_ONLY #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ @@ -395,6 +389,11 @@ h8_sci_offset, h8_sci_size) \ CPU_SCI_FNS(name, h8_sci_offset, h8_sci_size) #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) + #define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) \ + CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scif_offset, sh4_scif_size) + #define SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) \ + CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) #else #define SCIx_FNS(name, sh3_sci_offset, sh3_sci_size, sh4_sci_offset, sh4_sci_size, \ sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size, \ @@ -419,6 +418,18 @@ SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCxTDR, 0x20, 8) SCIF_FNS(SCxRDR, 0x24, 8) SCIF_FNS(SCLSR, 0x24, 16) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16) +SCIx_FNS(SCBRR, 0x04, 8, 0x04, 8) +SCIx_FNS(SCSCR, 0x08, 16, 0x08, 16) +SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8) +SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16) +SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8) +SCIF_FNS(SCTDSR, 0x0c, 8) +SCIF_FNS(SCFER, 0x10, 16) +SCIF_FNS(SCFCR, 0x18, 16) +SCIF_FNS(SCFDR, 0x1c, 16) +SCIF_FNS(SCLSR, 0x24, 16) #else /* reg SCI/SH3 SCI/SH4 SCIF/SH3 SCIF/SH4 SCI/H8*/ /* name off sz off sz off sz off sz off sz*/ @@ -589,6 +600,23 @@ static inline int sci_rxd_in(struct uart_port *port) return ctrl_inb(SCPDR0) & 0x0001 ? 1 : 0; /* SCIF0 */ return 1; } +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xffe00000) + return ctrl_inb(SCSPTR0) & 0x0008 ? 1 : 0; /* SCIF0 */ + if (port->mapbase == 0xffe10000) + return ctrl_inb(SCSPTR1) & 0x0020 ? 1 : 0; /* SCIF1 */ + if (port->mapbase == 0xffe20000) + return ctrl_inb(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF2 */ + if (port->mapbase == 0xa4e30000) + return ctrl_inb(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF3 */ + if (port->mapbase == 0xa4e40000) + return ctrl_inb(SCSPTR4) & 0x0001 ? 1 : 0; /* SCIF4 */ + if (port->mapbase == 0xa4e50000) + return ctrl_inb(SCSPTR5) & 0x0008 ? 1 : 0; /* SCIF5 */ + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) static inline int sci_rxd_in(struct uart_port *port) { @@ -727,6 +755,8 @@ static inline int sci_rxd_in(struct uart_port *port) defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) +#elif defined(CONFIG_CPU_SUBTYPE_SH7723) +#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1) #elif defined(__H8300H__) || defined(__H8300S__) #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) #elif defined(CONFIG_SUPERH64) diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 4e06ab6bcb6..b565d5a3749 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -561,6 +561,9 @@ static int __devexit ulite_remove(struct platform_device *pdev) return ulite_release(&pdev->dev); } +/* work with hotplug and coldplug */ +MODULE_ALIAS("platform:uartlite"); + static struct platform_driver ulite_platform_driver = { .probe = ulite_probe, .remove = __devexit_p(ulite_remove), diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 6fd51b0022c..98ab649c1ff 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -960,3 +960,6 @@ static void __exit vr41xx_siu_exit(void) module_init(vr41xx_siu_init); module_exit(vr41xx_siu_exit); + +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:SIU"); |