diff options
author | Artem B. Bityuckiy <dedekind@infradead.org> | 2005-07-06 15:43:18 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-07-06 19:40:38 +0200 |
commit | b3539219c9ea20ebf6a5ea3cc534f423a3607c41 (patch) | |
tree | d17c31c0eac0a7290ba5011b59a100fd9e9c9532 /drivers/serial | |
parent | 6430a8def12edebc1c9c7c2621d33ca0e8653c33 (diff) | |
parent | a18bcb7450840f07a772a45229de4811d930f461 (diff) | |
download | kernel-crypto-b3539219c9ea20ebf6a5ea3cc534f423a3607c41.tar.gz kernel-crypto-b3539219c9ea20ebf6a5ea3cc534f423a3607c41.tar.xz kernel-crypto-b3539219c9ea20ebf6a5ea3cc534f423a3607c41.zip |
Merge with rsync://fileserver/linux
Update to 2.6.12-rc3
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/68328serial.c | 17 | ||||
-rw-r--r-- | drivers/serial/8250.c | 61 | ||||
-rw-r--r-- | drivers/serial/8250_accent.c | 47 | ||||
-rw-r--r-- | drivers/serial/8250_boca.c | 61 | ||||
-rw-r--r-- | drivers/serial/8250_fourport.c | 53 | ||||
-rw-r--r-- | drivers/serial/8250_hub6.c | 58 | ||||
-rw-r--r-- | drivers/serial/8250_mca.c | 64 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 77 | ||||
-rw-r--r-- | drivers/serial/Makefile | 5 | ||||
-rw-r--r-- | drivers/serial/au1x00_uart.c | 3 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_cpm1.c | 32 | ||||
-rw-r--r-- | drivers/serial/ip22zilog.c | 13 | ||||
-rw-r--r-- | drivers/serial/mpsc.c | 3 | ||||
-rw-r--r-- | drivers/serial/pmac_zilog.c | 4 | ||||
-rw-r--r-- | drivers/serial/pxa.c | 3 | ||||
-rw-r--r-- | drivers/serial/s3c2410.c | 5 | ||||
-rw-r--r-- | drivers/serial/serial_core.c | 42 | ||||
-rw-r--r-- | drivers/serial/serial_cs.c | 106 | ||||
-rw-r--r-- | drivers/serial/serial_txx9.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunsab.c | 7 | ||||
-rw-r--r-- | drivers/serial/sunsu.c | 3 | ||||
-rw-r--r-- | drivers/serial/sunzilog.c | 13 |
22 files changed, 570 insertions, 110 deletions
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index feb8e73fc1c..d27fb4c881d 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -1497,23 +1497,6 @@ rs68328_init(void) return 0; } - - -/* - * register_serial and unregister_serial allows for serial ports to be - * configured at run-time, to support PCMCIA modems. - */ -/* SPARC: Unused at this time, just here to make things link. */ -int register_serial(struct serial_struct *req) -{ - return -1; -} - -void unregister_serial(int line) -{ - return; -} - module_init(rs68328_init); diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index d8b9d2b8c20..7e8fc7c1d4c 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -77,23 +77,9 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; */ #define is_real_interrupt(irq) ((irq) != 0) -/* - * This converts from our new CONFIG_ symbols to the symbols - * that asm/serial.h expects. You _NEED_ to comment out the - * linux/config.h include contained inside asm/serial.h for - * this to work. - */ -#undef CONFIG_SERIAL_MANY_PORTS -#undef CONFIG_SERIAL_DETECT_IRQ -#undef CONFIG_SERIAL_MULTIPORT -#undef CONFIG_HUB6 - #ifdef CONFIG_SERIAL_8250_DETECT_IRQ #define CONFIG_SERIAL_DETECT_IRQ 1 #endif -#ifdef CONFIG_SERIAL_8250_MULTIPORT -#define CONFIG_SERIAL_MULTIPORT 1 -#endif #ifdef CONFIG_SERIAL_8250_MANY_PORTS #define CONFIG_SERIAL_MANY_PORTS 1 #endif @@ -119,7 +105,7 @@ static struct old_serial_port old_serial_port[] = { SERIAL_PORT_DFNS /* defined in asm/serial.h */ }; -#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) +#define UART_NR CONFIG_SERIAL_8250_NR_UARTS #ifdef CONFIG_SERIAL_8250_RSA @@ -1007,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up) up->port.irq = (irq > 0) ? irq : 0; } +static inline void __stop_tx(struct uart_8250_port *p) +{ + if (p->ier & UART_IER_THRI) { + p->ier &= ~UART_IER_THRI; + serial_out(p, UART_IER, p->ier); + } +} + static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) { struct uart_8250_port *up = (struct uart_8250_port *)port; - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } + __stop_tx(up); /* - * We only do this from uart_stop - if we run out of - * characters to send, we don't want to prevent the - * FIFO from emptying. + * We really want to stop the transmitter from sending. */ - if (up->port.type == PORT_16C950 && tty_stop) { + if (up->port.type == PORT_16C950) { up->acr |= UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1045,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) transmit_chars(up); } } + /* - * We only do this from uart_start + * Re-enable the transmitter if we disabled it. */ - if (tty_start && up->port.type == PORT_16C950) { + if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1169,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); return; } @@ -1188,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) DEBUG_INTR("THRE..."); if (uart_circ_empty(xmit)) - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); } static _INLINE_ void check_modem_status(struct uart_8250_port *up) @@ -1390,13 +1380,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) @@ -2074,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) up->port.ops = &serial8250_pops; } - for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); + for (i = 0, up = serial8250_ports; + i < ARRAY_SIZE(old_serial_port) && i < UART_NR; i++, up++) { up->port.iobase = old_serial_port[i].port; up->port.irq = irq_canonicalize(old_serial_port[i].irq); @@ -2323,10 +2311,11 @@ static int __devinit serial8250_probe(struct device *dev) { struct plat_serial8250_port *p = dev->platform_data; struct uart_port port; + int ret, i; memset(&port, 0, sizeof(struct uart_port)); - for (; p && p->flags != 0; p++) { + for (i = 0; p && p->flags != 0; p++, i++) { port.iobase = p->iobase; port.membase = p->membase; port.irq = p->irq; @@ -2335,10 +2324,16 @@ static int __devinit serial8250_probe(struct device *dev) port.iotype = p->iotype; port.flags = p->flags; port.mapbase = p->mapbase; + port.hub6 = p->hub6; port.dev = dev; if (share_irqs) port.flags |= UPF_SHARE_IRQ; - serial8250_register_port(&port); + ret = serial8250_register_port(&port); + if (ret < 0) { + dev_err(dev, "unable to register port at index %d " + "(IO%lx MEM%lx IRQ%d): %d\n", i, + p->iobase, p->mapbase, p->irq, ret); + } } return 0; } diff --git a/drivers/serial/8250_accent.c b/drivers/serial/8250_accent.c new file mode 100644 index 00000000000..1f2c276063e --- /dev/null +++ b/drivers/serial/8250_accent.c @@ -0,0 +1,47 @@ +/* + * linux/drivers/serial/8250_accent.c + * + * Copyright (C) 2005 Russell King. + * Data taken from include/asm-i386/serial.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/serial_8250.h> + +#define PORT(_base,_irq) \ + { \ + .iobase = _base, \ + .irq = _irq, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF, \ + } + +static struct plat_serial8250_port accent_data[] = { + PORT(0x330, 4), + PORT(0x338, 4), + { }, +}; + +static struct platform_device accent_device = { + .name = "serial8250", + .id = 2, + .dev = { + .platform_data = accent_data, + }, +}; + +static int __init accent_init(void) +{ + return platform_device_register(&accent_device); +} + +module_init(accent_init); + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("8250 serial probe module for Accent Async cards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/8250_boca.c b/drivers/serial/8250_boca.c new file mode 100644 index 00000000000..465c9ea1e7a --- /dev/null +++ b/drivers/serial/8250_boca.c @@ -0,0 +1,61 @@ +/* + * linux/drivers/serial/8250_boca.c + * + * Copyright (C) 2005 Russell King. + * Data taken from include/asm-i386/serial.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/serial_8250.h> + +#define PORT(_base,_irq) \ + { \ + .iobase = _base, \ + .irq = _irq, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF, \ + } + +static struct plat_serial8250_port boca_data[] = { + PORT(0x100, 12), + PORT(0x108, 12), + PORT(0x110, 12), + PORT(0x118, 12), + PORT(0x120, 12), + PORT(0x128, 12), + PORT(0x130, 12), + PORT(0x138, 12), + PORT(0x140, 12), + PORT(0x148, 12), + PORT(0x150, 12), + PORT(0x158, 12), + PORT(0x160, 12), + PORT(0x168, 12), + PORT(0x170, 12), + PORT(0x178, 12), + { }, +}; + +static struct platform_device boca_device = { + .name = "serial8250", + .id = 3, + .dev = { + .platform_data = boca_data, + }, +}; + +static int __init boca_init(void) +{ + return platform_device_register(&boca_device); +} + +module_init(boca_init); + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("8250 serial probe module for Boca cards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/8250_fourport.c b/drivers/serial/8250_fourport.c new file mode 100644 index 00000000000..e9b4d908ef4 --- /dev/null +++ b/drivers/serial/8250_fourport.c @@ -0,0 +1,53 @@ +/* + * linux/drivers/serial/8250_fourport.c + * + * Copyright (C) 2005 Russell King. + * Data taken from include/asm-i386/serial.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/serial_8250.h> + +#define PORT(_base,_irq) \ + { \ + .iobase = _base, \ + .irq = _irq, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = UPF_BOOT_AUTOCONF | UPF_FOURPORT, \ + } + +static struct plat_serial8250_port fourport_data[] = { + PORT(0x1a0, 9), + PORT(0x1a8, 9), + PORT(0x1b0, 9), + PORT(0x1b8, 9), + PORT(0x2a0, 5), + PORT(0x2a8, 5), + PORT(0x2b0, 5), + PORT(0x2b8, 5), + { }, +}; + +static struct platform_device fourport_device = { + .name = "serial8250", + .id = 1, + .dev = { + .platform_data = fourport_data, + }, +}; + +static int __init fourport_init(void) +{ + return platform_device_register(&fourport_device); +} + +module_init(fourport_init); + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("8250 serial probe module for AST Fourport cards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/8250_hub6.c b/drivers/serial/8250_hub6.c new file mode 100644 index 00000000000..77f396f84b4 --- /dev/null +++ b/drivers/serial/8250_hub6.c @@ -0,0 +1,58 @@ +/* + * linux/drivers/serial/8250_hub6.c + * + * Copyright (C) 2005 Russell King. + * Data taken from include/asm-i386/serial.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/serial_8250.h> + +#define HUB6(card,port) \ + { \ + .iobase = 0x302, \ + .irq = 3, \ + .uartclk = 1843200, \ + .iotype = UPIO_HUB6, \ + .flags = UPF_BOOT_AUTOCONF, \ + .hub6 = (card) << 6 | (port) << 3 | 1, \ + } + +static struct plat_serial8250_port hub6_data[] = { + HUB6(0,0), + HUB6(0,1), + HUB6(0,2), + HUB6(0,3), + HUB6(0,4), + HUB6(0,5), + HUB6(1,0), + HUB6(1,1), + HUB6(1,2), + HUB6(1,3), + HUB6(1,4), + HUB6(1,5), + { }, +}; + +static struct platform_device hub6_device = { + .name = "serial8250", + .id = 4, + .dev = { + .platform_data = hub6_data, + }, +}; + +static int __init hub6_init(void) +{ + return platform_device_register(&hub6_device); +} + +module_init(hub6_init); + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("8250 serial probe module for Hub6 cards"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/8250_mca.c b/drivers/serial/8250_mca.c new file mode 100644 index 00000000000..f0c40d68b8c --- /dev/null +++ b/drivers/serial/8250_mca.c @@ -0,0 +1,64 @@ +/* + * linux/drivers/serial/8250_mca.c + * + * Copyright (C) 2005 Russell King. + * Data taken from include/asm-i386/serial.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/mca.h> +#include <linux/serial_8250.h> + +/* + * FIXME: Should we be doing AUTO_IRQ here? + */ +#ifdef CONFIG_SERIAL_8250_DETECT_IRQ +#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ +#else +#define MCA_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST +#endif + +#define PORT(_base,_irq) \ + { \ + .iobase = _base, \ + .irq = _irq, \ + .uartclk = 1843200, \ + .iotype = UPIO_PORT, \ + .flags = MCA_FLAGS, \ + } + +static struct plat_serial8250_port mca_data[] = { + PORT(0x3220, 3), + PORT(0x3228, 3), + PORT(0x4220, 3), + PORT(0x4228, 3), + PORT(0x5220, 3), + PORT(0x5228, 3), + { }, +}; + +static struct platform_device mca_device = { + .name = "serial8250", + .id = 5, + .dev = { + .platform_data = mca_data, + }, +}; + +static int __init mca_init(void) +{ + if (!MCA_bus) + return -ENODEV; + return platform_device_register(&mca_device); +} + +module_init(mca_init); + +MODULE_AUTHOR("Russell King"); +MODULE_DESCRIPTION("8250 serial probe module for MCA ports"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 25fcef2c42d..e0d0a470ddf 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -86,14 +86,14 @@ config SERIAL_8250_ACPI namespace, say Y here. If unsure, say N. config SERIAL_8250_NR_UARTS - int "Maximum number of non-legacy 8250/16550 serial ports" + int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 default "4" - ---help--- - Set this to the number of non-legacy serial ports you want - the driver to support. This includes any ports discovered - via ACPI or PCI enumeration and any ports that may be added - at run-time via hot-plug. + help + Set this to the number of serial ports you want the driver + to support. This includes any ports discovered via ACPI or + PCI enumeration and any ports that may be added at run-time + via hot-plug, or any ISA multi-port serial cards. config SERIAL_8250_EXTENDED bool "Extended 8250/16550 serial driver options" @@ -141,31 +141,74 @@ config SERIAL_8250_DETECT_IRQ If unsure, say N. -config SERIAL_8250_MULTIPORT - bool "Support special multiport boards" - depends on SERIAL_8250_EXTENDED - help - Some multiport serial ports have special ports which are used to - signal when there are any serial ports on the board which need - servicing. Say Y here to enable the serial driver to take advantage - of those special I/O ports. - config SERIAL_8250_RSA bool "Support RSA serial ports" depends on SERIAL_8250_EXTENDED help ::: To be written ::: -comment "Non-8250 serial port support" +# +# Multi-port serial cards +# + +config SERIAL_8250_FOURPORT + tristate "Support Fourport cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an AST FourPort serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_fourport. + +config SERIAL_8250_ACCENT + tristate "Support Accent cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have an Accent Async serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_accent. + + +config SERIAL_8250_BOCA + tristate "Support Boca cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a Boca serial board. Please read the Boca + mini-HOWTO, avaialble from <http://www.tldp.org/docs.html#howto> + + To compile this driver as a module, choose M here: the module + will be called 8250_boca. + + +config SERIAL_8250_HUB6 + tristate "Support Hub6 cards" + depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS + help + Say Y here if you have a HUB6 serial board. + + To compile this driver as a module, choose M here: the module + will be called 8250_hub6. + +config SERIAL_8250_MCA + tristate "Support 8250-type ports on MCA buses" + depends on SERIAL_8250 != n && MCA + help + Say Y here if you have a MCA serial ports. + + To compile this driver as a module, choose M here: the module + will be called 8250_mca. config SERIAL_8250_ACORN tristate "Acorn expansion card serial port support" - depends on ARM && ARCH_ACORN && SERIAL_8250 + depends on ARCH_ACORN && SERIAL_8250 help If you have an Atomwide Serial card or Serial Port card for an Acorn system, say Y to this option. The driver can handle 1, 2, or 3 port cards. If unsure, say N. +comment "Non-8250 serial port support" + config SERIAL_AMBA_PL010 tristate "ARM AMBA PL010 serial port support" depends on ARM_AMBA diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 8f1cdde7dbe..65bd4381685 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -17,6 +17,11 @@ obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y) obj-$(CONFIG_SERIAL_8250_CS) += serial_cs.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o +obj-$(CONFIG_SERIAL_8250_FOURPORT) += 8250_fourport.o +obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o +obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_boca.o +obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o +obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index 5400dc2c087..6104aeef124 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c @@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index de26cf7b003..7911912f50c 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo) ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; } +#ifdef CONFIG_MPC885ADS + /* Enable SMC1 transceivers */ + { + volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); + uint tmp; + + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_1; + out_be32(bcsr1, tmp); + iounmap(bcsr1); + } +#endif + pinfo->brg = 1; } void smc2_lineif(struct uart_cpm_port *pinfo) { - /* XXX SMC2: insert port configuration here */ +#ifdef CONFIG_MPC885ADS + volatile cpm8xx_t *cp = cpmp; + volatile uint __iomem *bcsr1; + uint tmp; + + cp->cp_pepar |= 0x00000c00; + cp->cp_pedir &= ~0x00000c00; + cp->cp_peso &= ~0x00000400; + cp->cp_peso |= 0x00000800; + + /* Enable SMC2 transceivers */ + bcsr1 = ioremap(BCSR1, 4); + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_2; + out_be32(bcsr1, tmp); + iounmap(bcsr1); +#endif + pinfo->brg = 2; } diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 3ea46c069f6..ea5bf4d4daa 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) { struct zilog_channel *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int ip22zilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = ip22zilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int ip22zilog_get_mctrl(struct uart_port *port) { unsigned char status; diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index a2a64331800..e43276c6a95 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -1058,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 mflags, status; - ulong iflags; - spin_lock_irqsave(&pi->port.lock, iflags); status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : readl(pi->mpsc_base + MPSC_CHR_10); - spin_unlock_irqrestore(&pi->port.lock, iflags); mflags = 0; if (status & 0x1) diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 85abd8a045e..1c9f7161712 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) /* * Get Modem Control bits (only the input ones, the core will * or that with a cached value of the control ones) - * The port lock is not held. + * The port lock is held and interrupts are disabled. */ static unsigned int pmz_get_mctrl(struct uart_port *port) { @@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port) if (ZS_IS_ASLEEP(uap) || uap->node == NULL) return 0; - status = pmz_peek_status(to_pmz(port)); + status = read_zsreg(uap, R0); ret = 0; if (status & DCD) diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 08b08d6ae90..461c81c9320 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port) static unsigned int serial_pxa_get_mctrl(struct uart_port *port) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 5c4678478b1..7365d4b50b9 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); - unsigned long flags; int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); - local_irq_save(flags); - rx_enabled(port) = 1; ret = request_irq(RX_IRQ(port), @@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port) /* the port reset code should have done the correct * register setup for the port controls */ - local_irq_restore(flags); return ret; err: s3c24xx_serial_shutdown(port); - local_irq_restore(flags); return ret; } diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 36b1ae083fb..54699c3a00a 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw) uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); } + if (info->flags & UIF_CTS_FLOW) { + spin_lock_irq(&port->lock); + if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) + info->tty->hw_stopped = 1; + spin_unlock_irq(&port->lock); + } + info->flags |= UIF_INITIALIZED; clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -828,7 +835,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file) if ((!file || !tty_hung_up_p(file)) && !(tty->flags & (1 << TTY_IO_ERROR))) { result = port->mctrl; + + spin_lock_irq(&port->lock); result |= port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); } up(&state->sem); @@ -1131,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios spin_unlock_irqrestore(&state->port->lock, flags); } + /* Handle turning on CRTSCTS */ + if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + spin_lock_irqsave(&state->port->lock, flags); + if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { + tty->hw_stopped = 1; + state->port->ops->stop_tx(state->port, 0); + } + spin_unlock_irqrestore(&state->port->lock, flags); + } + #if 0 /* * No need to wake up processes in open wait, since they @@ -1369,6 +1389,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) DECLARE_WAITQUEUE(wait, current); struct uart_info *info = state->info; struct uart_port *port = state->port; + unsigned int mctrl; info->blocked_open++; state->count--; @@ -1416,7 +1437,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) * and wait for the carrier to indicate that the * modem is ready for us. */ - if (port->ops->get_mctrl(port) & TIOCM_CAR) + spin_lock_irq(&port->lock); + mctrl = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); + if (mctrl & TIOCM_CAR) break; up(&state->sem); @@ -1618,7 +1642,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) if(capable(CAP_SYS_ADMIN)) { + spin_lock_irq(&port->lock); status = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); ret += sprintf(buf + ret, " tx:%d rx:%d", port->icount.tx, port->icount.rx); @@ -1782,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co, struct termios termios; int i; + /* + * Ensure that the serial console lock is initialised + * early. + */ + spin_lock_init(&port->lock); + memset(&termios, 0, sizeof(struct termios)); termios.c_cflag = CREAD | HUPCL | CLOCAL; @@ -2170,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state->port = port; - spin_lock_init(&port->lock); port->cons = drv->cons; port->info = state->info; + /* + * If this port is a console, then the spinlock is already + * initialised. + */ + if (!uart_console(port)) + spin_lock_init(&port->lock); + uart_configure_port(drv, state, port); /* diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 0d7b65f93e8..73a34b18866 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -772,6 +772,111 @@ serial_event(event_t event, int priority, event_callback_args_t * args) return 0; } +static struct pcmcia_device_id serial_ids[] = { + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), + PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), + PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), + PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), + PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), + PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), + PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea), + PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023), + PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), + PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), + PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), + PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2), + PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), + PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), + PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), + PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020), + PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f), + PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), + PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3), + PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15), + PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), + PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), + PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), + PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), + PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), + PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), + PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), + PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), + PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), + PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), + PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), + PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), + PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), + PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), + PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), + PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), + PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), + PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), + PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), + PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), + PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76), + PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), + PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), + PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), + PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), + PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80), + PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), + PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), + PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), + PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), + PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), + PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), + PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"), + PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), + PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), + PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"), + PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), + PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), + PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"), + PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), + PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), + PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), + /* too generic */ + /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ + /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ + PCMCIA_DEVICE_FUNC_ID(2), + PCMCIA_DEVICE_NULL, +}; +MODULE_DEVICE_TABLE(pcmcia, serial_ids); + static struct pcmcia_driver serial_cs_driver = { .owner = THIS_MODULE, .drv = { @@ -779,6 +884,7 @@ static struct pcmcia_driver serial_cs_driver = { }, .attach = serial_attach, .detach = serial_detach, + .id_table = serial_ids, }; static int __init init_serial_cs(void) diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3f1051a4a13..d085030df70 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port) static unsigned int serial_txx9_get_mctrl(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); - spin_unlock_irqrestore(&up->port.lock, flags); return ret; } diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 10e2990a40d..8d198880756 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) sunsab_tx_idle(up); } -/* port->lock is not held. */ +/* port->lock is held by caller and interrupts are disabled. */ static unsigned int sunsab_get_mctrl(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; - unsigned long flags; unsigned char val; unsigned int result; result = 0; - spin_lock_irqsave(&up->port.lock, flags); - val = readb(&up->regs->r.pvr); result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; @@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port) val = readb(&up->regs->r.star); result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - return result; } diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index ddc97c905e1..d57a3553aea 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) static unsigned int sunsu_get_mctrl(struct uart_port *port) { struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 8e65206d3d7..bff42a7b89d 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) { struct zilog_channel __iomem *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = sbus_readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int sunzilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = sunzilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int sunzilog_get_mctrl(struct uart_port *port) { unsigned char status; |